1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
49 #include "bgpd/bgpd.h"
50 #include "bgpd/bgp_table.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_route.h"
53 #include "bgpd/bgp_dump.h"
54 #include "bgpd/bgp_debug.h"
55 #include "bgpd/bgp_errors.h"
56 #include "bgpd/bgp_community.h"
57 #include "bgpd/bgp_attr.h"
58 #include "bgpd/bgp_regex.h"
59 #include "bgpd/bgp_clist.h"
60 #include "bgpd/bgp_fsm.h"
61 #include "bgpd/bgp_packet.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_open.h"
64 #include "bgpd/bgp_filter.h"
65 #include "bgpd/bgp_nexthop.h"
66 #include "bgpd/bgp_damp.h"
67 #include "bgpd/bgp_mplsvpn.h"
69 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/bgp_evpn.h"
73 #include "bgpd/bgp_advertise.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_vty.h"
76 #include "bgpd/bgp_mpath.h"
77 #include "bgpd/bgp_nht.h"
78 #include "bgpd/bgp_updgrp.h"
79 #include "bgpd/bgp_bfd.h"
80 #include "bgpd/bgp_memory.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_keepalives.h"
83 #include "bgpd/bgp_io.h"
84 #include "bgpd/bgp_ecommunity.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_labelpool.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "bgpd/bgp_addpath.h"
90 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
91 DEFINE_QOBJ_TYPE(bgp_master
)
93 DEFINE_QOBJ_TYPE(peer
)
95 /* BGP process wide configuration. */
96 static struct bgp_master bgp_master
;
98 /* BGP process wide configuration pointer to export. */
99 struct bgp_master
*bm
;
101 /* BGP community-list. */
102 struct community_list_handler
*bgp_clist
;
104 unsigned int multipath_num
= MULTIPATH_NUM
;
106 static void bgp_if_finish(struct bgp
*bgp
);
107 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
109 extern struct zclient
*zclient
;
111 /* handle main socket creation or deletion */
112 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
114 static int bgp_server_main_created
;
116 if (create
== true) {
117 if (bgp_server_main_created
)
119 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
120 return BGP_ERR_INVALID_VALUE
;
121 bgp_server_main_created
= 1;
124 if (!bgp_server_main_created
)
127 bgp_server_main_created
= 0;
131 void bgp_session_reset(struct peer
*peer
)
133 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
134 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
135 peer_delete(peer
->doppelganger
);
137 BGP_EVENT_ADD(peer
, BGP_Stop
);
141 * During session reset, we may delete the doppelganger peer, which would
142 * be the next node to the current node. If the session reset was invoked
143 * during walk of peer list, we would end up accessing the freed next
144 * node. This function moves the next node along.
146 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
151 n
= (nnode
) ? *nnode
: NULL
;
152 npeer
= (n
) ? listgetdata(n
) : NULL
;
154 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
155 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
156 PEER_FLAG_CONFIG_NODE
))) {
157 if (peer
->doppelganger
== npeer
)
158 /* nnode and *nnode are confirmed to be non-NULL here */
159 *nnode
= (*nnode
)->next
;
160 peer_delete(peer
->doppelganger
);
163 BGP_EVENT_ADD(peer
, BGP_Stop
);
166 /* BGP global flag manipulation. */
167 int bgp_option_set(int flag
)
171 case BGP_OPT_MULTIPLE_INSTANCE
:
172 case BGP_OPT_CONFIG_CISCO
:
173 case BGP_OPT_NO_LISTEN
:
174 SET_FLAG(bm
->options
, flag
);
177 return BGP_ERR_INVALID_FLAG
;
182 int bgp_option_unset(int flag
)
185 case BGP_OPT_MULTIPLE_INSTANCE
:
186 if (listcount(bm
->bgp
) > 1)
187 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
190 case BGP_OPT_CONFIG_CISCO
:
191 UNSET_FLAG(bm
->options
, flag
);
194 return BGP_ERR_INVALID_FLAG
;
199 int bgp_option_check(int flag
)
201 return CHECK_FLAG(bm
->options
, flag
);
204 /* BGP flag manipulation. */
205 int bgp_flag_set(struct bgp
*bgp
, int flag
)
207 SET_FLAG(bgp
->flags
, flag
);
211 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
213 UNSET_FLAG(bgp
->flags
, flag
);
217 int bgp_flag_check(struct bgp
*bgp
, int flag
)
219 return CHECK_FLAG(bgp
->flags
, flag
);
222 /* Internal function to set BGP structure configureation flag. */
223 static void bgp_config_set(struct bgp
*bgp
, int config
)
225 SET_FLAG(bgp
->config
, config
);
228 static void bgp_config_unset(struct bgp
*bgp
, int config
)
230 UNSET_FLAG(bgp
->config
, config
);
233 static int bgp_config_check(struct bgp
*bgp
, int config
)
235 return CHECK_FLAG(bgp
->config
, config
);
238 /* Set BGP router identifier. */
239 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
242 struct listnode
*node
, *nnode
;
244 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
247 /* EVPN uses router id in RD, withdraw them */
248 if (is_evpn_enabled())
249 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
251 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
253 /* Set all peer's local identifier with this value. */
254 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
255 IPV4_ADDR_COPY(&peer
->local_id
, id
);
257 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
258 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
259 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
260 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
264 /* EVPN uses router id in RD, update them */
265 if (is_evpn_enabled())
266 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
271 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
273 struct listnode
*node
, *nnode
;
276 if (vrf_id
== VRF_DEFAULT
) {
277 /* Router-id change for default VRF has to also update all
279 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
280 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
283 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
284 if (!bgp
->router_id_static
.s_addr
)
285 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
288 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
290 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
292 if (!bgp
->router_id_static
.s_addr
)
293 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
298 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
300 bgp
->router_id_static
= id
;
301 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
305 /* BGP's cluster-id control. */
306 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
309 struct listnode
*node
, *nnode
;
311 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
312 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
315 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
316 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
318 /* Clear all IBGP peer. */
319 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
320 if (peer
->sort
!= BGP_PEER_IBGP
)
323 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
324 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
325 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
326 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
332 int bgp_cluster_id_unset(struct bgp
*bgp
)
335 struct listnode
*node
, *nnode
;
337 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
340 bgp
->cluster_id
.s_addr
= 0;
341 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
343 /* Clear all IBGP peer. */
344 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
345 if (peer
->sort
!= BGP_PEER_IBGP
)
348 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
349 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
350 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
351 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
357 /* time_t value that is monotonicly increasing
358 * and uneffected by adjustments to system clock
360 time_t bgp_clock(void)
368 /* BGP timer configuration. */
369 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
371 bgp
->default_keepalive
=
372 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
373 bgp
->default_holdtime
= holdtime
;
378 int bgp_timers_unset(struct bgp
*bgp
)
380 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
381 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
386 /* BGP confederation configuration. */
387 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
390 struct listnode
*node
, *nnode
;
394 return BGP_ERR_INVALID_AS
;
396 /* Remember - were we doing confederation before? */
397 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
399 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
401 /* If we were doing confederation already, this is just an external
402 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
403 were not doing confederation before, reset all EBGP sessions. */
404 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
405 /* We're looking for peers who's AS is not local or part of our
407 if (already_confed
) {
408 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
410 if (BGP_IS_VALID_STATE_FOR_NOTIF(
413 PEER_DOWN_CONFED_ID_CHANGE
;
415 peer
, BGP_NOTIFY_CEASE
,
416 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
418 bgp_session_reset_safe(peer
, &nnode
);
421 /* Not doign confederation before, so reset every
424 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
425 /* Reset the local_as to be our EBGP one */
426 if (peer_sort(peer
) == BGP_PEER_EBGP
)
428 if (BGP_IS_VALID_STATE_FOR_NOTIF(
431 PEER_DOWN_CONFED_ID_CHANGE
;
433 peer
, BGP_NOTIFY_CEASE
,
434 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
436 bgp_session_reset_safe(peer
, &nnode
);
443 int bgp_confederation_id_unset(struct bgp
*bgp
)
446 struct listnode
*node
, *nnode
;
449 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
451 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
452 /* We're looking for peers who's AS is not local */
453 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
454 peer
->local_as
= bgp
->as
;
455 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
456 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
457 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
458 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
462 bgp_session_reset_safe(peer
, &nnode
);
468 /* Is an AS part of the confed or not? */
469 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
476 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
477 if (bgp
->confed_peers
[i
] == as
)
483 /* Add an AS to the confederation set. */
484 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
487 struct listnode
*node
, *nnode
;
490 return BGP_ERR_INVALID_BGP
;
493 return BGP_ERR_INVALID_AS
;
495 if (bgp_confederation_peers_check(bgp
, as
))
498 if (bgp
->confed_peers
)
500 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
501 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
504 XMALLOC(MTYPE_BGP_CONFED_LIST
,
505 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
507 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
508 bgp
->confed_peers_cnt
++;
510 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
511 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
512 if (peer
->as
== as
) {
513 peer
->local_as
= bgp
->as
;
514 if (BGP_IS_VALID_STATE_FOR_NOTIF(
517 PEER_DOWN_CONFED_PEER_CHANGE
;
519 peer
, BGP_NOTIFY_CEASE
,
520 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
522 bgp_session_reset_safe(peer
, &nnode
);
529 /* Delete an AS from the confederation set. */
530 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
535 struct listnode
*node
, *nnode
;
540 if (!bgp_confederation_peers_check(bgp
, as
))
543 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
544 if (bgp
->confed_peers
[i
] == as
)
545 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
546 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
548 bgp
->confed_peers_cnt
--;
550 if (bgp
->confed_peers_cnt
== 0) {
551 if (bgp
->confed_peers
)
552 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
553 bgp
->confed_peers
= NULL
;
556 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
557 bgp
->confed_peers_cnt
* sizeof(as_t
));
559 /* Now reset any peer who's remote AS has just been removed from the
561 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
562 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
563 if (peer
->as
== as
) {
564 peer
->local_as
= bgp
->confed_id
;
565 if (BGP_IS_VALID_STATE_FOR_NOTIF(
568 PEER_DOWN_CONFED_PEER_CHANGE
;
570 peer
, BGP_NOTIFY_CEASE
,
571 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
573 bgp_session_reset_safe(peer
, &nnode
);
581 /* Local preference configuration. */
582 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
587 bgp
->default_local_pref
= local_pref
;
592 int bgp_default_local_preference_unset(struct bgp
*bgp
)
597 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
602 /* Local preference configuration. */
603 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
608 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
613 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
617 bgp
->default_subgroup_pkt_queue_max
=
618 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
623 /* Listen limit configuration. */
624 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
629 bgp
->dynamic_neighbors_limit
= listen_limit
;
634 int bgp_listen_limit_unset(struct bgp
*bgp
)
639 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
644 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
645 afi_t
*afi
, safi_t
*safi
)
647 /* Map from IANA values to internal values, return error if
648 * values are unrecognized.
650 *afi
= afi_iana2int(pkt_afi
);
651 *safi
= safi_iana2int(pkt_safi
);
652 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
658 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
659 iana_safi_t
*pkt_safi
)
661 /* Map from internal values to IANA values, return error if
662 * internal values are bad (unexpected).
664 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
666 *pkt_afi
= afi_int2iana(afi
);
667 *pkt_safi
= safi_int2iana(safi
);
671 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
679 afid
= afindex(afi
, safi
);
680 if (afid
>= BGP_AF_MAX
)
683 assert(peer
->peer_af_array
[afid
] == NULL
);
685 /* Allocate new peer af */
686 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
688 peer
->peer_af_array
[afid
] = af
;
697 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
704 afid
= afindex(afi
, safi
);
705 if (afid
>= BGP_AF_MAX
)
708 return peer
->peer_af_array
[afid
];
711 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
719 afid
= afindex(afi
, safi
);
720 if (afid
>= BGP_AF_MAX
)
723 af
= peer
->peer_af_array
[afid
];
727 bgp_stop_announce_route_timer(af
);
729 if (PAF_SUBGRP(af
)) {
730 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
731 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
732 af
->subgroup
->update_group
->id
,
733 af
->subgroup
->id
, peer
->host
);
736 update_subgroup_remove_peer(af
->subgroup
, af
);
738 peer
->peer_af_array
[afid
] = NULL
;
739 XFREE(MTYPE_BGP_PEER_AF
, af
);
743 /* Peer comparison function for sorting. */
744 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
746 if (p1
->group
&& !p2
->group
)
749 if (!p1
->group
&& p2
->group
)
752 if (p1
->group
== p2
->group
) {
753 if (p1
->conf_if
&& !p2
->conf_if
)
756 if (!p1
->conf_if
&& p2
->conf_if
)
759 if (p1
->conf_if
&& p2
->conf_if
)
760 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
762 return strcmp(p1
->group
->name
, p2
->group
->name
);
764 return sockunion_cmp(&p1
->su
, &p2
->su
);
767 static unsigned int peer_hash_key_make(void *p
)
769 struct peer
*peer
= p
;
770 return sockunion_hash(&peer
->su
);
773 static bool peer_hash_same(const void *p1
, const void *p2
)
775 const struct peer
*peer1
= p1
;
776 const struct peer
*peer2
= p2
;
777 return (sockunion_same(&peer1
->su
, &peer2
->su
)
778 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
779 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
782 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
786 /* Skip if peer is not a peer-group member. */
787 if (!peer_group_active(peer
))
790 /* Unset override flag to signal inheritance from peer-group. */
791 UNSET_FLAG(peer
->flags_override
, flag
);
794 * Inherit flag state from peer-group. If the flag of the peer-group is
795 * not being inverted, the peer must inherit the inverse of the current
796 * peer-group flag state.
798 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
799 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
800 && CHECK_FLAG(peer
->flags_invert
, flag
))
801 COND_FLAG(peer
->flags
, flag
, !group_val
);
803 COND_FLAG(peer
->flags
, flag
, group_val
);
806 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
808 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
811 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
816 /* Skip if peer is not a peer-group member. */
817 if (!peer_group_active(peer
))
820 /* Unset override flag to signal inheritance from peer-group. */
821 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
824 * Inherit flag state from peer-group. If the flag of the peer-group is
825 * not being inverted, the peer must inherit the inverse of the current
826 * peer-group flag state.
828 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
829 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
830 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
831 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
833 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
836 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
838 if (!peer_group_active(peer
)) {
839 if (CHECK_FLAG(peer
->flags_invert
, flag
))
840 return !CHECK_FLAG(peer
->flags
, flag
);
842 return !!CHECK_FLAG(peer
->flags
, flag
);
845 return !!CHECK_FLAG(peer
->flags_override
, flag
);
848 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
851 if (!peer_group_active(peer
)) {
852 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
853 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
855 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
858 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
861 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
862 uint8_t type
, int direct
)
864 struct bgp_filter
*filter
;
866 if (peer_group_active(peer
))
867 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
870 filter
= &peer
->filter
[afi
][safi
];
872 case PEER_FT_DISTRIBUTE_LIST
:
873 return !!(filter
->dlist
[direct
].name
);
874 case PEER_FT_FILTER_LIST
:
875 return !!(filter
->aslist
[direct
].name
);
876 case PEER_FT_PREFIX_LIST
:
877 return !!(filter
->plist
[direct
].name
);
878 case PEER_FT_ROUTE_MAP
:
879 return !!(filter
->map
[direct
].name
);
880 case PEER_FT_UNSUPPRESS_MAP
:
881 return !!(filter
->usmap
.name
);
887 /* Return true if the addpath type is set for peer and different from
890 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
892 enum bgp_addpath_strat type
, g_type
;
894 type
= peer
->addpath_type
[afi
][safi
];
896 if (type
!= BGP_ADDPATH_NONE
) {
897 if (peer_group_active(peer
)) {
898 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
912 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
913 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
920 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
921 if (peer
->as_type
== AS_INTERNAL
)
922 return BGP_PEER_IBGP
;
924 else if (peer
->as_type
== AS_EXTERNAL
)
925 return BGP_PEER_EBGP
;
927 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
929 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
937 peer1
= listnode_head(peer
->group
->peer
);
942 return BGP_PEER_INTERNAL
;
946 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
947 if (peer
->local_as
== 0)
948 return BGP_PEER_INTERNAL
;
950 if (peer
->local_as
== peer
->as
) {
951 if (bgp
->as
== bgp
->confed_id
) {
952 if (peer
->local_as
== bgp
->as
)
953 return BGP_PEER_IBGP
;
955 return BGP_PEER_EBGP
;
957 if (peer
->local_as
== bgp
->confed_id
)
958 return BGP_PEER_EBGP
;
960 return BGP_PEER_IBGP
;
964 if (bgp_confederation_peers_check(bgp
, peer
->as
))
965 return BGP_PEER_CONFED
;
967 return BGP_PEER_EBGP
;
969 if (peer
->as_type
!= AS_SPECIFIED
)
970 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
973 return (peer
->local_as
== 0
975 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
980 /* Calculate and cache the peer "sort" */
981 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
983 peer
->sort
= peer_calc_sort(peer
);
987 static void peer_free(struct peer
*peer
)
992 assert(peer
->status
== Deleted
);
996 /* this /ought/ to have been done already through bgp_stop earlier,
997 * but just to be sure..
1000 bgp_reads_off(peer
);
1001 bgp_writes_off(peer
);
1002 assert(!peer
->t_write
);
1003 assert(!peer
->t_read
);
1004 BGP_EVENT_FLUSH(peer
);
1006 pthread_mutex_destroy(&peer
->io_mtx
);
1008 /* Free connected nexthop, if present */
1009 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1010 && !peer_dynamic_neighbor(peer
))
1011 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1014 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1017 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1021 /* Free allocated host character. */
1023 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1027 if (peer
->domainname
) {
1028 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1029 peer
->domainname
= NULL
;
1033 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1034 peer
->ifname
= NULL
;
1037 /* Update source configuration. */
1038 if (peer
->update_source
) {
1039 sockunion_free(peer
->update_source
);
1040 peer
->update_source
= NULL
;
1043 if (peer
->update_if
) {
1044 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1045 peer
->update_if
= NULL
;
1048 if (peer
->notify
.data
)
1049 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1050 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1052 if (peer
->clear_node_queue
)
1053 work_queue_free_and_null(&peer
->clear_node_queue
);
1055 bgp_sync_delete(peer
);
1057 if (peer
->conf_if
) {
1058 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1059 peer
->conf_if
= NULL
;
1062 bfd_info_free(&(peer
->bfd_info
));
1064 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1065 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1066 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1071 bgp_unlock(peer
->bgp
);
1073 memset(peer
, 0, sizeof(struct peer
));
1075 XFREE(MTYPE_BGP_PEER
, peer
);
1078 /* increase reference count on a struct peer */
1079 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1081 assert(peer
&& (peer
->lock
>= 0));
1084 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1092 /* decrease reference count on a struct peer
1093 * struct peer is freed and NULL returned if last reference
1095 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1097 assert(peer
&& (peer
->lock
> 0));
1100 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1105 if (peer
->lock
== 0) {
1113 /* Allocate new peer object, implicitely locked. */
1114 struct peer
*peer_new(struct bgp
*bgp
)
1121 /* bgp argument is absolutely required */
1126 /* Allocate new peer. */
1127 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1129 /* Set default value. */
1131 peer
->v_start
= BGP_INIT_START_TIMER
;
1132 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1133 peer
->status
= Idle
;
1134 peer
->ostatus
= Idle
;
1135 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1136 peer
->bgp
= bgp_lock(bgp
);
1137 peer
= peer_lock(peer
); /* initial reference */
1138 peer
->password
= NULL
;
1140 /* Set default flags. */
1141 FOREACH_AFI_SAFI (afi
, safi
) {
1142 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1143 SET_FLAG(peer
->af_flags
[afi
][safi
],
1144 PEER_FLAG_SEND_COMMUNITY
);
1145 SET_FLAG(peer
->af_flags
[afi
][safi
],
1146 PEER_FLAG_SEND_EXT_COMMUNITY
);
1147 SET_FLAG(peer
->af_flags
[afi
][safi
],
1148 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1150 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1151 PEER_FLAG_SEND_COMMUNITY
);
1152 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1153 PEER_FLAG_SEND_EXT_COMMUNITY
);
1154 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1155 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1157 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1160 /* set nexthop-unchanged for l2vpn evpn by default */
1161 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1162 PEER_FLAG_NEXTHOP_UNCHANGED
);
1164 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1166 /* Create buffers. */
1167 peer
->ibuf
= stream_fifo_new();
1168 peer
->obuf
= stream_fifo_new();
1169 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1171 /* We use a larger buffer for peer->obuf_work in the event that:
1172 * - We RX a BGP_UPDATE where the attributes alone are just
1173 * under BGP_MAX_PACKET_SIZE
1174 * - The user configures an outbound route-map that does many as-path
1175 * prepends or adds many communities. At most they can have
1176 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1177 * large they can make the attributes.
1179 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1180 * bounds checking for every single attribute as we construct an
1184 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1186 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1188 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1190 bgp_sync_init(peer
);
1192 /* Get service port number. */
1193 sp
= getservbyname("bgp", "tcp");
1194 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1196 QOBJ_REG(peer
, peer
);
1201 * This function is invoked when a duplicate peer structure associated with
1202 * a neighbor is being deleted. If this about-to-be-deleted structure is
1203 * the one with all the config, then we have to copy over the info.
1205 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1207 struct peer_af
*paf
;
1215 /* The following function is used by both peer group config copy to
1216 * individual peer and when we transfer config
1218 if (peer_src
->change_local_as
)
1219 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1221 /* peer flags apply */
1222 peer_dst
->flags
= peer_src
->flags
;
1223 peer_dst
->cap
= peer_src
->cap
;
1225 peer_dst
->local_as
= peer_src
->local_as
;
1226 peer_dst
->port
= peer_src
->port
;
1227 (void)peer_sort(peer_dst
);
1228 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1231 peer_dst
->holdtime
= peer_src
->holdtime
;
1232 peer_dst
->keepalive
= peer_src
->keepalive
;
1233 peer_dst
->connect
= peer_src
->connect
;
1234 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1235 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1236 peer_dst
->routeadv
= peer_src
->routeadv
;
1237 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1239 /* password apply */
1240 if (peer_src
->password
&& !peer_dst
->password
)
1241 peer_dst
->password
=
1242 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1244 FOREACH_AFI_SAFI (afi
, safi
) {
1245 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1246 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1247 peer_dst
->allowas_in
[afi
][safi
] =
1248 peer_src
->allowas_in
[afi
][safi
];
1249 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1250 peer_dst
->addpath_type
[afi
][safi
] =
1251 peer_src
->addpath_type
[afi
][safi
];
1254 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1255 paf
= peer_src
->peer_af_array
[afidx
];
1257 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1260 /* update-source apply */
1261 if (peer_src
->update_source
) {
1262 if (peer_dst
->update_source
)
1263 sockunion_free(peer_dst
->update_source
);
1264 if (peer_dst
->update_if
) {
1265 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1266 peer_dst
->update_if
= NULL
;
1268 peer_dst
->update_source
=
1269 sockunion_dup(peer_src
->update_source
);
1270 } else if (peer_src
->update_if
) {
1271 if (peer_dst
->update_if
)
1272 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1273 if (peer_dst
->update_source
) {
1274 sockunion_free(peer_dst
->update_source
);
1275 peer_dst
->update_source
= NULL
;
1277 peer_dst
->update_if
=
1278 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1281 if (peer_src
->ifname
) {
1282 if (peer_dst
->ifname
)
1283 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1286 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1290 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1291 struct interface
*ifp
)
1293 struct connected
*ifc
;
1296 struct listnode
*node
;
1298 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1299 * IPv4 address of the other end.
1301 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1302 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1303 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1304 if (p
.prefixlen
== 30) {
1305 peer
->su
.sa
.sa_family
= AF_INET
;
1306 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1308 peer
->su
.sin
.sin_addr
.s_addr
=
1310 else if (addr
% 4 == 2)
1311 peer
->su
.sin
.sin_addr
.s_addr
=
1313 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1314 peer
->su
.sin
.sin_len
=
1315 sizeof(struct sockaddr_in
);
1316 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1318 } else if (p
.prefixlen
== 31) {
1319 peer
->su
.sa
.sa_family
= AF_INET
;
1320 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1322 peer
->su
.sin
.sin_addr
.s_addr
=
1325 peer
->su
.sin
.sin_addr
.s_addr
=
1327 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1328 peer
->su
.sin
.sin_len
=
1329 sizeof(struct sockaddr_in
);
1330 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1332 } else if (bgp_debug_neighbor_events(peer
))
1334 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1342 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1343 struct interface
*ifp
)
1345 struct nbr_connected
*ifc_nbr
;
1347 /* Have we learnt the peer's IPv6 link-local address? */
1348 if (ifp
->nbr_connected
1349 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1350 peer
->su
.sa
.sa_family
= AF_INET6
;
1351 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1352 sizeof(struct in6_addr
));
1354 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1356 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1364 * Set or reset the peer address socketunion structure based on the
1365 * learnt/derived peer address. If the address has changed, update the
1366 * password on the listen socket, if needed.
1368 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1370 struct interface
*ifp
;
1372 int peer_addr_updated
= 0;
1378 * Our peer structure is stored in the bgp->peerhash
1379 * release it before we modify anything.
1381 hash_release(peer
->bgp
->peerhash
, peer
);
1383 prev_family
= peer
->su
.sa
.sa_family
;
1384 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1386 /* If BGP unnumbered is not "v6only", we first see if we can
1388 * peer's IPv4 address.
1390 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1392 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1394 /* If "v6only" or we can't derive peer's IPv4 address, see if
1396 * learnt the peer's IPv6 link-local address. This is from the
1398 * IPv6 address in router advertisement.
1400 if (!peer_addr_updated
)
1402 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1404 /* If we could derive the peer address, we may need to install the
1406 * configured for the peer, if any, on the listen socket. Otherwise,
1408 * that peer's address is not available and uninstall the password, if
1411 if (peer_addr_updated
) {
1412 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1413 && prev_family
== AF_UNSPEC
)
1416 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1417 && prev_family
!= AF_UNSPEC
)
1418 bgp_md5_unset(peer
);
1419 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1420 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1424 * Since our su changed we need to del/add peer to the peerhash
1426 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1429 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1432 struct bgp_node
*rn
, *nrn
;
1434 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1435 rn
= bgp_route_next(rn
)) {
1436 if (rn
->info
!= NULL
) {
1437 /* Special handling for 2-level routing
1439 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1440 || safi
== SAFI_EVPN
) {
1441 for (nrn
= bgp_table_top(
1442 (struct bgp_table
*)(rn
->info
));
1443 nrn
; nrn
= bgp_route_next(nrn
))
1444 bgp_process(bgp
, nrn
, afi
, safi
);
1446 bgp_process(bgp
, rn
, afi
, safi
);
1451 /* Force a bestpath recalculation for all prefixes. This is used
1452 * when 'bgp bestpath' commands are entered.
1454 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1459 FOREACH_AFI_SAFI (afi
, safi
) {
1460 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1465 * Create new BGP peer.
1467 * conf_if and su are mutually exclusive if configuring from the cli.
1468 * If we are handing a doppelganger, then we *must* pass in both
1469 * the original peer's su and conf_if, so that we can appropriately
1470 * track the bgp->peerhash( ie we don't want to remove the current
1471 * one from the config ).
1473 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1474 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1475 int as_type
, afi_t afi
, safi_t safi
,
1476 struct peer_group
*group
)
1480 char buf
[SU_ADDRSTRLEN
];
1482 peer
= peer_new(bgp
);
1484 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1488 bgp_peer_conf_if_to_su_update(peer
);
1490 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1491 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1494 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1496 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1497 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1499 peer
->local_as
= local_as
;
1500 peer
->as
= remote_as
;
1501 peer
->as_type
= as_type
;
1502 peer
->local_id
= bgp
->router_id
;
1503 peer
->v_holdtime
= bgp
->default_holdtime
;
1504 peer
->v_keepalive
= bgp
->default_keepalive
;
1505 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1506 ? BGP_DEFAULT_IBGP_ROUTEADV
1507 : BGP_DEFAULT_EBGP_ROUTEADV
;
1509 peer
= peer_lock(peer
); /* bgp peer list reference */
1510 peer
->group
= group
;
1511 listnode_add_sort(bgp
->peer
, peer
);
1512 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1514 /* Adjust update-group coalesce timer heuristics for # peers. */
1515 if (bgp
->heuristic_coalesce
) {
1516 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1518 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1519 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1522 active
= peer_active(peer
);
1524 /* Last read and reset time set */
1525 peer
->readtime
= peer
->resettime
= bgp_clock();
1527 /* Default TTL set. */
1528 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1530 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1533 peer
->afc
[afi
][safi
] = 1;
1534 peer_af_create(peer
, afi
, safi
);
1537 /* auto shutdown if configured */
1538 if (bgp
->autoshutdown
)
1539 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1540 /* Set up peer's events and timers. */
1541 else if (!active
&& peer_active(peer
))
1542 bgp_timer_set(peer
);
1547 /* Make accept BGP peer. This function is only called from the test code */
1548 struct peer
*peer_create_accept(struct bgp
*bgp
)
1552 peer
= peer_new(bgp
);
1554 peer
= peer_lock(peer
); /* bgp peer list reference */
1555 listnode_add_sort(bgp
->peer
, peer
);
1561 * Return true if we have a peer configured to use this afi/safi
1563 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1565 struct listnode
*node
;
1568 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1569 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1572 if (peer
->afc
[afi
][safi
])
1579 /* Change peer's AS number. */
1580 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1582 bgp_peer_sort_t type
;
1585 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1586 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1587 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1588 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1589 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1591 bgp_session_reset(peer
);
1593 type
= peer_sort(peer
);
1595 peer
->as_type
= as_specified
;
1597 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1598 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1599 && peer
->bgp
->as
!= as
)
1600 peer
->local_as
= peer
->bgp
->confed_id
;
1602 peer
->local_as
= peer
->bgp
->as
;
1604 /* Advertisement-interval reset */
1605 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1606 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1607 ? BGP_DEFAULT_IBGP_ROUTEADV
1608 : BGP_DEFAULT_EBGP_ROUTEADV
;
1612 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1614 else if (type
== BGP_PEER_IBGP
)
1617 /* reflector-client reset */
1618 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1619 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1620 PEER_FLAG_REFLECTOR_CLIENT
);
1621 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1622 PEER_FLAG_REFLECTOR_CLIENT
);
1623 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1624 PEER_FLAG_REFLECTOR_CLIENT
);
1625 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1626 PEER_FLAG_REFLECTOR_CLIENT
);
1627 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1628 PEER_FLAG_REFLECTOR_CLIENT
);
1629 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1630 PEER_FLAG_REFLECTOR_CLIENT
);
1631 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1632 PEER_FLAG_REFLECTOR_CLIENT
);
1633 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1634 PEER_FLAG_REFLECTOR_CLIENT
);
1635 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1636 PEER_FLAG_REFLECTOR_CLIENT
);
1637 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1638 PEER_FLAG_REFLECTOR_CLIENT
);
1639 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1640 PEER_FLAG_REFLECTOR_CLIENT
);
1641 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1642 PEER_FLAG_REFLECTOR_CLIENT
);
1643 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1644 PEER_FLAG_REFLECTOR_CLIENT
);
1647 /* local-as reset */
1648 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1649 peer
->change_local_as
= 0;
1650 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1651 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1652 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1656 /* If peer does not exist, create new one. If peer already exists,
1657 set AS number to the peer. */
1658 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1659 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1665 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1667 peer
= peer_lookup(bgp
, su
);
1670 /* Not allowed for a dynamic peer. */
1671 if (peer_dynamic_neighbor(peer
)) {
1673 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1676 /* When this peer is a member of peer-group. */
1678 if (peer
->group
->conf
->as
) {
1679 /* Return peer group's AS number. */
1680 *as
= peer
->group
->conf
->as
;
1681 return BGP_ERR_PEER_GROUP_MEMBER
;
1683 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1684 if ((as_type
!= AS_INTERNAL
)
1685 && (bgp
->as
!= *as
)) {
1687 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1690 if ((as_type
!= AS_EXTERNAL
)
1691 && (bgp
->as
== *as
)) {
1693 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1698 /* Existing peer's AS number change. */
1699 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1700 || (peer
->as_type
!= as_type
))
1701 peer_as_change(peer
, *as
, as_type
);
1704 return BGP_ERR_NO_INTERFACE_CONFIG
;
1706 /* If the peer is not part of our confederation, and its not an
1707 iBGP peer then spoof the source AS */
1708 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1709 && !bgp_confederation_peers_check(bgp
, *as
)
1711 local_as
= bgp
->confed_id
;
1715 /* If this is IPv4 unicast configuration and "no bgp default
1716 ipv4-unicast" is specified. */
1718 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1719 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1720 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1723 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1730 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1731 struct peer
*peer
, afi_t afi
,
1735 int out
= FILTER_OUT
;
1737 uint32_t pflags_ovrd
;
1738 uint8_t *pfilter_ovrd
;
1742 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1743 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1745 /* peer af_flags apply */
1746 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1747 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1748 ^ peer
->af_flags_invert
[afi
][safi
];
1749 flags_tmp
&= ~pflags_ovrd
;
1751 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1752 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1753 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1754 conf
->af_flags_invert
[afi
][safi
]);
1756 /* maximum-prefix */
1757 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1758 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1759 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1760 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1764 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1765 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1768 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1769 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1771 /* default-originate route-map */
1772 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1773 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1774 MTYPE_ROUTE_MAP_NAME
);
1775 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1778 /* inbound filter apply */
1779 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1780 PEER_STR_ATTR_INHERIT(peer
, group
,
1781 filter
[afi
][safi
].dlist
[in
].name
,
1782 MTYPE_BGP_FILTER_NAME
);
1783 PEER_ATTR_INHERIT(peer
, group
,
1784 filter
[afi
][safi
].dlist
[in
].alist
);
1787 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1788 PEER_STR_ATTR_INHERIT(peer
, group
,
1789 filter
[afi
][safi
].plist
[in
].name
,
1790 MTYPE_BGP_FILTER_NAME
);
1791 PEER_ATTR_INHERIT(peer
, group
,
1792 filter
[afi
][safi
].plist
[in
].plist
);
1795 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1796 PEER_STR_ATTR_INHERIT(peer
, group
,
1797 filter
[afi
][safi
].aslist
[in
].name
,
1798 MTYPE_BGP_FILTER_NAME
);
1799 PEER_ATTR_INHERIT(peer
, group
,
1800 filter
[afi
][safi
].aslist
[in
].aslist
);
1803 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1804 PEER_STR_ATTR_INHERIT(peer
, group
,
1805 filter
[afi
][safi
].map
[in
].name
,
1806 MTYPE_BGP_FILTER_NAME
);
1807 PEER_ATTR_INHERIT(peer
, group
,
1808 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1811 /* outbound filter apply */
1812 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1813 PEER_STR_ATTR_INHERIT(peer
, group
,
1814 filter
[afi
][safi
].dlist
[out
].name
,
1815 MTYPE_BGP_FILTER_NAME
);
1816 PEER_ATTR_INHERIT(peer
, group
,
1817 filter
[afi
][safi
].dlist
[out
].alist
);
1820 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1821 PEER_STR_ATTR_INHERIT(peer
, group
,
1822 filter
[afi
][safi
].plist
[out
].name
,
1823 MTYPE_BGP_FILTER_NAME
);
1824 PEER_ATTR_INHERIT(peer
, group
,
1825 filter
[afi
][safi
].plist
[out
].plist
);
1828 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1829 PEER_STR_ATTR_INHERIT(peer
, group
,
1830 filter
[afi
][safi
].aslist
[out
].name
,
1831 MTYPE_BGP_FILTER_NAME
);
1832 PEER_ATTR_INHERIT(peer
, group
,
1833 filter
[afi
][safi
].aslist
[out
].aslist
);
1836 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1837 PEER_STR_ATTR_INHERIT(peer
, group
,
1838 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1839 MTYPE_BGP_FILTER_NAME
);
1840 PEER_ATTR_INHERIT(peer
, group
,
1841 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1844 /* nondirectional filter apply */
1845 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1846 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1847 MTYPE_BGP_FILTER_NAME
);
1848 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1851 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1852 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1853 bgp_addpath_type_changed(conf
->bgp
);
1857 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1862 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1863 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1864 __func__
, peer
->host
);
1868 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1870 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1871 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1872 return BGP_ERR_PEER_SAFI_CONFLICT
;
1874 /* Nothing to do if we've already activated this peer */
1875 if (peer
->afc
[afi
][safi
])
1878 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1881 active
= peer_active(peer
);
1882 peer
->afc
[afi
][safi
] = 1;
1885 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1887 if (!active
&& peer_active(peer
)) {
1888 bgp_timer_set(peer
);
1890 if (peer
->status
== Established
) {
1891 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1892 peer
->afc_adv
[afi
][safi
] = 1;
1893 bgp_capability_send(peer
, afi
, safi
,
1895 CAPABILITY_ACTION_SET
);
1896 if (peer
->afc_recv
[afi
][safi
]) {
1897 peer
->afc_nego
[afi
][safi
] = 1;
1898 bgp_announce_route(peer
, afi
, safi
);
1901 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1902 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1903 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1906 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1907 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1908 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1909 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1912 * If we are turning on a AFI/SAFI locally and we've
1913 * started bringing a peer up, we need to tell
1914 * the other peer to restart because we might loose
1915 * configuration here because when the doppelganger
1916 * gets to a established state due to how
1917 * we resolve we could just overwrite the afi/safi
1920 other
= peer
->doppelganger
;
1922 && (other
->status
== OpenSent
1923 || other
->status
== OpenConfirm
)) {
1924 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1925 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1926 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1933 /* Activate the peer or peer group for specified AFI and SAFI. */
1934 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1937 struct peer_group
*group
;
1938 struct listnode
*node
, *nnode
;
1939 struct peer
*tmp_peer
;
1942 /* Nothing to do if we've already activated this peer */
1943 if (peer
->afc
[afi
][safi
])
1948 /* This is a peer-group so activate all of the members of the
1949 * peer-group as well */
1950 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1952 /* Do not activate a peer for both SAFI_UNICAST and
1953 * SAFI_LABELED_UNICAST */
1954 if ((safi
== SAFI_UNICAST
1955 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1956 || (safi
== SAFI_LABELED_UNICAST
1957 && peer
->afc
[afi
][SAFI_UNICAST
]))
1958 return BGP_ERR_PEER_SAFI_CONFLICT
;
1960 peer
->afc
[afi
][safi
] = 1;
1961 group
= peer
->group
;
1963 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1964 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1967 ret
|= peer_activate_af(peer
, afi
, safi
);
1970 /* If this is the first peer to be activated for this
1971 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1972 if (safi
== SAFI_LABELED_UNICAST
1973 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1975 if (BGP_DEBUG(zebra
, ZEBRA
))
1977 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1979 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1980 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1983 if (safi
== SAFI_FLOWSPEC
) {
1984 /* connect to table manager */
1985 bgp_zebra_init_tm_connect(bgp
);
1990 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1993 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1994 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1995 __func__
, peer
->host
);
1999 /* Nothing to do if we've already deactivated this peer */
2000 if (!peer
->afc
[afi
][safi
])
2003 /* De-activate the address family configuration. */
2004 peer
->afc
[afi
][safi
] = 0;
2006 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2007 flog_err(EC_BGP_PEER_DELETE
,
2008 "couldn't delete af structure for peer %s",
2013 if (peer
->status
== Established
) {
2014 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2015 peer
->afc_adv
[afi
][safi
] = 0;
2016 peer
->afc_nego
[afi
][safi
] = 0;
2018 if (peer_active_nego(peer
)) {
2019 bgp_capability_send(peer
, afi
, safi
,
2021 CAPABILITY_ACTION_UNSET
);
2022 bgp_clear_route(peer
, afi
, safi
);
2023 peer
->pcount
[afi
][safi
] = 0;
2025 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2026 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2027 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2030 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2031 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2032 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2039 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2042 struct peer_group
*group
;
2043 struct peer
*tmp_peer
;
2044 struct listnode
*node
, *nnode
;
2047 /* Nothing to do if we've already de-activated this peer */
2048 if (!peer
->afc
[afi
][safi
])
2051 /* This is a peer-group so de-activate all of the members of the
2052 * peer-group as well */
2053 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2054 peer
->afc
[afi
][safi
] = 0;
2055 group
= peer
->group
;
2057 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2058 flog_err(EC_BGP_PEER_DELETE
,
2059 "couldn't delete af structure for peer %s",
2063 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2064 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2067 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2072 /* If this is the last peer to be deactivated for this
2073 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2074 if (safi
== SAFI_LABELED_UNICAST
2075 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2076 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2078 if (BGP_DEBUG(zebra
, ZEBRA
))
2080 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2082 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2083 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2088 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2091 return peer_activate(peer
, afi
, safi
);
2093 return peer_deactivate(peer
, afi
, safi
);
2096 static void peer_nsf_stop(struct peer
*peer
)
2101 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2102 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2104 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2105 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2106 peer
->nsf
[afi
][safi
] = 0;
2108 if (peer
->t_gr_restart
) {
2109 BGP_TIMER_OFF(peer
->t_gr_restart
);
2110 if (bgp_debug_neighbor_events(peer
))
2111 zlog_debug("%s graceful restart timer stopped",
2114 if (peer
->t_gr_stale
) {
2115 BGP_TIMER_OFF(peer
->t_gr_stale
);
2116 if (bgp_debug_neighbor_events(peer
))
2118 "%s graceful restart stalepath timer stopped",
2121 bgp_clear_route_all(peer
);
2124 /* Delete peer from confguration.
2126 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2127 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2129 * This function /should/ take care to be idempotent, to guard against
2130 * it being called multiple times through stray events that come in
2131 * that happen to result in this function being called again. That
2132 * said, getting here for a "Deleted" peer is a bug in the neighbour
2135 int peer_delete(struct peer
*peer
)
2141 struct bgp_filter
*filter
;
2142 struct listnode
*pn
;
2145 assert(peer
->status
!= Deleted
);
2148 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2150 bgp_reads_off(peer
);
2151 bgp_writes_off(peer
);
2152 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2153 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2155 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2156 peer_nsf_stop(peer
);
2158 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2160 /* If this peer belongs to peer group, clear up the
2163 if (peer_dynamic_neighbor(peer
))
2164 peer_drop_dynamic_neighbor(peer
);
2166 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2168 peer
); /* group->peer list reference */
2169 list_delete_node(peer
->group
->peer
, pn
);
2174 /* Withdraw all information from routing table. We can not use
2175 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2176 * executed after peer structure is deleted.
2178 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2180 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2182 if (peer
->doppelganger
) {
2183 peer
->doppelganger
->doppelganger
= NULL
;
2184 peer
->doppelganger
= NULL
;
2187 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2188 bgp_fsm_change_status(peer
, Deleted
);
2190 /* Remove from NHT */
2191 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2192 bgp_unlink_nexthop_by_peer(peer
);
2194 /* Password configuration */
2195 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2196 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2198 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2199 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2200 bgp_md5_unset(peer
);
2203 bgp_timer_set(peer
); /* stops all timers for Deleted */
2205 /* Delete from all peer list. */
2206 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2207 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2208 peer_unlock(peer
); /* bgp peer list reference */
2209 list_delete_node(bgp
->peer
, pn
);
2210 hash_release(bgp
->peerhash
, peer
);
2215 stream_fifo_free(peer
->ibuf
);
2220 stream_fifo_free(peer
->obuf
);
2224 if (peer
->ibuf_work
) {
2225 ringbuf_del(peer
->ibuf_work
);
2226 peer
->ibuf_work
= NULL
;
2229 if (peer
->obuf_work
) {
2230 stream_free(peer
->obuf_work
);
2231 peer
->obuf_work
= NULL
;
2234 if (peer
->scratch
) {
2235 stream_free(peer
->scratch
);
2236 peer
->scratch
= NULL
;
2239 /* Local and remote addresses. */
2240 if (peer
->su_local
) {
2241 sockunion_free(peer
->su_local
);
2242 peer
->su_local
= NULL
;
2245 if (peer
->su_remote
) {
2246 sockunion_free(peer
->su_remote
);
2247 peer
->su_remote
= NULL
;
2250 /* Free filter related memory. */
2251 FOREACH_AFI_SAFI (afi
, safi
) {
2252 filter
= &peer
->filter
[afi
][safi
];
2254 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2255 if (filter
->dlist
[i
].name
) {
2256 XFREE(MTYPE_BGP_FILTER_NAME
,
2257 filter
->dlist
[i
].name
);
2258 filter
->dlist
[i
].name
= NULL
;
2261 if (filter
->plist
[i
].name
) {
2262 XFREE(MTYPE_BGP_FILTER_NAME
,
2263 filter
->plist
[i
].name
);
2264 filter
->plist
[i
].name
= NULL
;
2267 if (filter
->aslist
[i
].name
) {
2268 XFREE(MTYPE_BGP_FILTER_NAME
,
2269 filter
->aslist
[i
].name
);
2270 filter
->aslist
[i
].name
= NULL
;
2274 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2275 if (filter
->map
[i
].name
) {
2276 XFREE(MTYPE_BGP_FILTER_NAME
,
2277 filter
->map
[i
].name
);
2278 filter
->map
[i
].name
= NULL
;
2282 if (filter
->usmap
.name
) {
2283 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2284 filter
->usmap
.name
= NULL
;
2287 if (peer
->default_rmap
[afi
][safi
].name
) {
2288 XFREE(MTYPE_ROUTE_MAP_NAME
,
2289 peer
->default_rmap
[afi
][safi
].name
);
2290 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2294 FOREACH_AFI_SAFI (afi
, safi
)
2295 peer_af_delete(peer
, afi
, safi
);
2297 if (peer
->hostname
) {
2298 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2299 peer
->hostname
= NULL
;
2302 if (peer
->domainname
) {
2303 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2304 peer
->domainname
= NULL
;
2307 peer_unlock(peer
); /* initial reference */
2312 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2314 return strcmp(g1
->name
, g2
->name
);
2317 /* Peer group cofiguration. */
2318 static struct peer_group
*peer_group_new(void)
2320 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2321 sizeof(struct peer_group
));
2324 static void peer_group_free(struct peer_group
*group
)
2326 XFREE(MTYPE_PEER_GROUP
, group
);
2329 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2331 struct peer_group
*group
;
2332 struct listnode
*node
, *nnode
;
2334 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2335 if (strcmp(group
->name
, name
) == 0)
2341 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2343 struct peer_group
*group
;
2346 group
= peer_group_lookup(bgp
, name
);
2350 group
= peer_group_new();
2353 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2354 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2355 group
->peer
= list_new();
2356 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2357 group
->listen_range
[afi
] = list_new();
2358 group
->conf
= peer_new(bgp
);
2359 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2360 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2361 if (group
->conf
->host
)
2362 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2363 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2364 group
->conf
->group
= group
;
2365 group
->conf
->as
= 0;
2366 group
->conf
->ttl
= 1;
2367 group
->conf
->gtsm_hops
= 0;
2368 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2369 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2370 listnode_add_sort(bgp
->group
, group
);
2375 static void peer_group2peer_config_copy(struct peer_group
*group
,
2385 peer
->as
= conf
->as
;
2388 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2389 peer
->change_local_as
= conf
->change_local_as
;
2392 peer
->ttl
= conf
->ttl
;
2395 peer
->gtsm_hops
= conf
->gtsm_hops
;
2397 /* peer flags apply */
2398 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2399 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2400 flags_tmp
&= ~peer
->flags_override
;
2402 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2403 SET_FLAG(peer
->flags
, flags_tmp
);
2404 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2406 /* peer timers apply */
2407 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2408 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2409 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2412 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2413 PEER_ATTR_INHERIT(peer
, group
, connect
);
2414 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2415 peer
->v_connect
= conf
->connect
;
2417 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2420 /* advertisement-interval apply */
2421 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2422 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2423 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2424 peer
->v_routeadv
= conf
->routeadv
;
2426 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2427 ? BGP_DEFAULT_IBGP_ROUTEADV
2428 : BGP_DEFAULT_EBGP_ROUTEADV
;
2431 /* password apply */
2432 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2433 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2434 MTYPE_PEER_PASSWORD
);
2436 if (!BGP_PEER_SU_UNSPEC(peer
))
2439 /* update-source apply */
2440 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2441 if (conf
->update_source
) {
2442 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2443 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2444 } else if (conf
->update_if
) {
2445 sockunion_free(peer
->update_source
);
2446 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2447 MTYPE_PEER_UPDATE_SOURCE
);
2451 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2454 /* Peer group's remote AS configuration. */
2455 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2458 struct peer_group
*group
;
2460 struct listnode
*node
, *nnode
;
2462 group
= peer_group_lookup(bgp
, group_name
);
2466 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2470 /* When we setup peer-group AS number all peer group member's AS
2471 number must be updated to same number. */
2472 peer_as_change(group
->conf
, *as
, as_type
);
2474 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2475 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2476 || (peer
->as_type
!= as_type
))
2477 peer_as_change(peer
, *as
, as_type
);
2483 int peer_group_delete(struct peer_group
*group
)
2487 struct prefix
*prefix
;
2489 struct listnode
*node
, *nnode
;
2494 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2495 other
= peer
->doppelganger
;
2497 if (other
&& other
->status
!= Deleted
) {
2498 other
->group
= NULL
;
2502 list_delete(&group
->peer
);
2504 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2505 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2507 prefix_free(prefix
);
2509 list_delete(&group
->listen_range
[afi
]);
2512 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2515 bfd_info_free(&(group
->conf
->bfd_info
));
2517 group
->conf
->group
= NULL
;
2518 peer_delete(group
->conf
);
2520 /* Delete from all peer_group list. */
2521 listnode_delete(bgp
->group
, group
);
2523 peer_group_free(group
);
2528 int peer_group_remote_as_delete(struct peer_group
*group
)
2530 struct peer
*peer
, *other
;
2531 struct listnode
*node
, *nnode
;
2533 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2534 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2537 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2538 other
= peer
->doppelganger
;
2542 if (other
&& other
->status
!= Deleted
) {
2543 other
->group
= NULL
;
2547 list_delete_all_node(group
->peer
);
2549 group
->conf
->as
= 0;
2550 group
->conf
->as_type
= AS_UNSPECIFIED
;
2555 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2557 struct prefix
*prefix
;
2558 struct listnode
*node
, *nnode
;
2561 afi
= family2afi(range
->family
);
2563 /* Group needs remote AS configured. */
2564 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2565 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2567 /* Ensure no duplicates. Currently we don't care about overlaps. */
2568 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2569 if (prefix_same(range
, prefix
))
2573 prefix
= prefix_new();
2574 prefix_copy(prefix
, range
);
2575 listnode_add(group
->listen_range
[afi
], prefix
);
2579 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2581 struct prefix
*prefix
, prefix2
;
2582 struct listnode
*node
, *nnode
;
2585 char buf
[PREFIX2STR_BUFFER
];
2587 afi
= family2afi(range
->family
);
2589 /* Identify the listen range. */
2590 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2591 if (prefix_same(range
, prefix
))
2596 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2598 prefix2str(prefix
, buf
, sizeof(buf
));
2600 /* Dispose off any dynamic neighbors that exist due to this listen range
2602 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2603 if (!peer_dynamic_neighbor(peer
))
2606 sockunion2hostprefix(&peer
->su
, &prefix2
);
2607 if (prefix_match(prefix
, &prefix2
)) {
2608 if (bgp_debug_neighbor_events(peer
))
2610 "Deleting dynamic neighbor %s group %s upon "
2611 "delete of listen range %s",
2612 peer
->host
, group
->name
, buf
);
2617 /* Get rid of the listen range */
2618 listnode_delete(group
->listen_range
[afi
], prefix
);
2623 /* Bind specified peer to peer group. */
2624 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2625 struct peer_group
*group
, as_t
*as
)
2627 int first_member
= 0;
2631 /* Lookup the peer. */
2633 peer
= peer_lookup(bgp
, su
);
2635 /* The peer exist, bind it to the peer-group */
2637 /* When the peer already belongs to a peer-group, check the
2639 if (peer_group_active(peer
)) {
2641 /* The peer is already bound to the peer-group,
2644 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2647 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2650 /* The peer has not specified a remote-as, inherit it from the
2652 if (peer
->as_type
== AS_UNSPECIFIED
) {
2653 peer
->as_type
= group
->conf
->as_type
;
2654 peer
->as
= group
->conf
->as
;
2657 if (!group
->conf
->as
) {
2658 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2659 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2662 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2665 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2669 peer_group2peer_config_copy(group
, peer
);
2671 FOREACH_AFI_SAFI (afi
, safi
) {
2672 if (group
->conf
->afc
[afi
][safi
]) {
2673 peer
->afc
[afi
][safi
] = 1;
2675 if (peer_af_find(peer
, afi
, safi
)
2676 || peer_af_create(peer
, afi
, safi
)) {
2677 peer_group2peer_config_copy_af(
2678 group
, peer
, afi
, safi
);
2680 } else if (peer
->afc
[afi
][safi
])
2681 peer_deactivate(peer
, afi
, safi
);
2685 assert(group
&& peer
->group
== group
);
2687 listnode_delete(bgp
->peer
, peer
);
2689 peer
->group
= group
;
2690 listnode_add_sort(bgp
->peer
, peer
);
2692 peer
= peer_lock(peer
); /* group->peer list reference */
2693 listnode_add(group
->peer
, peer
);
2697 /* Advertisement-interval reset */
2698 if (!CHECK_FLAG(group
->conf
->flags
,
2699 PEER_FLAG_ROUTEADV
)) {
2700 group
->conf
->v_routeadv
=
2701 (peer_sort(group
->conf
)
2703 ? BGP_DEFAULT_IBGP_ROUTEADV
2704 : BGP_DEFAULT_EBGP_ROUTEADV
;
2707 /* ebgp-multihop reset */
2708 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2709 group
->conf
->ttl
= MAXTTL
;
2711 /* local-as reset */
2712 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2713 group
->conf
->change_local_as
= 0;
2714 peer_flag_unset(group
->conf
,
2715 PEER_FLAG_LOCAL_AS
);
2716 peer_flag_unset(group
->conf
,
2717 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2718 peer_flag_unset(group
->conf
,
2719 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2723 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2725 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2726 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2727 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2728 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2730 bgp_session_reset(peer
);
2734 /* Create a new peer. */
2736 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2737 && (!group
->conf
->as
)) {
2738 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2741 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2742 group
->conf
->as_type
, 0, 0, group
);
2744 peer
= peer_lock(peer
); /* group->peer list reference */
2745 listnode_add(group
->peer
, peer
);
2747 peer_group2peer_config_copy(group
, peer
);
2749 /* If the peer-group is active for this afi/safi then activate
2751 FOREACH_AFI_SAFI (afi
, safi
) {
2752 if (group
->conf
->afc
[afi
][safi
]) {
2753 peer
->afc
[afi
][safi
] = 1;
2754 peer_af_create(peer
, afi
, safi
);
2755 peer_group2peer_config_copy_af(group
, peer
, afi
,
2757 } else if (peer
->afc
[afi
][safi
])
2758 peer_deactivate(peer
, afi
, safi
);
2761 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2763 /* Set up peer's events and timers. */
2764 if (peer_active(peer
))
2765 bgp_timer_set(peer
);
2771 static int bgp_startup_timer_expire(struct thread
*thread
)
2775 bgp
= THREAD_ARG(thread
);
2776 bgp
->t_startup
= NULL
;
2782 * On shutdown we call the cleanup function which
2783 * does a free of the link list nodes, free up
2784 * the data we are pointing at too.
2786 static void bgp_vrf_string_name_delete(void *data
)
2790 XFREE(MTYPE_TMP
, vname
);
2793 /* BGP instance creation by `router bgp' commands. */
2794 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2795 enum bgp_instance_type inst_type
)
2801 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2804 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2805 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2806 zlog_debug("Creating Default VRF, AS %u", *as
);
2808 zlog_debug("Creating %s %s, AS %u",
2809 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2816 bgp
->heuristic_coalesce
= true;
2817 bgp
->inst_type
= inst_type
;
2818 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2820 bgp
->peer_self
= peer_new(bgp
);
2821 if (bgp
->peer_self
->host
)
2822 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2823 bgp
->peer_self
->host
=
2824 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2825 if (bgp
->peer_self
->hostname
!= NULL
) {
2826 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2827 bgp
->peer_self
->hostname
= NULL
;
2829 if (cmd_hostname_get())
2830 bgp
->peer_self
->hostname
=
2831 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2833 if (bgp
->peer_self
->domainname
!= NULL
) {
2834 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2835 bgp
->peer_self
->domainname
= NULL
;
2837 if (cmd_domainname_get())
2838 bgp
->peer_self
->domainname
=
2839 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2840 bgp
->peer
= list_new();
2841 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2842 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2844 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2846 bgp
->group
= list_new();
2847 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2849 FOREACH_AFI_SAFI (afi
, safi
) {
2850 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2851 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2852 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2854 /* Enable maximum-paths */
2855 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2857 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2861 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2862 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2863 bgp
->default_subgroup_pkt_queue_max
=
2864 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2865 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2866 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2867 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2868 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2869 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2870 bgp
->dynamic_neighbors_count
= 0;
2871 #if DFLT_BGP_IMPORT_CHECK
2872 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2874 #if DFLT_BGP_SHOW_HOSTNAME
2875 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2877 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2878 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2880 #if DFLT_BGP_DETERMINISTIC_MED
2881 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2883 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2888 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2889 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2891 assert(bgp
->rfapi_cfg
);
2893 #endif /* ENABLE_BGP_VNC */
2895 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2896 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2897 bgp
->vpn_policy
[afi
].afi
= afi
;
2898 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2899 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2902 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2903 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2904 bgp_vrf_string_name_delete
;
2905 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2906 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2907 bgp_vrf_string_name_delete
;
2910 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2912 /* TODO - The startup timer needs to be run for the whole of BGP
2914 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2915 bgp
->restart_time
, &bgp
->t_startup
);
2918 /* printable name we can use in debug messages */
2919 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2920 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2930 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2932 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2933 snprintf(bgp
->name_pretty
, len
, "%s %s",
2934 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2940 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2941 memory_order_relaxed
);
2942 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2943 memory_order_relaxed
);
2944 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2948 update_bgp_group_init(bgp
);
2950 /* assign a unique rd id for auto derivation of vrf's RD */
2951 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2958 /* Return the "default VRF" instance of BGP. */
2959 struct bgp
*bgp_get_default(void)
2962 struct listnode
*node
, *nnode
;
2964 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2965 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2970 /* Lookup BGP entry. */
2971 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2974 struct listnode
*node
, *nnode
;
2976 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2978 && ((bgp
->name
== NULL
&& name
== NULL
)
2979 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2984 /* Lookup BGP structure by view name. */
2985 struct bgp
*bgp_lookup_by_name(const char *name
)
2988 struct listnode
*node
, *nnode
;
2990 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2991 if ((bgp
->name
== NULL
&& name
== NULL
)
2992 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2997 /* Lookup BGP instance based on VRF id. */
2998 /* Note: Only to be used for incoming messages from Zebra. */
2999 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3003 /* Lookup VRF (in tree) and follow link. */
3004 vrf
= vrf_lookup_by_id(vrf_id
);
3007 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3010 /* handle socket creation or deletion, if necessary
3011 * this is called for all new BGP instances
3013 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3018 /* Create BGP server socket, if listen mode not disabled */
3019 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3021 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3023 * suppress vrf socket
3025 if (create
== FALSE
) {
3026 bgp_close_vrf_socket(bgp
);
3030 return BGP_ERR_INVALID_VALUE
;
3032 * if vrf_id did not change
3034 if (vrf
->vrf_id
== old_vrf_id
)
3036 if (old_vrf_id
!= VRF_UNKNOWN
) {
3037 /* look for old socket. close it. */
3038 bgp_close_vrf_socket(bgp
);
3040 /* if backend is not yet identified ( VRF_UNKNOWN) then
3041 * creation will be done later
3043 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3045 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3047 return BGP_ERR_INVALID_VALUE
;
3050 return bgp_check_main_socket(create
, bgp
);
3053 /* Called from VTY commands. */
3054 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3055 enum bgp_instance_type inst_type
)
3058 struct vrf
*vrf
= NULL
;
3060 /* Multiple instance check. */
3061 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3063 bgp
= bgp_lookup_by_name(name
);
3065 bgp
= bgp_get_default();
3067 /* Already exists. */
3069 if (bgp
->as
!= *as
) {
3071 return BGP_ERR_INSTANCE_MISMATCH
;
3073 if (bgp
->inst_type
!= inst_type
)
3074 return BGP_ERR_INSTANCE_MISMATCH
;
3079 /* BGP instance name can not be specified for single instance.
3082 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3084 /* Get default BGP structure if exists. */
3085 bgp
= bgp_get_default();
3088 if (bgp
->as
!= *as
) {
3090 return BGP_ERR_AS_MISMATCH
;
3097 bgp
= bgp_create(as
, name
, inst_type
);
3098 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3099 bgp_address_init(bgp
);
3100 bgp_tip_hash_init(bgp
);
3104 bgp
->t_rmap_def_originate_eval
= NULL
;
3106 /* If Default instance or VRF, link to the VRF structure, if present. */
3107 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3108 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3109 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3111 bgp_vrf_link(bgp
, vrf
);
3113 /* BGP server socket already processed if BGP instance
3114 * already part of the list
3116 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3117 listnode_add(bm
->bgp
, bgp
);
3119 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3120 if (BGP_DEBUG(zebra
, ZEBRA
))
3121 zlog_debug("%s: Registering BGP instance %s to zebra",
3122 __PRETTY_FUNCTION__
, name
);
3123 bgp_zebra_instance_register(bgp
);
3130 * Make BGP instance "up". Applies only to VRFs (non-default) and
3131 * implies the VRF has been learnt from Zebra.
3133 void bgp_instance_up(struct bgp
*bgp
)
3136 struct listnode
*node
, *next
;
3138 /* Register with zebra. */
3139 bgp_zebra_instance_register(bgp
);
3141 /* Kick off any peers that may have been configured. */
3142 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3143 if (!BGP_PEER_START_SUPPRESSED(peer
))
3144 BGP_EVENT_ADD(peer
, BGP_Start
);
3147 /* Process any networks that have been configured. */
3148 bgp_static_add(bgp
);
3152 * Make BGP instance "down". Applies only to VRFs (non-default) and
3153 * implies the VRF has been deleted by Zebra.
3155 void bgp_instance_down(struct bgp
*bgp
)
3158 struct listnode
*node
;
3159 struct listnode
*next
;
3162 if (bgp
->t_rmap_def_originate_eval
) {
3163 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3164 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3168 /* Bring down peers, so corresponding routes are purged. */
3169 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3170 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3171 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3172 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3174 bgp_session_reset(peer
);
3177 /* Purge network and redistributed routes. */
3178 bgp_purge_static_redist_routes(bgp
);
3180 /* Cleanup registered nexthops (flags) */
3181 bgp_cleanup_nexthops(bgp
);
3184 /* Delete BGP instance. */
3185 int bgp_delete(struct bgp
*bgp
)
3188 struct peer_group
*group
;
3189 struct listnode
*node
, *next
;
3195 THREAD_OFF(bgp
->t_startup
);
3196 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3197 THREAD_OFF(bgp
->t_update_delay
);
3198 THREAD_OFF(bgp
->t_establish_wait
);
3200 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3201 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3202 zlog_debug("Deleting Default VRF");
3204 zlog_debug("Deleting %s %s",
3205 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3211 /* unmap from RT list */
3212 bgp_evpn_vrf_delete(bgp
);
3215 if (bgp
->t_rmap_def_originate_eval
) {
3216 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3217 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3221 /* Inform peers we're going down. */
3222 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3223 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3224 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3225 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3228 /* Delete static routes (networks). */
3229 bgp_static_delete(bgp
);
3231 /* Unset redistribution. */
3232 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3233 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3234 if (i
!= ZEBRA_ROUTE_BGP
)
3235 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3237 /* Free peers and peer-groups. */
3238 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3239 peer_group_delete(group
);
3241 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3244 if (bgp
->peer_self
) {
3245 peer_delete(bgp
->peer_self
);
3246 bgp
->peer_self
= NULL
;
3249 update_bgp_group_free(bgp
);
3251 /* TODO - Other memory may need to be freed - e.g., NHT */
3256 bgp_cleanup_routes(bgp
);
3258 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3259 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3262 &bgp
->vpn_policy
[afi
]
3263 .import_redirect_rtlist
);
3264 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3267 /* Deregister from Zebra, if needed */
3268 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3269 if (BGP_DEBUG(zebra
, ZEBRA
))
3270 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3271 __PRETTY_FUNCTION__
, bgp
->name
);
3272 bgp_zebra_instance_deregister(bgp
);
3275 /* Remove visibility via the master list - there may however still be
3276 * routes to be processed still referencing the struct bgp.
3278 listnode_delete(bm
->bgp
, bgp
);
3280 /* Free interfaces in this instance. */
3283 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3284 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3286 bgp_vrf_unlink(bgp
, vrf
);
3288 thread_master_free_unused(bm
->master
);
3289 bgp_unlock(bgp
); /* initial reference */
3294 void bgp_free(struct bgp
*bgp
)
3298 struct bgp_table
*table
;
3299 struct bgp_node
*rn
;
3300 struct bgp_rmap
*rmap
;
3304 list_delete(&bgp
->group
);
3305 list_delete(&bgp
->peer
);
3307 if (bgp
->peerhash
) {
3308 hash_free(bgp
->peerhash
);
3309 bgp
->peerhash
= NULL
;
3312 FOREACH_AFI_SAFI (afi
, safi
) {
3313 /* Special handling for 2-level routing tables. */
3314 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3315 || safi
== SAFI_EVPN
) {
3316 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3317 rn
= bgp_route_next(rn
)) {
3318 table
= (struct bgp_table
*)rn
->info
;
3319 bgp_table_finish(&table
);
3322 if (bgp
->route
[afi
][safi
])
3323 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3324 if (bgp
->aggregate
[afi
][safi
])
3325 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3326 if (bgp
->rib
[afi
][safi
])
3327 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3328 rmap
= &bgp
->table_map
[afi
][safi
];
3330 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3333 bgp_scan_finish(bgp
);
3334 bgp_address_destroy(bgp
);
3335 bgp_tip_hash_destroy(bgp
);
3337 /* release the auto RD id */
3338 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3340 bgp_evpn_cleanup(bgp
);
3341 bgp_pbr_cleanup(bgp
);
3343 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3344 vpn_policy_direction_t dir
;
3346 if (bgp
->vpn_policy
[afi
].import_vrf
)
3347 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3348 if (bgp
->vpn_policy
[afi
].export_vrf
)
3349 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3351 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3352 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3353 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3354 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3355 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3356 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3360 XFREE(MTYPE_BGP
, bgp
->name
);
3361 if (bgp
->name_pretty
)
3362 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3364 XFREE(MTYPE_BGP
, bgp
);
3367 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3370 struct listnode
*node
, *nnode
;
3376 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3377 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3378 && !CHECK_FLAG(peer
->sflags
,
3379 PEER_STATUS_ACCEPT_PEER
))
3381 } else if (bm
->bgp
!= NULL
) {
3382 struct listnode
*bgpnode
, *nbgpnode
;
3384 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3385 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3387 && !strcmp(peer
->conf_if
, conf_if
)
3388 && !CHECK_FLAG(peer
->sflags
,
3389 PEER_STATUS_ACCEPT_PEER
))
3395 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3398 struct listnode
*node
, *nnode
;
3404 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3405 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3406 && !CHECK_FLAG(peer
->sflags
,
3407 PEER_STATUS_ACCEPT_PEER
))
3409 } else if (bm
->bgp
!= NULL
) {
3410 struct listnode
*bgpnode
, *nbgpnode
;
3412 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3413 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3415 && !strcmp(peer
->hostname
, hostname
)
3416 && !CHECK_FLAG(peer
->sflags
,
3417 PEER_STATUS_ACCEPT_PEER
))
3423 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3425 struct peer
*peer
= NULL
;
3426 struct peer tmp_peer
;
3428 memset(&tmp_peer
, 0, sizeof(struct peer
));
3431 * We do not want to find the doppelganger peer so search for the peer
3433 * the hash that has PEER_FLAG_CONFIG_NODE
3435 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3440 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3441 } else if (bm
->bgp
!= NULL
) {
3442 struct listnode
*bgpnode
, *nbgpnode
;
3444 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3445 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3454 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3455 union sockunion
*su
,
3456 struct peer_group
*group
)
3462 /* Create peer first; we've already checked group config is valid. */
3463 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3464 group
->conf
->as_type
, 0, 0, group
);
3469 peer
= peer_lock(peer
);
3470 listnode_add(group
->peer
, peer
);
3472 peer_group2peer_config_copy(group
, peer
);
3475 * Bind peer for all AFs configured for the group. We don't call
3476 * peer_group_bind as that is sub-optimal and does some stuff we don't
3479 FOREACH_AFI_SAFI (afi
, safi
) {
3480 if (!group
->conf
->afc
[afi
][safi
])
3482 peer
->afc
[afi
][safi
] = 1;
3484 if (!peer_af_find(peer
, afi
, safi
))
3485 peer_af_create(peer
, afi
, safi
);
3487 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3490 /* Mark as dynamic, but also as a "config node" for other things to
3492 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3493 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3499 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3500 struct prefix
*prefix
)
3502 struct listnode
*node
, *nnode
;
3503 struct prefix
*range
;
3506 afi
= family2afi(prefix
->family
);
3508 if (group
->listen_range
[afi
])
3509 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3511 if (prefix_match(range
, prefix
))
3518 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3519 struct prefix
**listen_range
)
3521 struct prefix
*range
= NULL
;
3522 struct peer_group
*group
= NULL
;
3523 struct listnode
*node
, *nnode
;
3525 *listen_range
= NULL
;
3527 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3528 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3531 } else if (bm
->bgp
!= NULL
) {
3532 struct listnode
*bgpnode
, *nbgpnode
;
3534 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3535 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3536 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3542 *listen_range
= range
;
3543 return (group
&& range
) ? group
: NULL
;
3546 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3548 struct peer_group
*group
;
3551 struct prefix prefix
;
3552 struct prefix
*listen_range
;
3554 char buf
[PREFIX2STR_BUFFER
];
3555 char buf1
[PREFIX2STR_BUFFER
];
3557 sockunion2hostprefix(su
, &prefix
);
3559 /* See if incoming connection matches a configured listen range. */
3560 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3571 prefix2str(&prefix
, buf
, sizeof(buf
));
3572 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3574 if (bgp_debug_neighbor_events(NULL
))
3576 "Dynamic Neighbor %s matches group %s listen range %s",
3577 buf
, group
->name
, buf1
);
3579 /* Are we within the listen limit? */
3580 dncount
= gbgp
->dynamic_neighbors_count
;
3582 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3583 if (bgp_debug_neighbor_events(NULL
))
3584 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3585 inet_sutop(su
, buf
),
3586 gbgp
->dynamic_neighbors_limit
);
3590 /* Ensure group is not disabled. */
3591 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3592 if (bgp_debug_neighbor_events(NULL
))
3594 "Dynamic Neighbor %s rejected - group %s disabled",
3599 /* Check that at least one AF is activated for the group. */
3600 if (!peer_group_af_configured(group
)) {
3601 if (bgp_debug_neighbor_events(NULL
))
3603 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3608 /* Create dynamic peer and bind to associated group. */
3609 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3612 gbgp
->dynamic_neighbors_count
= ++dncount
;
3614 if (bgp_debug_neighbor_events(peer
))
3615 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3616 peer
->host
, group
->name
, dncount
);
3621 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3624 if (peer
->group
->bgp
) {
3625 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3627 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3629 if (bgp_debug_neighbor_events(peer
))
3630 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3631 peer
->group
->name
, dncount
);
3634 /* If peer is configured at least one address family return 1. */
3635 int peer_active(struct peer
*peer
)
3637 if (BGP_PEER_SU_UNSPEC(peer
))
3639 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3640 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3641 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3642 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3643 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3644 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3645 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3646 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3647 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3648 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3649 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3654 /* If peer is negotiated at least one address family return 1. */
3655 int peer_active_nego(struct peer
*peer
)
3657 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3658 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3659 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3660 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3661 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3662 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3663 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3664 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3665 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3666 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3667 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3668 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3669 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3674 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3675 enum peer_change_type type
)
3677 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3680 if (peer
->status
!= Established
)
3683 if (type
== peer_change_reset
) {
3684 /* If we're resetting session, we've to delete both peer struct
3686 if ((peer
->doppelganger
)
3687 && (peer
->doppelganger
->status
!= Deleted
)
3688 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3689 PEER_FLAG_CONFIG_NODE
)))
3690 peer_delete(peer
->doppelganger
);
3692 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3693 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3694 } else if (type
== peer_change_reset_in
) {
3695 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3696 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3697 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3699 if ((peer
->doppelganger
)
3700 && (peer
->doppelganger
->status
!= Deleted
)
3701 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3702 PEER_FLAG_CONFIG_NODE
)))
3703 peer_delete(peer
->doppelganger
);
3705 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3706 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3708 } else if (type
== peer_change_reset_out
) {
3709 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3710 bgp_announce_route(peer
, afi
, safi
);
3714 struct peer_flag_action
{
3718 /* This flag can be set for peer-group member. */
3719 uint8_t not_for_member
;
3721 /* Action when the flag is changed. */
3722 enum peer_change_type type
;
3725 static const struct peer_flag_action peer_flag_action_list
[] = {
3726 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3727 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3728 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3729 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3730 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3731 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3732 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3733 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3734 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3735 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3736 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3737 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3738 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3739 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3740 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3741 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3742 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3745 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3746 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3747 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3748 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3749 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3750 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3751 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3752 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3753 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3754 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3755 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3756 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3757 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3758 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3759 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3760 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3761 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3762 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3763 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3764 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3765 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3766 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3767 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3768 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3769 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3770 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3773 /* Proper action set. */
3774 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3775 int size
, struct peer_flag_action
*action
,
3782 const struct peer_flag_action
*match
= NULL
;
3784 /* Check peer's frag action. */
3785 for (i
= 0; i
< size
; i
++) {
3786 match
= &action_list
[i
];
3788 if (match
->flag
== 0)
3791 if (match
->flag
& flag
) {
3794 if (match
->type
== peer_change_reset_in
)
3796 if (match
->type
== peer_change_reset_out
)
3798 if (match
->type
== peer_change_reset
) {
3802 if (match
->not_for_member
)
3803 action
->not_for_member
= 1;
3807 /* Set peer clear type. */
3808 if (reset_in
&& reset_out
)
3809 action
->type
= peer_change_reset
;
3811 action
->type
= peer_change_reset_in
;
3813 action
->type
= peer_change_reset_out
;
3815 action
->type
= peer_change_none
;
3820 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3822 if (flag
== PEER_FLAG_SHUTDOWN
) {
3823 if (CHECK_FLAG(peer
->flags
, flag
)) {
3824 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3825 peer_nsf_stop(peer
);
3827 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3828 if (peer
->t_pmax_restart
) {
3829 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3830 if (bgp_debug_neighbor_events(peer
))
3832 "%s Maximum-prefix restart timer canceled",
3836 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3837 peer_nsf_stop(peer
);
3839 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3840 char *msg
= peer
->tx_shutdown_message
;
3843 if (!msg
&& peer_group_active(peer
))
3844 msg
= peer
->group
->conf
3845 ->tx_shutdown_message
;
3846 msglen
= msg
? strlen(msg
) : 0;
3851 uint8_t msgbuf
[129];
3854 memcpy(msgbuf
+ 1, msg
, msglen
);
3856 bgp_notify_send_with_data(
3857 peer
, BGP_NOTIFY_CEASE
,
3858 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3859 msgbuf
, msglen
+ 1);
3862 peer
, BGP_NOTIFY_CEASE
,
3863 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3865 bgp_session_reset(peer
);
3867 peer
->v_start
= BGP_INIT_START_TIMER
;
3868 BGP_EVENT_ADD(peer
, BGP_Stop
);
3870 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3871 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3872 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3873 else if (flag
== PEER_FLAG_PASSIVE
)
3874 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3875 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3876 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3878 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3879 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3881 bgp_session_reset(peer
);
3884 /* Change specified peer flag. */
3885 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3889 bool invert
, member_invert
;
3890 struct peer
*member
;
3891 struct listnode
*node
, *nnode
;
3892 struct peer_flag_action action
;
3894 memset(&action
, 0, sizeof(struct peer_flag_action
));
3895 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3897 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3898 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3901 /* Abort if no flag action exists. */
3903 return BGP_ERR_INVALID_FLAG
;
3905 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3906 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3907 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3908 return BGP_ERR_PEER_FLAG_CONFLICT
;
3910 /* Handle flag updates where desired state matches current state. */
3911 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3912 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3913 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3917 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3918 COND_FLAG(peer
->flags_override
, flag
, invert
);
3923 /* Inherit from peer-group or set/unset flags accordingly. */
3924 if (peer_group_active(peer
) && set
== invert
)
3925 peer_flag_inherit(peer
, flag
);
3927 COND_FLAG(peer
->flags
, flag
, set
);
3929 /* Check if handling a regular peer. */
3930 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3931 /* Update flag override state accordingly. */
3932 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3934 /* Execute flag action on peer. */
3935 if (action
.type
== peer_change_reset
)
3936 peer_flag_modify_action(peer
, flag
);
3938 /* Skip peer-group mechanics for regular peers. */
3943 * Update peer-group members, unless they are explicitely overriding
3944 * peer-group configuration.
3946 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
3947 /* Skip peers with overridden configuration. */
3948 if (CHECK_FLAG(member
->flags_override
, flag
))
3951 /* Check if only member without group is inverted. */
3953 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
3955 /* Skip peers with equivalent configuration. */
3956 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
3959 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
3962 /* Update flag on peer-group member. */
3963 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
3965 /* Execute flag action on peer-group member. */
3966 if (action
.type
== peer_change_reset
)
3967 peer_flag_modify_action(member
, flag
);
3973 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3975 return peer_flag_modify(peer
, flag
, 1);
3978 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
3980 return peer_flag_modify(peer
, flag
, 0);
3983 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3984 uint32_t flag
, bool set
)
3988 bool invert
, member_invert
;
3989 struct peer
*member
;
3990 struct listnode
*node
, *nnode
;
3991 struct peer_flag_action action
;
3993 memset(&action
, 0, sizeof(struct peer_flag_action
));
3994 size
= sizeof peer_af_flag_action_list
3995 / sizeof(struct peer_flag_action
);
3997 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
3998 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4001 /* Abort if flag action exists. */
4003 return BGP_ERR_INVALID_FLAG
;
4005 /* Special check for reflector client. */
4006 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4007 && peer_sort(peer
) != BGP_PEER_IBGP
)
4008 return BGP_ERR_NOT_INTERNAL_PEER
;
4010 /* Special check for remove-private-AS. */
4011 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4012 && peer_sort(peer
) == BGP_PEER_IBGP
)
4013 return BGP_ERR_REMOVE_PRIVATE_AS
;
4015 /* as-override is not allowed for IBGP peers */
4016 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4017 return BGP_ERR_AS_OVERRIDE
;
4019 /* Handle flag updates where desired state matches current state. */
4020 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4021 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4022 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4027 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4028 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4035 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4036 * if we are setting/unsetting flags which conflict with this flag
4037 * handle accordingly
4039 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4043 * if we are setting NEXTHOP_SELF, we need to unset the
4044 * NEXTHOP_UNCHANGED flag
4046 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4047 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4048 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4049 PEER_FLAG_NEXTHOP_UNCHANGED
);
4053 * if we are unsetting NEXTHOP_SELF, we need to set the
4054 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4056 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4057 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4058 SET_FLAG(peer
->af_flags
[afi
][safi
],
4059 PEER_FLAG_NEXTHOP_UNCHANGED
);
4063 /* Inherit from peer-group or set/unset flags accordingly. */
4064 if (peer_group_active(peer
) && set
== invert
)
4065 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4067 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4069 /* Execute action when peer is established. */
4070 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4071 && peer
->status
== Established
) {
4072 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4073 bgp_clear_adj_in(peer
, afi
, safi
);
4075 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4076 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4077 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4078 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4079 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4080 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4081 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4082 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4084 peer_change_action(peer
, afi
, safi
, action
.type
);
4088 /* Check if handling a regular peer. */
4089 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4090 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4094 * Update peer-group members, unless they are explicitely
4095 * overriding peer-group configuration.
4097 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4099 /* Skip peers with overridden configuration. */
4100 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4104 /* Check if only member without group is inverted. */
4106 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4110 /* Skip peers with equivalent configuration. */
4111 if (set
!= member_invert
4112 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4115 if (set
== member_invert
4116 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4119 /* Update flag on peer-group member. */
4120 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4121 set
!= member_invert
);
4123 /* Execute flag action on peer-group member. */
4124 if (member
->status
== Established
) {
4125 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4126 bgp_clear_adj_in(member
, afi
, safi
);
4128 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4129 member
->last_reset
=
4130 PEER_DOWN_RR_CLIENT_CHANGE
;
4132 == PEER_FLAG_RSERVER_CLIENT
)
4133 member
->last_reset
=
4134 PEER_DOWN_RS_CLIENT_CHANGE
;
4136 == PEER_FLAG_ORF_PREFIX_SM
)
4137 member
->last_reset
=
4138 PEER_DOWN_CAPABILITY_CHANGE
;
4140 == PEER_FLAG_ORF_PREFIX_RM
)
4141 member
->last_reset
=
4142 PEER_DOWN_CAPABILITY_CHANGE
;
4144 peer_change_action(member
, afi
, safi
,
4154 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4156 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4159 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4161 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4165 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4167 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4168 peer
->tx_shutdown_message
=
4169 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4173 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4175 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4180 /* EBGP multihop configuration. */
4181 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4183 struct peer_group
*group
;
4184 struct listnode
*node
, *nnode
;
4187 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4190 /* see comment in peer_ttl_security_hops_set() */
4191 if (ttl
!= MAXTTL
) {
4192 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4193 group
= peer
->group
;
4194 if (group
->conf
->gtsm_hops
!= 0)
4195 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4197 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4199 if (peer1
->sort
== BGP_PEER_IBGP
)
4202 if (peer1
->gtsm_hops
!= 0)
4203 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4206 if (peer
->gtsm_hops
!= 0)
4207 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4213 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4214 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4215 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4216 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4217 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4219 bgp_session_reset(peer
);
4222 group
= peer
->group
;
4223 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4224 if (peer
->sort
== BGP_PEER_IBGP
)
4227 peer
->ttl
= group
->conf
->ttl
;
4229 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4230 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4231 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4233 bgp_session_reset(peer
);
4239 int peer_ebgp_multihop_unset(struct peer
*peer
)
4241 struct peer_group
*group
;
4242 struct listnode
*node
, *nnode
;
4244 if (peer
->sort
== BGP_PEER_IBGP
)
4247 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4248 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4250 if (peer_group_active(peer
))
4251 peer
->ttl
= peer
->group
->conf
->ttl
;
4255 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4256 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4257 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4258 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4260 bgp_session_reset(peer
);
4262 group
= peer
->group
;
4263 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4264 if (peer
->sort
== BGP_PEER_IBGP
)
4269 if (peer
->fd
>= 0) {
4270 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4272 peer
, BGP_NOTIFY_CEASE
,
4273 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4275 bgp_session_reset(peer
);
4282 /* Neighbor description. */
4283 int peer_description_set(struct peer
*peer
, const char *desc
)
4286 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4288 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4293 int peer_description_unset(struct peer
*peer
)
4296 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4303 /* Neighbor update-source. */
4304 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4306 struct peer
*member
;
4307 struct listnode
*node
, *nnode
;
4309 /* Set flag and configuration on peer. */
4310 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4311 if (peer
->update_if
) {
4312 if (strcmp(peer
->update_if
, ifname
) == 0)
4314 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4316 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4317 sockunion_free(peer
->update_source
);
4318 peer
->update_source
= NULL
;
4320 /* Check if handling a regular peer. */
4321 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4322 /* Send notification or reset peer depending on state. */
4323 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4324 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4325 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4326 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4328 bgp_session_reset(peer
);
4330 /* Skip peer-group mechanics for regular peers. */
4335 * Set flag and configuration on all peer-group members, unless they are
4336 * explicitely overriding peer-group configuration.
4338 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4339 /* Skip peers with overridden configuration. */
4340 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4343 /* Skip peers with the same configuration. */
4344 if (member
->update_if
) {
4345 if (strcmp(member
->update_if
, ifname
) == 0)
4347 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4350 /* Set flag and configuration on peer-group member. */
4351 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4352 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4353 sockunion_free(member
->update_source
);
4354 member
->update_source
= NULL
;
4356 /* Send notification or reset peer depending on state. */
4357 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4358 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4359 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4360 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4362 bgp_session_reset(member
);
4368 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4370 struct peer
*member
;
4371 struct listnode
*node
, *nnode
;
4373 /* Set flag and configuration on peer. */
4374 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4375 if (peer
->update_source
) {
4376 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4378 sockunion_free(peer
->update_source
);
4380 peer
->update_source
= sockunion_dup(su
);
4381 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4383 /* Check if handling a regular peer. */
4384 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4385 /* Send notification or reset peer depending on state. */
4386 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4387 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4388 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4389 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4391 bgp_session_reset(peer
);
4393 /* Skip peer-group mechanics for regular peers. */
4398 * Set flag and configuration on all peer-group members, unless they are
4399 * explicitely overriding peer-group configuration.
4401 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4402 /* Skip peers with overridden configuration. */
4403 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4406 /* Skip peers with the same configuration. */
4407 if (member
->update_source
) {
4408 if (sockunion_cmp(member
->update_source
, su
) == 0)
4410 sockunion_free(member
->update_source
);
4413 /* Set flag and configuration on peer-group member. */
4414 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4415 member
->update_source
= sockunion_dup(su
);
4416 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4418 /* Send notification or reset peer depending on state. */
4419 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4420 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4421 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4422 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4424 bgp_session_reset(member
);
4430 int peer_update_source_unset(struct peer
*peer
)
4432 struct peer
*member
;
4433 struct listnode
*node
, *nnode
;
4435 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4438 /* Inherit configuration from peer-group if peer is member. */
4439 if (peer_group_active(peer
)) {
4440 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4441 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4442 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4443 MTYPE_PEER_UPDATE_SOURCE
);
4445 /* Otherwise remove flag and configuration from peer. */
4446 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4447 sockunion_free(peer
->update_source
);
4448 peer
->update_source
= NULL
;
4449 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4452 /* Check if handling a regular peer. */
4453 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4454 /* Send notification or reset peer depending on state. */
4455 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4456 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4457 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4458 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4460 bgp_session_reset(peer
);
4462 /* Skip peer-group mechanics for regular peers. */
4467 * Set flag and configuration on all peer-group members, unless they are
4468 * explicitely overriding peer-group configuration.
4470 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4471 /* Skip peers with overridden configuration. */
4472 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4475 /* Skip peers with the same configuration. */
4476 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4477 && !member
->update_source
&& !member
->update_if
)
4480 /* Remove flag and configuration on peer-group member. */
4481 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4482 sockunion_free(member
->update_source
);
4483 member
->update_source
= NULL
;
4484 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4486 /* Send notification or reset peer depending on state. */
4487 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4488 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4489 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4490 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4492 bgp_session_reset(member
);
4498 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4499 const char *rmap
, struct route_map
*route_map
)
4501 struct peer
*member
;
4502 struct listnode
*node
, *nnode
;
4504 /* Set flag and configuration on peer. */
4505 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4507 if (!peer
->default_rmap
[afi
][safi
].name
4508 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4509 if (peer
->default_rmap
[afi
][safi
].name
)
4510 XFREE(MTYPE_ROUTE_MAP_NAME
,
4511 peer
->default_rmap
[afi
][safi
].name
);
4513 peer
->default_rmap
[afi
][safi
].name
=
4514 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4515 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4518 if (peer
->default_rmap
[afi
][safi
].name
)
4519 XFREE(MTYPE_ROUTE_MAP_NAME
,
4520 peer
->default_rmap
[afi
][safi
].name
);
4522 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4523 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4526 /* Check if handling a regular peer. */
4527 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4528 /* Update peer route announcements. */
4529 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4530 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4531 bgp_default_originate(peer
, afi
, safi
, 0);
4532 bgp_announce_route(peer
, afi
, safi
);
4535 /* Skip peer-group mechanics for regular peers. */
4540 * Set flag and configuration on all peer-group members, unless they are
4541 * explicitely overriding peer-group configuration.
4543 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4544 /* Skip peers with overridden configuration. */
4545 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4546 PEER_FLAG_DEFAULT_ORIGINATE
))
4549 /* Set flag and configuration on peer-group member. */
4550 SET_FLAG(member
->af_flags
[afi
][safi
],
4551 PEER_FLAG_DEFAULT_ORIGINATE
);
4553 if (member
->default_rmap
[afi
][safi
].name
)
4554 XFREE(MTYPE_ROUTE_MAP_NAME
,
4555 member
->default_rmap
[afi
][safi
].name
);
4557 member
->default_rmap
[afi
][safi
].name
=
4558 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4559 member
->default_rmap
[afi
][safi
].map
= route_map
;
4562 /* Update peer route announcements. */
4563 if (member
->status
== Established
4564 && member
->afc_nego
[afi
][safi
]) {
4565 update_group_adjust_peer(
4566 peer_af_find(member
, afi
, safi
));
4567 bgp_default_originate(member
, afi
, safi
, 0);
4568 bgp_announce_route(member
, afi
, safi
);
4575 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4577 struct peer
*member
;
4578 struct listnode
*node
, *nnode
;
4580 /* Inherit configuration from peer-group if peer is member. */
4581 if (peer_group_active(peer
)) {
4582 peer_af_flag_inherit(peer
, afi
, safi
,
4583 PEER_FLAG_DEFAULT_ORIGINATE
);
4584 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4585 default_rmap
[afi
][safi
].name
,
4586 MTYPE_ROUTE_MAP_NAME
);
4587 PEER_ATTR_INHERIT(peer
, peer
->group
,
4588 default_rmap
[afi
][safi
].map
);
4590 /* Otherwise remove flag and configuration from peer. */
4591 peer_af_flag_unset(peer
, afi
, safi
,
4592 PEER_FLAG_DEFAULT_ORIGINATE
);
4593 if (peer
->default_rmap
[afi
][safi
].name
)
4594 XFREE(MTYPE_ROUTE_MAP_NAME
,
4595 peer
->default_rmap
[afi
][safi
].name
);
4596 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4597 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4600 /* Check if handling a regular peer. */
4601 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4602 /* Update peer route announcements. */
4603 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4604 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4605 bgp_default_originate(peer
, afi
, safi
, 1);
4606 bgp_announce_route(peer
, afi
, safi
);
4609 /* Skip peer-group mechanics for regular peers. */
4614 * Remove flag and configuration from all peer-group members, unless
4615 * they are explicitely overriding peer-group configuration.
4617 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4618 /* Skip peers with overridden configuration. */
4619 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4620 PEER_FLAG_DEFAULT_ORIGINATE
))
4623 /* Remove flag and configuration on peer-group member. */
4624 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4625 PEER_FLAG_DEFAULT_ORIGINATE
);
4626 if (peer
->default_rmap
[afi
][safi
].name
)
4627 XFREE(MTYPE_ROUTE_MAP_NAME
,
4628 peer
->default_rmap
[afi
][safi
].name
);
4629 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4630 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4632 /* Update peer route announcements. */
4633 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4634 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4635 bgp_default_originate(peer
, afi
, safi
, 1);
4636 bgp_announce_route(peer
, afi
, safi
);
4643 int peer_port_set(struct peer
*peer
, uint16_t port
)
4649 int peer_port_unset(struct peer
*peer
)
4651 peer
->port
= BGP_PORT_DEFAULT
;
4656 * Helper function that is called after the name of the policy
4657 * being used by a peer has changed (AF specific). Automatically
4658 * initiates inbound or outbound processing as needed.
4660 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4664 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4665 if (peer
->status
== Established
)
4666 bgp_announce_route(peer
, afi
, safi
);
4668 if (peer
->status
!= Established
)
4671 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4672 PEER_FLAG_SOFT_RECONFIG
))
4673 bgp_soft_reconfig_in(peer
, afi
, safi
);
4674 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4675 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4676 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4681 /* neighbor weight. */
4682 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4684 struct peer
*member
;
4685 struct listnode
*node
, *nnode
;
4687 /* Set flag and configuration on peer. */
4688 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4689 if (peer
->weight
[afi
][safi
] != weight
) {
4690 peer
->weight
[afi
][safi
] = weight
;
4691 peer_on_policy_change(peer
, afi
, safi
, 0);
4694 /* Skip peer-group mechanics for regular peers. */
4695 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4699 * Set flag and configuration on all peer-group members, unless they are
4700 * explicitely overriding peer-group configuration.
4702 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4703 /* Skip peers with overridden configuration. */
4704 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4708 /* Set flag and configuration on peer-group member. */
4709 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4710 if (member
->weight
[afi
][safi
] != weight
) {
4711 member
->weight
[afi
][safi
] = weight
;
4712 peer_on_policy_change(member
, afi
, safi
, 0);
4719 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4721 struct peer
*member
;
4722 struct listnode
*node
, *nnode
;
4724 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4727 /* Inherit configuration from peer-group if peer is member. */
4728 if (peer_group_active(peer
)) {
4729 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4730 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4732 peer_on_policy_change(peer
, afi
, safi
, 0);
4736 /* Remove flag and configuration from peer. */
4737 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4738 peer
->weight
[afi
][safi
] = 0;
4739 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 * Remove flag and configuration from all peer-group members, unless
4747 * they are 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 /* Skip peers where flag is already disabled. */
4756 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4759 /* Remove flag and configuration on peer-group member. */
4760 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4761 member
->weight
[afi
][safi
] = 0;
4762 peer_on_policy_change(member
, afi
, safi
, 0);
4768 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4770 struct peer
*member
;
4771 struct listnode
*node
, *nnode
;
4773 if (keepalive
> 65535)
4774 return BGP_ERR_INVALID_VALUE
;
4776 if (holdtime
> 65535)
4777 return BGP_ERR_INVALID_VALUE
;
4779 if (holdtime
< 3 && holdtime
!= 0)
4780 return BGP_ERR_INVALID_VALUE
;
4782 /* Set flag and configuration on peer. */
4783 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4784 peer
->holdtime
= holdtime
;
4785 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4787 /* Skip peer-group mechanics for regular peers. */
4788 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4792 * Set flag and configuration on all peer-group members, unless they are
4793 * explicitely overriding peer-group configuration.
4795 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4796 /* Skip peers with overridden configuration. */
4797 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4800 /* Set flag and configuration on peer-group member. */
4801 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4802 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4803 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4809 int peer_timers_unset(struct peer
*peer
)
4811 struct peer
*member
;
4812 struct listnode
*node
, *nnode
;
4814 /* Inherit configuration from peer-group if peer is member. */
4815 if (peer_group_active(peer
)) {
4816 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4817 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4818 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4820 /* Otherwise remove flag and configuration from peer. */
4821 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4823 peer
->keepalive
= 0;
4826 /* Skip peer-group mechanics for regular peers. */
4827 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4831 * Remove flag and configuration from all peer-group members, unless
4832 * they are explicitely overriding peer-group configuration.
4834 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4835 /* Skip peers with overridden configuration. */
4836 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4839 /* Remove flag and configuration on peer-group member. */
4840 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4841 member
->holdtime
= 0;
4842 member
->keepalive
= 0;
4848 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4850 struct peer
*member
;
4851 struct listnode
*node
, *nnode
;
4853 if (connect
> 65535)
4854 return BGP_ERR_INVALID_VALUE
;
4856 /* Set flag and configuration on peer. */
4857 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4858 peer
->connect
= connect
;
4859 peer
->v_connect
= connect
;
4861 /* Skip peer-group mechanics for regular peers. */
4862 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4866 * Set flag and configuration on all peer-group members, unless they are
4867 * explicitely overriding peer-group configuration.
4869 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4870 /* Skip peers with overridden configuration. */
4871 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4874 /* Set flag and configuration on peer-group member. */
4875 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4876 member
->connect
= connect
;
4877 member
->v_connect
= connect
;
4883 int peer_timers_connect_unset(struct peer
*peer
)
4885 struct peer
*member
;
4886 struct listnode
*node
, *nnode
;
4888 /* Inherit configuration from peer-group if peer is member. */
4889 if (peer_group_active(peer
)) {
4890 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4891 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4893 /* Otherwise remove flag and configuration from peer. */
4894 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4898 /* Set timer with fallback to default value. */
4900 peer
->v_connect
= peer
->connect
;
4902 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4904 /* Skip peer-group mechanics for regular peers. */
4905 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4909 * Remove flag and configuration from all peer-group members, unless
4910 * they are explicitely overriding peer-group configuration.
4912 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4913 /* Skip peers with overridden configuration. */
4914 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4917 /* Remove flag and configuration on peer-group member. */
4918 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4919 member
->connect
= 0;
4920 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4926 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4928 struct peer
*member
;
4929 struct listnode
*node
, *nnode
;
4932 return BGP_ERR_INVALID_VALUE
;
4934 /* Set flag and configuration on peer. */
4935 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
4936 peer
->routeadv
= routeadv
;
4937 peer
->v_routeadv
= routeadv
;
4939 /* Check if handling a regular peer. */
4940 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4941 /* Update peer route announcements. */
4942 update_group_adjust_peer_afs(peer
);
4943 if (peer
->status
== Established
)
4944 bgp_announce_route_all(peer
);
4946 /* Skip peer-group mechanics for regular peers. */
4951 * Set flag and configuration on all peer-group members, unless they are
4952 * explicitely overriding peer-group configuration.
4954 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4955 /* Skip peers with overridden configuration. */
4956 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
4959 /* Set flag and configuration on peer-group member. */
4960 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
4961 member
->routeadv
= routeadv
;
4962 member
->v_routeadv
= routeadv
;
4964 /* Update peer route announcements. */
4965 update_group_adjust_peer_afs(member
);
4966 if (member
->status
== Established
)
4967 bgp_announce_route_all(member
);
4973 int peer_advertise_interval_unset(struct peer
*peer
)
4975 struct peer
*member
;
4976 struct listnode
*node
, *nnode
;
4978 /* Inherit configuration from peer-group if peer is member. */
4979 if (peer_group_active(peer
)) {
4980 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
4981 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
4983 /* Otherwise remove flag and configuration from peer. */
4984 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
4988 /* Set timer with fallback to default value. */
4990 peer
->v_routeadv
= peer
->routeadv
;
4992 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
4993 ? BGP_DEFAULT_IBGP_ROUTEADV
4994 : BGP_DEFAULT_EBGP_ROUTEADV
;
4996 /* Check if handling a regular peer. */
4997 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4998 /* Update peer route announcements. */
4999 update_group_adjust_peer_afs(peer
);
5000 if (peer
->status
== Established
)
5001 bgp_announce_route_all(peer
);
5003 /* Skip peer-group mechanics for regular peers. */
5008 * Remove flag and configuration from all peer-group members, unless
5009 * they are explicitely overriding peer-group configuration.
5011 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5012 /* Skip peers with overridden configuration. */
5013 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5016 /* Remove flag and configuration on peer-group member. */
5017 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5018 member
->routeadv
= 0;
5019 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5020 ? BGP_DEFAULT_IBGP_ROUTEADV
5021 : BGP_DEFAULT_EBGP_ROUTEADV
;
5023 /* Update peer route announcements. */
5024 update_group_adjust_peer_afs(member
);
5025 if (member
->status
== Established
)
5026 bgp_announce_route_all(member
);
5032 /* neighbor interface */
5033 void peer_interface_set(struct peer
*peer
, const char *str
)
5036 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5037 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5040 void peer_interface_unset(struct peer
*peer
)
5043 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5044 peer
->ifname
= NULL
;
5048 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5049 int allow_num
, int origin
)
5051 struct peer
*member
;
5052 struct listnode
*node
, *nnode
;
5054 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5055 return BGP_ERR_INVALID_VALUE
;
5057 /* Set flag and configuration on peer. */
5058 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5060 if (peer
->allowas_in
[afi
][safi
] != 0
5061 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5062 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5063 peer_af_flag_set(peer
, afi
, safi
,
5064 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5065 peer
->allowas_in
[afi
][safi
] = 0;
5066 peer_on_policy_change(peer
, afi
, safi
, 0);
5069 if (peer
->allowas_in
[afi
][safi
] != allow_num
5070 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5071 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5073 peer_af_flag_unset(peer
, afi
, safi
,
5074 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5075 peer
->allowas_in
[afi
][safi
] = allow_num
;
5076 peer_on_policy_change(peer
, afi
, safi
, 0);
5080 /* Skip peer-group mechanics for regular peers. */
5081 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5085 * Set flag and configuration on all peer-group members, unless
5086 * they are explicitely overriding peer-group configuration.
5088 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5089 /* Skip peers with overridden configuration. */
5090 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5091 PEER_FLAG_ALLOWAS_IN
))
5094 /* Set flag and configuration on peer-group member. */
5095 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5097 if (member
->allowas_in
[afi
][safi
] != 0
5098 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5099 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5100 SET_FLAG(member
->af_flags
[afi
][safi
],
5101 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5102 member
->allowas_in
[afi
][safi
] = 0;
5103 peer_on_policy_change(peer
, afi
, safi
, 0);
5106 if (member
->allowas_in
[afi
][safi
] != allow_num
5107 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5108 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5109 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5110 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5111 member
->allowas_in
[afi
][safi
] = allow_num
;
5112 peer_on_policy_change(peer
, afi
, safi
, 0);
5120 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5122 struct peer
*member
;
5123 struct listnode
*node
, *nnode
;
5125 /* Skip peer if flag is already disabled. */
5126 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5129 /* Inherit configuration from peer-group if peer is member. */
5130 if (peer_group_active(peer
)) {
5131 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5132 peer_af_flag_inherit(peer
, afi
, safi
,
5133 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5134 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5135 peer_on_policy_change(peer
, afi
, safi
, 0);
5140 /* Remove flag and configuration from peer. */
5141 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5142 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5143 peer
->allowas_in
[afi
][safi
] = 0;
5144 peer_on_policy_change(peer
, afi
, safi
, 0);
5146 /* Skip peer-group mechanics if handling a regular peer. */
5147 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5151 * Remove flags and configuration from all peer-group members, unless
5152 * they are explicitely overriding peer-group configuration.
5154 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5155 /* Skip peers with overridden configuration. */
5156 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5157 PEER_FLAG_ALLOWAS_IN
))
5160 /* Skip peers where flag is already disabled. */
5161 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5162 PEER_FLAG_ALLOWAS_IN
))
5165 /* Remove flags and configuration on peer-group member. */
5166 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5167 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5168 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5169 member
->allowas_in
[afi
][safi
] = 0;
5170 peer_on_policy_change(member
, afi
, safi
, 0);
5176 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5179 bool old_no_prepend
, old_replace_as
;
5180 struct bgp
*bgp
= peer
->bgp
;
5181 struct peer
*member
;
5182 struct listnode
*node
, *nnode
;
5184 if (peer_sort(peer
) != BGP_PEER_EBGP
5185 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5186 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5189 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5192 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5194 /* Save previous flag states. */
5196 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5198 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5200 /* Set flag and configuration on peer. */
5201 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5202 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5203 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5205 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5206 && old_replace_as
== replace_as
)
5208 peer
->change_local_as
= as
;
5210 /* Check if handling a regular peer. */
5211 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5212 /* Send notification or reset peer depending on state. */
5213 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5214 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5215 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5216 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5218 bgp_session_reset(peer
);
5220 /* Skip peer-group mechanics for regular peers. */
5225 * Set flag and configuration on all peer-group members, unless they are
5226 * explicitely overriding peer-group configuration.
5228 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5229 /* Skip peers with overridden configuration. */
5230 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5233 /* Skip peers with the same configuration. */
5234 old_no_prepend
= CHECK_FLAG(member
->flags
,
5235 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5236 old_replace_as
= CHECK_FLAG(member
->flags
,
5237 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5238 if (member
->change_local_as
== as
5239 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5240 && old_no_prepend
== no_prepend
5241 && old_replace_as
== replace_as
)
5244 /* Set flag and configuration on peer-group member. */
5245 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5246 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5248 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5250 member
->change_local_as
= as
;
5252 /* Send notification or stop peer depending on state. */
5253 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5254 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5255 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5256 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5258 BGP_EVENT_ADD(member
, BGP_Stop
);
5264 int peer_local_as_unset(struct peer
*peer
)
5266 struct peer
*member
;
5267 struct listnode
*node
, *nnode
;
5269 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5272 /* Inherit configuration from peer-group if peer is member. */
5273 if (peer_group_active(peer
)) {
5274 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5275 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5276 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5277 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5279 /* Otherwise remove flag and configuration from peer. */
5280 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5281 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5282 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5283 peer
->change_local_as
= 0;
5286 /* Check if handling a regular peer. */
5287 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5288 /* Send notification or stop peer depending on state. */
5289 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5290 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5291 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5292 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5294 BGP_EVENT_ADD(peer
, BGP_Stop
);
5296 /* Skip peer-group mechanics for regular peers. */
5301 * Remove flag and configuration from all peer-group members, unless
5302 * they are explicitely overriding peer-group configuration.
5304 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5305 /* Skip peers with overridden configuration. */
5306 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5309 /* Remove flag and configuration on peer-group member. */
5310 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5311 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5312 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5313 member
->change_local_as
= 0;
5315 /* Send notification or stop peer depending on state. */
5316 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5317 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5318 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5319 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5321 bgp_session_reset(member
);
5327 /* Set password for authenticating with the peer. */
5328 int peer_password_set(struct peer
*peer
, const char *password
)
5330 struct peer
*member
;
5331 struct listnode
*node
, *nnode
;
5332 int len
= password
? strlen(password
) : 0;
5333 int ret
= BGP_SUCCESS
;
5335 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5336 return BGP_ERR_INVALID_VALUE
;
5338 /* Set flag and configuration on peer. */
5339 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5340 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5342 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5343 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5345 /* Check if handling a regular peer. */
5346 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5347 /* Send notification or reset peer depending on state. */
5348 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5349 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5350 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5352 bgp_session_reset(peer
);
5355 * Attempt to install password on socket and skip peer-group
5358 if (BGP_PEER_SU_UNSPEC(peer
))
5360 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5361 : BGP_ERR_TCPSIG_FAILED
;
5365 * Set flag and configuration on all peer-group members, unless they are
5366 * explicitely overriding peer-group configuration.
5368 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5369 /* Skip peers with overridden configuration. */
5370 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5373 /* Skip peers with the same password. */
5374 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5377 /* Set flag and configuration on peer-group member. */
5378 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5379 if (member
->password
)
5380 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5381 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5383 /* Send notification or reset peer depending on state. */
5384 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5385 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5386 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5388 bgp_session_reset(member
);
5390 /* Attempt to install password on socket. */
5391 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5392 ret
= BGP_ERR_TCPSIG_FAILED
;
5398 int peer_password_unset(struct peer
*peer
)
5400 struct peer
*member
;
5401 struct listnode
*node
, *nnode
;
5403 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5406 /* Inherit configuration from peer-group if peer is member. */
5407 if (peer_group_active(peer
)) {
5408 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5409 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5410 MTYPE_PEER_PASSWORD
);
5412 /* Otherwise remove flag and configuration from peer. */
5413 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5414 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5417 /* Check if handling a regular peer. */
5418 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5419 /* Send notification or reset peer depending on state. */
5420 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5421 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5422 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5424 bgp_session_reset(peer
);
5426 /* Attempt to uninstall password on socket. */
5427 if (!BGP_PEER_SU_UNSPEC(peer
))
5428 bgp_md5_unset(peer
);
5430 /* Skip peer-group mechanics for regular peers. */
5435 * Remove flag and configuration from all peer-group members, unless
5436 * they are explicitely overriding peer-group configuration.
5438 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5439 /* Skip peers with overridden configuration. */
5440 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5443 /* Remove flag and configuration on peer-group member. */
5444 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5445 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5447 /* Send notification or reset peer depending on state. */
5448 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5449 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5450 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5452 bgp_session_reset(member
);
5454 /* Attempt to uninstall password on socket. */
5455 if (!BGP_PEER_SU_UNSPEC(member
))
5456 bgp_md5_unset(member
);
5463 /* Set distribute list to the peer. */
5464 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5467 struct peer
*member
;
5468 struct bgp_filter
*filter
;
5469 struct listnode
*node
, *nnode
;
5471 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5472 return BGP_ERR_INVALID_VALUE
;
5474 /* Set configuration on peer. */
5475 filter
= &peer
->filter
[afi
][safi
];
5476 if (filter
->plist
[direct
].name
)
5477 return BGP_ERR_PEER_FILTER_CONFLICT
;
5478 if (filter
->dlist
[direct
].name
)
5479 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5480 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5481 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5483 /* Check if handling a regular peer. */
5484 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5485 /* Set override-flag and process peer route updates. */
5486 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5487 PEER_FT_DISTRIBUTE_LIST
);
5488 peer_on_policy_change(peer
, afi
, safi
,
5489 (direct
== FILTER_OUT
) ? 1 : 0);
5491 /* Skip peer-group mechanics for regular peers. */
5496 * Set configuration on all peer-group members, un less they are
5497 * explicitely overriding peer-group configuration.
5499 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5500 /* Skip peers with overridden configuration. */
5501 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5502 PEER_FT_DISTRIBUTE_LIST
))
5505 /* Set configuration on peer-group member. */
5506 filter
= &member
->filter
[afi
][safi
];
5507 if (filter
->dlist
[direct
].name
)
5508 XFREE(MTYPE_BGP_FILTER_NAME
,
5509 filter
->dlist
[direct
].name
);
5510 filter
->dlist
[direct
].name
=
5511 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5512 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5514 /* Process peer route updates. */
5515 peer_on_policy_change(member
, afi
, safi
,
5516 (direct
== FILTER_OUT
) ? 1 : 0);
5522 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5524 struct peer
*member
;
5525 struct bgp_filter
*filter
;
5526 struct listnode
*node
, *nnode
;
5528 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5529 return BGP_ERR_INVALID_VALUE
;
5531 /* Unset override-flag unconditionally. */
5532 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5533 PEER_FT_DISTRIBUTE_LIST
);
5535 /* Inherit configuration from peer-group if peer is member. */
5536 if (peer_group_active(peer
)) {
5537 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5538 filter
[afi
][safi
].dlist
[direct
].name
,
5539 MTYPE_BGP_FILTER_NAME
);
5540 PEER_ATTR_INHERIT(peer
, peer
->group
,
5541 filter
[afi
][safi
].dlist
[direct
].alist
);
5543 /* Otherwise remove configuration from peer. */
5544 filter
= &peer
->filter
[afi
][safi
];
5545 if (filter
->dlist
[direct
].name
)
5546 XFREE(MTYPE_BGP_FILTER_NAME
,
5547 filter
->dlist
[direct
].name
);
5548 filter
->dlist
[direct
].name
= NULL
;
5549 filter
->dlist
[direct
].alist
= NULL
;
5552 /* Check if handling a regular peer. */
5553 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5554 /* Process peer route updates. */
5555 peer_on_policy_change(peer
, afi
, safi
,
5556 (direct
== FILTER_OUT
) ? 1 : 0);
5558 /* Skip peer-group mechanics for regular peers. */
5563 * Remove configuration on all peer-group members, unless they are
5564 * explicitely overriding peer-group configuration.
5566 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5567 /* Skip peers with overridden configuration. */
5568 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5569 PEER_FT_DISTRIBUTE_LIST
))
5572 /* Remove configuration on peer-group member. */
5573 filter
= &member
->filter
[afi
][safi
];
5574 if (filter
->dlist
[direct
].name
)
5575 XFREE(MTYPE_BGP_FILTER_NAME
,
5576 filter
->dlist
[direct
].name
);
5577 filter
->dlist
[direct
].name
= NULL
;
5578 filter
->dlist
[direct
].alist
= NULL
;
5580 /* Process peer route updates. */
5581 peer_on_policy_change(member
, afi
, safi
,
5582 (direct
== FILTER_OUT
) ? 1 : 0);
5588 /* Update distribute list. */
5589 static void peer_distribute_update(struct access_list
*access
)
5594 struct listnode
*mnode
, *mnnode
;
5595 struct listnode
*node
, *nnode
;
5598 struct peer_group
*group
;
5599 struct bgp_filter
*filter
;
5601 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5603 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5604 access
->name
, 0, 0);
5605 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5606 FOREACH_AFI_SAFI (afi
, safi
) {
5607 filter
= &peer
->filter
[afi
][safi
];
5609 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5611 if (filter
->dlist
[direct
].name
)
5612 filter
->dlist
[direct
]
5613 .alist
= access_list_lookup(
5615 filter
->dlist
[direct
]
5618 filter
->dlist
[direct
].alist
=
5623 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5624 FOREACH_AFI_SAFI (afi
, safi
) {
5625 filter
= &group
->conf
->filter
[afi
][safi
];
5627 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5629 if (filter
->dlist
[direct
].name
)
5630 filter
->dlist
[direct
]
5631 .alist
= access_list_lookup(
5633 filter
->dlist
[direct
]
5636 filter
->dlist
[direct
].alist
=
5642 vnc_prefix_list_update(bgp
);
5647 /* Set prefix list to the peer. */
5648 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5651 struct peer
*member
;
5652 struct bgp_filter
*filter
;
5653 struct listnode
*node
, *nnode
;
5655 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5656 return BGP_ERR_INVALID_VALUE
;
5658 /* Set configuration on peer. */
5659 filter
= &peer
->filter
[afi
][safi
];
5660 if (filter
->dlist
[direct
].name
)
5661 return BGP_ERR_PEER_FILTER_CONFLICT
;
5662 if (filter
->plist
[direct
].name
)
5663 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5664 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5665 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5667 /* Check if handling a regular peer. */
5668 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5669 /* Set override-flag and process peer route updates. */
5670 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5671 PEER_FT_PREFIX_LIST
);
5672 peer_on_policy_change(peer
, afi
, safi
,
5673 (direct
== FILTER_OUT
) ? 1 : 0);
5675 /* Skip peer-group mechanics for regular peers. */
5680 * Set configuration on all peer-group members, unless they are
5681 * explicitely overriding peer-group configuration.
5683 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5684 /* Skip peers with overridden configuration. */
5685 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5686 PEER_FT_PREFIX_LIST
))
5689 /* Set configuration on peer-group member. */
5690 filter
= &member
->filter
[afi
][safi
];
5691 if (filter
->plist
[direct
].name
)
5692 XFREE(MTYPE_BGP_FILTER_NAME
,
5693 filter
->plist
[direct
].name
);
5694 filter
->plist
[direct
].name
=
5695 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5696 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5698 /* Process peer route updates. */
5699 peer_on_policy_change(member
, afi
, safi
,
5700 (direct
== FILTER_OUT
) ? 1 : 0);
5706 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5709 struct peer
*member
;
5710 struct bgp_filter
*filter
;
5711 struct listnode
*node
, *nnode
;
5713 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5714 return BGP_ERR_INVALID_VALUE
;
5716 /* Unset override-flag unconditionally. */
5717 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5718 PEER_FT_PREFIX_LIST
);
5720 /* Inherit configuration from peer-group if peer is member. */
5721 if (peer_group_active(peer
)) {
5722 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5723 filter
[afi
][safi
].plist
[direct
].name
,
5724 MTYPE_BGP_FILTER_NAME
);
5725 PEER_ATTR_INHERIT(peer
, peer
->group
,
5726 filter
[afi
][safi
].plist
[direct
].plist
);
5728 /* Otherwise remove configuration from peer. */
5729 filter
= &peer
->filter
[afi
][safi
];
5730 if (filter
->plist
[direct
].name
)
5731 XFREE(MTYPE_BGP_FILTER_NAME
,
5732 filter
->plist
[direct
].name
);
5733 filter
->plist
[direct
].name
= NULL
;
5734 filter
->plist
[direct
].plist
= NULL
;
5737 /* Check if handling a regular peer. */
5738 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5739 /* Process peer route updates. */
5740 peer_on_policy_change(peer
, afi
, safi
,
5741 (direct
== FILTER_OUT
) ? 1 : 0);
5743 /* Skip peer-group mechanics for regular peers. */
5748 * Remove configuration on all peer-group members, unless they are
5749 * explicitely overriding peer-group configuration.
5751 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5752 /* Skip peers with overridden configuration. */
5753 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5754 PEER_FT_PREFIX_LIST
))
5757 /* Remove configuration on peer-group member. */
5758 filter
= &member
->filter
[afi
][safi
];
5759 if (filter
->plist
[direct
].name
)
5760 XFREE(MTYPE_BGP_FILTER_NAME
,
5761 filter
->plist
[direct
].name
);
5762 filter
->plist
[direct
].name
= NULL
;
5763 filter
->plist
[direct
].plist
= NULL
;
5765 /* Process peer route updates. */
5766 peer_on_policy_change(member
, afi
, safi
,
5767 (direct
== FILTER_OUT
) ? 1 : 0);
5773 /* Update prefix-list list. */
5774 static void peer_prefix_list_update(struct prefix_list
*plist
)
5776 struct listnode
*mnode
, *mnnode
;
5777 struct listnode
*node
, *nnode
;
5780 struct peer_group
*group
;
5781 struct bgp_filter
*filter
;
5786 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5789 * Update the prefix-list on update groups.
5791 update_group_policy_update(
5792 bgp
, BGP_POLICY_PREFIX_LIST
,
5793 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5795 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5796 FOREACH_AFI_SAFI (afi
, safi
) {
5797 filter
= &peer
->filter
[afi
][safi
];
5799 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5801 if (filter
->plist
[direct
].name
)
5802 filter
->plist
[direct
]
5803 .plist
= prefix_list_lookup(
5805 filter
->plist
[direct
]
5808 filter
->plist
[direct
].plist
=
5813 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5814 FOREACH_AFI_SAFI (afi
, safi
) {
5815 filter
= &group
->conf
->filter
[afi
][safi
];
5817 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5819 if (filter
->plist
[direct
].name
)
5820 filter
->plist
[direct
]
5821 .plist
= prefix_list_lookup(
5823 filter
->plist
[direct
]
5826 filter
->plist
[direct
].plist
=
5834 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5837 struct peer
*member
;
5838 struct bgp_filter
*filter
;
5839 struct listnode
*node
, *nnode
;
5841 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5842 return BGP_ERR_INVALID_VALUE
;
5844 /* Set configuration on peer. */
5845 filter
= &peer
->filter
[afi
][safi
];
5846 if (filter
->aslist
[direct
].name
)
5847 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5848 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5849 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5851 /* Check if handling a regular peer. */
5852 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5853 /* Set override-flag and process peer route updates. */
5854 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5855 PEER_FT_FILTER_LIST
);
5856 peer_on_policy_change(peer
, afi
, safi
,
5857 (direct
== FILTER_OUT
) ? 1 : 0);
5859 /* Skip peer-group mechanics for regular peers. */
5864 * Set configuration on all peer-group members, unless they are
5865 * explicitely overriding peer-group configuration.
5867 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5868 /* Skip peers with overridden configuration. */
5869 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5870 PEER_FT_FILTER_LIST
))
5873 /* Set configuration on peer-group member. */
5874 filter
= &member
->filter
[afi
][safi
];
5875 if (filter
->aslist
[direct
].name
)
5876 XFREE(MTYPE_BGP_FILTER_NAME
,
5877 filter
->aslist
[direct
].name
);
5878 filter
->aslist
[direct
].name
=
5879 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5880 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5882 /* Process peer route updates. */
5883 peer_on_policy_change(member
, afi
, safi
,
5884 (direct
== FILTER_OUT
) ? 1 : 0);
5890 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5892 struct peer
*member
;
5893 struct bgp_filter
*filter
;
5894 struct listnode
*node
, *nnode
;
5896 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5897 return BGP_ERR_INVALID_VALUE
;
5899 /* Unset override-flag unconditionally. */
5900 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5901 PEER_FT_FILTER_LIST
);
5903 /* Inherit configuration from peer-group if peer is member. */
5904 if (peer_group_active(peer
)) {
5905 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5906 filter
[afi
][safi
].aslist
[direct
].name
,
5907 MTYPE_BGP_FILTER_NAME
);
5908 PEER_ATTR_INHERIT(peer
, peer
->group
,
5909 filter
[afi
][safi
].aslist
[direct
].aslist
);
5911 /* Otherwise remove configuration from peer. */
5912 filter
= &peer
->filter
[afi
][safi
];
5913 if (filter
->aslist
[direct
].name
)
5914 XFREE(MTYPE_BGP_FILTER_NAME
,
5915 filter
->aslist
[direct
].name
);
5916 filter
->aslist
[direct
].name
= NULL
;
5917 filter
->aslist
[direct
].aslist
= NULL
;
5920 /* Check if handling a regular peer. */
5921 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5922 /* Process peer route updates. */
5923 peer_on_policy_change(peer
, afi
, safi
,
5924 (direct
== FILTER_OUT
) ? 1 : 0);
5926 /* Skip peer-group mechanics for regular peers. */
5931 * Remove configuration on all peer-group members, unless they are
5932 * explicitely overriding peer-group configuration.
5934 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5935 /* Skip peers with overridden configuration. */
5936 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5937 PEER_FT_FILTER_LIST
))
5940 /* Remove configuration on peer-group member. */
5941 filter
= &member
->filter
[afi
][safi
];
5942 if (filter
->aslist
[direct
].name
)
5943 XFREE(MTYPE_BGP_FILTER_NAME
,
5944 filter
->aslist
[direct
].name
);
5945 filter
->aslist
[direct
].name
= NULL
;
5946 filter
->aslist
[direct
].aslist
= NULL
;
5948 /* Process peer route updates. */
5949 peer_on_policy_change(member
, afi
, safi
,
5950 (direct
== FILTER_OUT
) ? 1 : 0);
5956 static void peer_aslist_update(const char *aslist_name
)
5961 struct listnode
*mnode
, *mnnode
;
5962 struct listnode
*node
, *nnode
;
5965 struct peer_group
*group
;
5966 struct bgp_filter
*filter
;
5968 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5969 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5972 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5973 FOREACH_AFI_SAFI (afi
, safi
) {
5974 filter
= &peer
->filter
[afi
][safi
];
5976 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5978 if (filter
->aslist
[direct
].name
)
5979 filter
->aslist
[direct
]
5980 .aslist
= as_list_lookup(
5981 filter
->aslist
[direct
]
5984 filter
->aslist
[direct
].aslist
=
5989 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5990 FOREACH_AFI_SAFI (afi
, safi
) {
5991 filter
= &group
->conf
->filter
[afi
][safi
];
5993 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5995 if (filter
->aslist
[direct
].name
)
5996 filter
->aslist
[direct
]
5997 .aslist
= as_list_lookup(
5998 filter
->aslist
[direct
]
6001 filter
->aslist
[direct
].aslist
=
6009 static void peer_aslist_add(char *aslist_name
)
6011 peer_aslist_update(aslist_name
);
6012 route_map_notify_dependencies((char *)aslist_name
,
6013 RMAP_EVENT_ASLIST_ADDED
);
6016 static void peer_aslist_del(const char *aslist_name
)
6018 peer_aslist_update(aslist_name
);
6019 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6023 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6024 const char *name
, struct route_map
*route_map
)
6026 struct peer
*member
;
6027 struct bgp_filter
*filter
;
6028 struct listnode
*node
, *nnode
;
6030 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6031 return BGP_ERR_INVALID_VALUE
;
6033 /* Set configuration on peer. */
6034 filter
= &peer
->filter
[afi
][safi
];
6035 if (filter
->map
[direct
].name
)
6036 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6037 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6038 filter
->map
[direct
].map
= route_map
;
6040 /* Check if handling a regular peer. */
6041 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6042 /* Set override-flag and process peer route updates. */
6043 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6045 peer_on_policy_change(peer
, afi
, safi
,
6046 (direct
== RMAP_OUT
) ? 1 : 0);
6048 /* Skip peer-group mechanics for regular peers. */
6053 * Set configuration on all peer-group members, unless they are
6054 * explicitely overriding peer-group configuration.
6056 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6057 /* Skip peers with overridden configuration. */
6058 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6062 /* Set configuration on peer-group member. */
6063 filter
= &member
->filter
[afi
][safi
];
6064 if (filter
->map
[direct
].name
)
6065 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6066 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6067 filter
->map
[direct
].map
= route_map
;
6069 /* Process peer route updates. */
6070 peer_on_policy_change(member
, afi
, safi
,
6071 (direct
== RMAP_OUT
) ? 1 : 0);
6076 /* Unset route-map from the peer. */
6077 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6079 struct peer
*member
;
6080 struct bgp_filter
*filter
;
6081 struct listnode
*node
, *nnode
;
6083 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6084 return BGP_ERR_INVALID_VALUE
;
6086 /* Unset override-flag unconditionally. */
6087 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6089 /* Inherit configuration from peer-group if peer is member. */
6090 if (peer_group_active(peer
)) {
6091 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6092 filter
[afi
][safi
].map
[direct
].name
,
6093 MTYPE_BGP_FILTER_NAME
);
6094 PEER_ATTR_INHERIT(peer
, peer
->group
,
6095 filter
[afi
][safi
].map
[direct
].map
);
6097 /* Otherwise remove configuration from peer. */
6098 filter
= &peer
->filter
[afi
][safi
];
6099 if (filter
->map
[direct
].name
)
6100 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6101 filter
->map
[direct
].name
= NULL
;
6102 filter
->map
[direct
].map
= NULL
;
6105 /* Check if handling a regular peer. */
6106 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6107 /* Process peer route updates. */
6108 peer_on_policy_change(peer
, afi
, safi
,
6109 (direct
== RMAP_OUT
) ? 1 : 0);
6111 /* Skip peer-group mechanics for regular peers. */
6116 * Remove configuration on all peer-group members, unless they are
6117 * explicitely overriding peer-group configuration.
6119 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6120 /* Skip peers with overridden configuration. */
6121 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6125 /* Remove configuration on peer-group member. */
6126 filter
= &member
->filter
[afi
][safi
];
6127 if (filter
->map
[direct
].name
)
6128 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6129 filter
->map
[direct
].name
= NULL
;
6130 filter
->map
[direct
].map
= NULL
;
6132 /* Process peer route updates. */
6133 peer_on_policy_change(member
, afi
, safi
,
6134 (direct
== RMAP_OUT
) ? 1 : 0);
6140 /* Set unsuppress-map to the peer. */
6141 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6142 const char *name
, struct route_map
*route_map
)
6144 struct peer
*member
;
6145 struct bgp_filter
*filter
;
6146 struct listnode
*node
, *nnode
;
6148 /* Set configuration on peer. */
6149 filter
= &peer
->filter
[afi
][safi
];
6150 if (filter
->usmap
.name
)
6151 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6152 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6153 filter
->usmap
.map
= route_map
;
6155 /* Check if handling a regular peer. */
6156 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6157 /* Set override-flag and process peer route updates. */
6158 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6159 PEER_FT_UNSUPPRESS_MAP
);
6160 peer_on_policy_change(peer
, afi
, safi
, 1);
6162 /* Skip peer-group mechanics for regular peers. */
6167 * Set configuration on all peer-group members, unless they are
6168 * explicitely overriding peer-group configuration.
6170 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6171 /* Skip peers with overridden configuration. */
6172 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6173 PEER_FT_UNSUPPRESS_MAP
))
6176 /* Set configuration on peer-group member. */
6177 filter
= &member
->filter
[afi
][safi
];
6178 if (filter
->usmap
.name
)
6179 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6180 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6181 filter
->usmap
.map
= route_map
;
6183 /* Process peer route updates. */
6184 peer_on_policy_change(member
, afi
, safi
, 1);
6190 /* Unset route-map from the peer. */
6191 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6193 struct peer
*member
;
6194 struct bgp_filter
*filter
;
6195 struct listnode
*node
, *nnode
;
6197 /* Unset override-flag unconditionally. */
6198 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6200 /* Inherit configuration from peer-group if peer is member. */
6201 if (peer_group_active(peer
)) {
6202 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6203 filter
[afi
][safi
].usmap
.name
,
6204 MTYPE_BGP_FILTER_NAME
);
6205 PEER_ATTR_INHERIT(peer
, peer
->group
,
6206 filter
[afi
][safi
].usmap
.map
);
6208 /* Otherwise remove configuration from peer. */
6209 filter
= &peer
->filter
[afi
][safi
];
6210 if (filter
->usmap
.name
)
6211 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6212 filter
->usmap
.name
= NULL
;
6213 filter
->usmap
.map
= NULL
;
6216 /* Check if handling a regular peer. */
6217 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6218 /* Process peer route updates. */
6219 peer_on_policy_change(peer
, afi
, safi
, 1);
6221 /* Skip peer-group mechanics for regular peers. */
6226 * Remove configuration on all peer-group members, unless they are
6227 * explicitely overriding peer-group configuration.
6229 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6230 /* Skip peers with overridden configuration. */
6231 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6232 PEER_FT_UNSUPPRESS_MAP
))
6235 /* Remove configuration on peer-group member. */
6236 filter
= &member
->filter
[afi
][safi
];
6237 if (filter
->usmap
.name
)
6238 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6239 filter
->usmap
.name
= NULL
;
6240 filter
->usmap
.map
= NULL
;
6242 /* Process peer route updates. */
6243 peer_on_policy_change(member
, afi
, safi
, 1);
6249 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6250 uint32_t max
, uint8_t threshold
, int warning
,
6253 struct peer
*member
;
6254 struct listnode
*node
, *nnode
;
6256 /* Set flags and configuration on peer. */
6257 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6259 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6261 peer_af_flag_unset(peer
, afi
, safi
,
6262 PEER_FLAG_MAX_PREFIX_WARNING
);
6264 peer
->pmax
[afi
][safi
] = max
;
6265 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6266 peer
->pmax_restart
[afi
][safi
] = restart
;
6268 /* Check if handling a regular peer. */
6269 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6270 /* Re-check if peer violates maximum-prefix. */
6271 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6272 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6274 /* Skip peer-group mechanics for regular peers. */
6279 * Set flags and configuration on all peer-group members, unless they
6280 * are explicitely overriding peer-group configuration.
6282 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6283 /* Skip peers with overridden configuration. */
6284 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6285 PEER_FLAG_MAX_PREFIX
))
6288 /* Set flag and configuration on peer-group member. */
6289 member
->pmax
[afi
][safi
] = max
;
6290 member
->pmax_threshold
[afi
][safi
] = threshold
;
6291 member
->pmax_restart
[afi
][safi
] = restart
;
6293 SET_FLAG(member
->af_flags
[afi
][safi
],
6294 PEER_FLAG_MAX_PREFIX_WARNING
);
6296 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6297 PEER_FLAG_MAX_PREFIX_WARNING
);
6299 /* Re-check if peer violates maximum-prefix. */
6300 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6301 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6307 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6309 /* Inherit configuration from peer-group if peer is member. */
6310 if (peer_group_active(peer
)) {
6311 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6312 peer_af_flag_inherit(peer
, afi
, safi
,
6313 PEER_FLAG_MAX_PREFIX_WARNING
);
6314 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6315 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6316 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6321 /* Remove flags and configuration from peer. */
6322 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6323 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6324 peer
->pmax
[afi
][safi
] = 0;
6325 peer
->pmax_threshold
[afi
][safi
] = 0;
6326 peer
->pmax_restart
[afi
][safi
] = 0;
6329 * Remove flags and configuration from all peer-group members, unless
6330 * they are explicitely overriding peer-group configuration.
6332 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6333 struct peer
*member
;
6334 struct listnode
*node
;
6336 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6337 /* Skip peers with overridden configuration. */
6338 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6339 PEER_FLAG_MAX_PREFIX
))
6342 /* Remove flag and configuration on peer-group member.
6344 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6345 PEER_FLAG_MAX_PREFIX
);
6346 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6347 PEER_FLAG_MAX_PREFIX_WARNING
);
6348 member
->pmax
[afi
][safi
] = 0;
6349 member
->pmax_threshold
[afi
][safi
] = 0;
6350 member
->pmax_restart
[afi
][safi
] = 0;
6357 int is_ebgp_multihop_configured(struct peer
*peer
)
6359 struct peer_group
*group
;
6360 struct listnode
*node
, *nnode
;
6363 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6364 group
= peer
->group
;
6365 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6366 && (group
->conf
->ttl
!= 1))
6369 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6370 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6371 && (peer1
->ttl
!= 1))
6375 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6381 /* Set # of hops between us and BGP peer. */
6382 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6384 struct peer_group
*group
;
6385 struct listnode
*node
, *nnode
;
6388 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6389 gtsm_hops
, peer
->host
);
6391 /* We cannot configure ttl-security hops when ebgp-multihop is already
6392 set. For non peer-groups, the check is simple. For peer-groups,
6394 slightly messy, because we need to check both the peer-group
6396 and all peer-group members for any trace of ebgp-multihop
6398 before actually applying the ttl-security rules. Cisco really made a
6399 mess of this configuration parameter, and OpenBGPD got it right.
6402 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6403 if (is_ebgp_multihop_configured(peer
))
6404 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6406 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6407 peer
->gtsm_hops
= gtsm_hops
;
6409 /* Calling ebgp multihop also resets the session.
6410 * On restart, NHT will get setup correctly as will the
6411 * min & max ttls on the socket. The return value is
6414 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6419 group
= peer
->group
;
6420 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6422 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6424 /* Calling ebgp multihop also resets the
6426 * On restart, NHT will get setup correctly as
6428 * min & max ttls on the socket. The return
6432 peer_ebgp_multihop_set(peer
, MAXTTL
);
6436 /* Post the first gtsm setup or if its ibgp, maxttl setting
6438 * necessary, just set the minttl.
6440 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6441 peer
->gtsm_hops
= gtsm_hops
;
6444 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6445 MAXTTL
+ 1 - gtsm_hops
);
6446 if ((peer
->status
< Established
) && peer
->doppelganger
6447 && (peer
->doppelganger
->fd
>= 0))
6448 sockopt_minttl(peer
->su
.sa
.sa_family
,
6449 peer
->doppelganger
->fd
,
6450 MAXTTL
+ 1 - gtsm_hops
);
6452 group
= peer
->group
;
6453 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6455 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6457 /* Change setting of existing peer
6458 * established then change value (may break
6460 * not established yet (teardown session and
6462 * no session then do nothing (will get
6463 * handled by next connection)
6465 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6467 peer
->su
.sa
.sa_family
, peer
->fd
,
6468 MAXTTL
+ 1 - peer
->gtsm_hops
);
6469 if ((peer
->status
< Established
)
6470 && peer
->doppelganger
6471 && (peer
->doppelganger
->fd
>= 0))
6472 sockopt_minttl(peer
->su
.sa
.sa_family
,
6473 peer
->doppelganger
->fd
,
6474 MAXTTL
+ 1 - gtsm_hops
);
6482 int peer_ttl_security_hops_unset(struct peer
*peer
)
6484 struct peer_group
*group
;
6485 struct listnode
*node
, *nnode
;
6488 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6491 /* if a peer-group member, then reset to peer-group default rather than
6493 if (peer_group_active(peer
))
6494 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6496 peer
->gtsm_hops
= 0;
6498 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6499 /* Invoking ebgp_multihop_set will set the TTL back to the
6501 * value as well as restting the NHT and such. The session is
6504 if (peer
->sort
== BGP_PEER_EBGP
)
6505 ret
= peer_ebgp_multihop_unset(peer
);
6508 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6511 if ((peer
->status
< Established
) && peer
->doppelganger
6512 && (peer
->doppelganger
->fd
>= 0))
6513 sockopt_minttl(peer
->su
.sa
.sa_family
,
6514 peer
->doppelganger
->fd
, 0);
6517 group
= peer
->group
;
6518 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6519 peer
->gtsm_hops
= 0;
6520 if (peer
->sort
== BGP_PEER_EBGP
)
6521 ret
= peer_ebgp_multihop_unset(peer
);
6524 sockopt_minttl(peer
->su
.sa
.sa_family
,
6527 if ((peer
->status
< Established
)
6528 && peer
->doppelganger
6529 && (peer
->doppelganger
->fd
>= 0))
6530 sockopt_minttl(peer
->su
.sa
.sa_family
,
6531 peer
->doppelganger
->fd
,
6541 * If peer clear is invoked in a loop for all peers on the BGP instance,
6542 * it may end up freeing the doppelganger, and if this was the next node
6543 * to the current node, we would end up accessing the freed next node.
6544 * Pass along additional parameter which can be updated if next node
6545 * is freed; only required when walking the peer list on BGP instance.
6547 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6549 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6550 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6551 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6552 if (peer
->t_pmax_restart
) {
6553 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6554 if (bgp_debug_neighbor_events(peer
))
6556 "%s Maximum-prefix restart timer canceled",
6559 BGP_EVENT_ADD(peer
, BGP_Start
);
6563 peer
->v_start
= BGP_INIT_START_TIMER
;
6564 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6565 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6566 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6568 bgp_session_reset_safe(peer
, nnode
);
6573 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6574 enum bgp_clear_type stype
)
6576 struct peer_af
*paf
;
6578 if (peer
->status
!= Established
)
6581 if (!peer
->afc
[afi
][safi
])
6582 return BGP_ERR_AF_UNCONFIGURED
;
6584 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6586 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6587 /* Clear the "neighbor x.x.x.x default-originate" flag */
6588 paf
= peer_af_find(peer
, afi
, safi
);
6589 if (paf
&& paf
->subgroup
6590 && CHECK_FLAG(paf
->subgroup
->sflags
,
6591 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6592 UNSET_FLAG(paf
->subgroup
->sflags
,
6593 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6595 bgp_announce_route(peer
, afi
, safi
);
6598 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6599 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6600 PEER_CAP_ORF_PREFIX_SM_ADV
)
6601 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6602 PEER_CAP_ORF_PREFIX_RM_RCV
)
6603 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6604 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6605 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6606 uint8_t prefix_type
;
6608 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6609 PEER_CAP_ORF_PREFIX_RM_RCV
))
6610 prefix_type
= ORF_TYPE_PREFIX
;
6612 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6614 if (filter
->plist
[FILTER_IN
].plist
) {
6615 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6616 PEER_STATUS_ORF_PREFIX_SEND
))
6617 bgp_route_refresh_send(
6618 peer
, afi
, safi
, prefix_type
,
6620 bgp_route_refresh_send(peer
, afi
, safi
,
6622 REFRESH_IMMEDIATE
, 0);
6624 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6625 PEER_STATUS_ORF_PREFIX_SEND
))
6626 bgp_route_refresh_send(
6627 peer
, afi
, safi
, prefix_type
,
6628 REFRESH_IMMEDIATE
, 1);
6630 bgp_route_refresh_send(peer
, afi
, safi
,
6637 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6638 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6639 /* If neighbor has soft reconfiguration inbound flag.
6640 Use Adj-RIB-In database. */
6641 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6642 PEER_FLAG_SOFT_RECONFIG
))
6643 bgp_soft_reconfig_in(peer
, afi
, safi
);
6645 /* If neighbor has route refresh capability, send route
6647 message to the peer. */
6648 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6649 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6650 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6653 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6659 /* Display peer uptime.*/
6660 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6663 time_t uptime1
, epoch_tbuf
;
6666 /* If there is no connection has been done before print `never'. */
6669 json_object_string_add(json
, "peerUptime", "never");
6670 json_object_int_add(json
, "peerUptimeMsec", 0);
6672 snprintf(buf
, len
, "never");
6676 /* Get current time. */
6677 uptime1
= bgp_clock();
6679 tm
= gmtime(&uptime1
);
6681 if (uptime1
< ONE_DAY_SECOND
)
6682 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6684 else if (uptime1
< ONE_WEEK_SECOND
)
6685 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6687 else if (uptime1
< ONE_YEAR_SECOND
)
6688 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6689 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6691 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6693 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6696 epoch_tbuf
= time(NULL
) - uptime1
;
6697 json_object_string_add(json
, "peerUptime", buf
);
6698 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6699 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6706 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6707 afi_t afi
, safi_t safi
)
6709 struct bgp_filter
*filter
;
6713 filter
= &peer
->filter
[afi
][safi
];
6715 /* distribute-list. */
6716 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6718 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6719 filter
->dlist
[FILTER_IN
].name
);
6721 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6723 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6724 filter
->dlist
[FILTER_OUT
].name
);
6727 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6729 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6730 filter
->plist
[FILTER_IN
].name
);
6732 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6734 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6735 filter
->plist
[FILTER_OUT
].name
);
6738 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6739 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6740 filter
->map
[RMAP_IN
].name
);
6742 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6744 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6745 filter
->map
[RMAP_OUT
].name
);
6747 /* unsuppress-map */
6748 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6749 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6750 filter
->usmap
.name
);
6753 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6755 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6756 filter
->aslist
[FILTER_IN
].name
);
6758 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6760 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6761 filter
->aslist
[FILTER_OUT
].name
);
6764 /* BGP peer configuration display function. */
6765 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6768 struct peer
*g_peer
= NULL
;
6769 char buf
[SU_ADDRSTRLEN
];
6771 int if_pg_printed
= FALSE
;
6772 int if_ras_printed
= FALSE
;
6774 /* Skip dynamic neighbors. */
6775 if (peer_dynamic_neighbor(peer
))
6779 addr
= peer
->conf_if
;
6783 /************************************
6784 ****** Global to the neighbor ******
6785 ************************************/
6786 if (peer
->conf_if
) {
6787 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6788 vty_out(vty
, " neighbor %s interface v6only", addr
);
6790 vty_out(vty
, " neighbor %s interface", addr
);
6792 if (peer_group_active(peer
)) {
6793 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6794 if_pg_printed
= TRUE
;
6795 } else if (peer
->as_type
== AS_SPECIFIED
) {
6796 vty_out(vty
, " remote-as %u", peer
->as
);
6797 if_ras_printed
= TRUE
;
6798 } else if (peer
->as_type
== AS_INTERNAL
) {
6799 vty_out(vty
, " remote-as internal");
6800 if_ras_printed
= TRUE
;
6801 } else if (peer
->as_type
== AS_EXTERNAL
) {
6802 vty_out(vty
, " remote-as external");
6803 if_ras_printed
= TRUE
;
6809 /* remote-as and peer-group */
6810 /* peer is a member of a peer-group */
6811 if (peer_group_active(peer
)) {
6812 g_peer
= peer
->group
->conf
;
6814 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6815 if (peer
->as_type
== AS_SPECIFIED
) {
6816 vty_out(vty
, " neighbor %s remote-as %u\n",
6818 } else if (peer
->as_type
== AS_INTERNAL
) {
6820 " neighbor %s remote-as internal\n",
6822 } else if (peer
->as_type
== AS_EXTERNAL
) {
6824 " neighbor %s remote-as external\n",
6829 /* For swpX peers we displayed the peer-group
6830 * via 'neighbor swpX interface peer-group WORD' */
6832 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6836 /* peer is NOT a member of a peer-group */
6838 /* peer is a peer-group, declare the peer-group */
6839 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6840 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6843 if (!if_ras_printed
) {
6844 if (peer
->as_type
== AS_SPECIFIED
) {
6845 vty_out(vty
, " neighbor %s remote-as %u\n",
6847 } else if (peer
->as_type
== AS_INTERNAL
) {
6849 " neighbor %s remote-as internal\n",
6851 } else if (peer
->as_type
== AS_EXTERNAL
) {
6853 " neighbor %s remote-as external\n",
6860 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6861 vty_out(vty
, " neighbor %s local-as %u", addr
,
6862 peer
->change_local_as
);
6863 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6864 vty_out(vty
, " no-prepend");
6865 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6866 vty_out(vty
, " replace-as");
6872 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6876 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6877 if (peer
->tx_shutdown_message
)
6878 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6879 peer
->tx_shutdown_message
);
6881 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6885 if (peer
->bfd_info
) {
6886 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6887 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6892 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6893 vty_out(vty
, " neighbor %s password %s\n", addr
,
6897 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6898 if (!peer_group_active(peer
)) {
6899 vty_out(vty
, " neighbor %s solo\n", addr
);
6904 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6905 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6908 /* Local interface name */
6910 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6914 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6915 vty_out(vty
, " neighbor %s passive\n", addr
);
6918 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6919 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6920 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6921 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6926 /* ttl-security hops */
6927 if (peer
->gtsm_hops
!= 0) {
6928 if (!peer_group_active(peer
)
6929 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6930 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6931 addr
, peer
->gtsm_hops
);
6935 /* disable-connected-check */
6936 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
6937 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
6939 /* enforce-first-as */
6940 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
6941 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
6944 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
6945 if (peer
->update_source
)
6946 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6947 sockunion2str(peer
->update_source
, buf
,
6949 else if (peer
->update_if
)
6950 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6954 /* advertisement-interval */
6955 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
6956 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6960 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
6961 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6962 peer
->keepalive
, peer
->holdtime
);
6964 /* timers connect */
6965 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
6966 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6969 /* capability dynamic */
6970 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
6971 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6973 /* capability extended-nexthop */
6974 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
6975 if (CHECK_FLAG(peer
->flags_invert
, PEER_FLAG_CAPABILITY_ENHE
))
6977 " no neighbor %s capability extended-nexthop\n",
6981 " neighbor %s capability extended-nexthop\n",
6985 /* dont-capability-negotiation */
6986 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
6987 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
6989 /* override-capability */
6990 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
6991 vty_out(vty
, " neighbor %s override-capability\n", addr
);
6993 /* strict-capability-match */
6994 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
6995 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
6998 /* BGP peer configuration display function. */
6999 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7000 struct peer
*peer
, afi_t afi
, safi_t safi
)
7002 struct peer
*g_peer
= NULL
;
7004 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7006 /* Skip dynamic neighbors. */
7007 if (peer_dynamic_neighbor(peer
))
7011 addr
= peer
->conf_if
;
7015 /************************************
7016 ****** Per AF to the neighbor ******
7017 ************************************/
7018 if (peer_group_active(peer
)) {
7019 g_peer
= peer
->group
->conf
;
7021 /* If the peer-group is active but peer is not, print a 'no
7023 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7024 vty_out(vty
, " no neighbor %s activate\n", addr
);
7027 /* If the peer-group is not active but peer is, print an
7029 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7030 vty_out(vty
, " neighbor %s activate\n", addr
);
7033 if (peer
->afc
[afi
][safi
]) {
7034 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7035 if (bgp_flag_check(bgp
,
7036 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7037 vty_out(vty
, " neighbor %s activate\n",
7041 vty_out(vty
, " neighbor %s activate\n", addr
);
7043 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7044 if (!bgp_flag_check(bgp
,
7045 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7047 " no neighbor %s activate\n",
7054 /* addpath TX knobs */
7055 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7056 switch (peer
->addpath_type
[afi
][safi
]) {
7057 case BGP_ADDPATH_ALL
:
7058 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7061 case BGP_ADDPATH_BEST_PER_AS
:
7063 " neighbor %s addpath-tx-bestpath-per-AS\n",
7066 case BGP_ADDPATH_MAX
:
7067 case BGP_ADDPATH_NONE
:
7072 /* ORF capability. */
7073 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7074 || peergroup_af_flag_check(peer
, afi
, safi
,
7075 PEER_FLAG_ORF_PREFIX_RM
)) {
7076 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7078 if (peergroup_af_flag_check(peer
, afi
, safi
,
7079 PEER_FLAG_ORF_PREFIX_SM
)
7080 && peergroup_af_flag_check(peer
, afi
, safi
,
7081 PEER_FLAG_ORF_PREFIX_RM
))
7082 vty_out(vty
, " both");
7083 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7084 PEER_FLAG_ORF_PREFIX_SM
))
7085 vty_out(vty
, " send");
7087 vty_out(vty
, " receive");
7091 /* Route reflector client. */
7092 if (peergroup_af_flag_check(peer
, afi
, safi
,
7093 PEER_FLAG_REFLECTOR_CLIENT
)) {
7094 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7097 /* next-hop-self force */
7098 if (peergroup_af_flag_check(peer
, afi
, safi
,
7099 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7100 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7104 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7105 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7108 /* remove-private-AS */
7109 if (peergroup_af_flag_check(peer
, afi
, safi
,
7110 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7111 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7115 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7116 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7117 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7121 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7122 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7123 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7126 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7127 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7128 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7132 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7133 vty_out(vty
, " neighbor %s as-override\n", addr
);
7136 /* send-community print. */
7137 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7138 PEER_FLAG_SEND_COMMUNITY
);
7139 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7140 PEER_FLAG_SEND_EXT_COMMUNITY
);
7141 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7142 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7144 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7145 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7146 vty_out(vty
, " no neighbor %s send-community all\n",
7151 " no neighbor %s send-community\n",
7155 " no neighbor %s send-community extended\n",
7160 " no neighbor %s send-community large\n",
7164 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7165 vty_out(vty
, " neighbor %s send-community all\n",
7167 } else if (flag_scomm
&& flag_secomm
) {
7168 vty_out(vty
, " neighbor %s send-community both\n",
7172 vty_out(vty
, " neighbor %s send-community\n",
7176 " neighbor %s send-community extended\n",
7180 " neighbor %s send-community large\n",
7185 /* Default information */
7186 if (peergroup_af_flag_check(peer
, afi
, safi
,
7187 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7188 vty_out(vty
, " neighbor %s default-originate", addr
);
7190 if (peer
->default_rmap
[afi
][safi
].name
)
7191 vty_out(vty
, " route-map %s",
7192 peer
->default_rmap
[afi
][safi
].name
);
7197 /* Soft reconfiguration inbound. */
7198 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7199 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7203 /* maximum-prefix. */
7204 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7205 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7206 peer
->pmax
[afi
][safi
]);
7208 if (peer
->pmax_threshold
[afi
][safi
]
7209 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7210 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7211 if (peer_af_flag_check(peer
, afi
, safi
,
7212 PEER_FLAG_MAX_PREFIX_WARNING
))
7213 vty_out(vty
, " warning-only");
7214 if (peer
->pmax_restart
[afi
][safi
])
7215 vty_out(vty
, " restart %u",
7216 peer
->pmax_restart
[afi
][safi
]);
7221 /* Route server client. */
7222 if (peergroup_af_flag_check(peer
, afi
, safi
,
7223 PEER_FLAG_RSERVER_CLIENT
)) {
7224 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7227 /* Nexthop-local unchanged. */
7228 if (peergroup_af_flag_check(peer
, afi
, safi
,
7229 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7230 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7233 /* allowas-in <1-10> */
7234 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7235 if (peer_af_flag_check(peer
, afi
, safi
,
7236 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7237 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7238 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7239 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7241 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7242 peer
->allowas_in
[afi
][safi
]);
7247 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7248 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7249 peer
->weight
[afi
][safi
]);
7252 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7254 /* atribute-unchanged. */
7255 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7256 || (safi
!= SAFI_EVPN
7257 && peer_af_flag_check(peer
, afi
, safi
,
7258 PEER_FLAG_NEXTHOP_UNCHANGED
))
7259 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7261 if (!peer_group_active(peer
)
7262 || peergroup_af_flag_check(peer
, afi
, safi
,
7263 PEER_FLAG_AS_PATH_UNCHANGED
)
7264 || peergroup_af_flag_check(peer
, afi
, safi
,
7265 PEER_FLAG_NEXTHOP_UNCHANGED
)
7266 || peergroup_af_flag_check(peer
, afi
, safi
,
7267 PEER_FLAG_MED_UNCHANGED
)) {
7270 " neighbor %s attribute-unchanged%s%s%s\n",
7272 peer_af_flag_check(peer
, afi
, safi
,
7273 PEER_FLAG_AS_PATH_UNCHANGED
)
7276 peer_af_flag_check(peer
, afi
, safi
,
7277 PEER_FLAG_NEXTHOP_UNCHANGED
)
7280 peer_af_flag_check(peer
, afi
, safi
,
7281 PEER_FLAG_MED_UNCHANGED
)
7288 /* Address family based peer configuration display. */
7289 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7293 struct peer_group
*group
;
7294 struct listnode
*node
, *nnode
;
7297 vty_frame(vty
, " !\n address-family ");
7298 if (afi
== AFI_IP
) {
7299 if (safi
== SAFI_UNICAST
)
7300 vty_frame(vty
, "ipv4 unicast");
7301 else if (safi
== SAFI_LABELED_UNICAST
)
7302 vty_frame(vty
, "ipv4 labeled-unicast");
7303 else if (safi
== SAFI_MULTICAST
)
7304 vty_frame(vty
, "ipv4 multicast");
7305 else if (safi
== SAFI_MPLS_VPN
)
7306 vty_frame(vty
, "ipv4 vpn");
7307 else if (safi
== SAFI_ENCAP
)
7308 vty_frame(vty
, "ipv4 encap");
7309 else if (safi
== SAFI_FLOWSPEC
)
7310 vty_frame(vty
, "ipv4 flowspec");
7311 } else if (afi
== AFI_IP6
) {
7312 if (safi
== SAFI_UNICAST
)
7313 vty_frame(vty
, "ipv6 unicast");
7314 else if (safi
== SAFI_LABELED_UNICAST
)
7315 vty_frame(vty
, "ipv6 labeled-unicast");
7316 else if (safi
== SAFI_MULTICAST
)
7317 vty_frame(vty
, "ipv6 multicast");
7318 else if (safi
== SAFI_MPLS_VPN
)
7319 vty_frame(vty
, "ipv6 vpn");
7320 else if (safi
== SAFI_ENCAP
)
7321 vty_frame(vty
, "ipv6 encap");
7322 else if (safi
== SAFI_FLOWSPEC
)
7323 vty_frame(vty
, "ipv6 flowspec");
7324 } else if (afi
== AFI_L2VPN
) {
7325 if (safi
== SAFI_EVPN
)
7326 vty_frame(vty
, "l2vpn evpn");
7328 vty_frame(vty
, "\n");
7330 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7332 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7334 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7336 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7337 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7339 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7340 /* Skip dynamic neighbors. */
7341 if (peer_dynamic_neighbor(peer
))
7344 /* Do not display doppelganger peers */
7345 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7346 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7349 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7350 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7352 if (safi
== SAFI_EVPN
)
7353 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7355 if (safi
== SAFI_FLOWSPEC
)
7356 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7358 if (safi
== SAFI_UNICAST
) {
7359 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7360 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7361 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7363 vty_out(vty
, " export vpn\n");
7365 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7366 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7368 vty_out(vty
, " import vpn\n");
7370 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7371 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7374 for (ALL_LIST_ELEMENTS_RO(
7375 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7377 vty_out(vty
, " import vrf %s\n", name
);
7381 vty_endframe(vty
, " exit-address-family\n");
7384 /* clang-format off */
7385 #if CONFDATE > 20190517
7386 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7388 /* clang-format on */
7390 int bgp_config_write(struct vty
*vty
)
7394 struct peer_group
*group
;
7396 struct listnode
*node
, *nnode
;
7397 struct listnode
*mnode
, *mnnode
;
7399 /* BGP Multiple instance. */
7400 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7401 vty_out(vty
, "no bgp multiple-instance\n");
7405 /* BGP Config type. */
7406 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7407 vty_out(vty
, "bgp config-type cisco\n");
7411 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7412 vty_out(vty
, "bgp route-map delay-timer %u\n",
7413 bm
->rmap_update_timer
);
7416 vty_out(vty
, "!\n");
7418 /* BGP configuration. */
7419 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7421 /* skip all auto created vrf as they dont have user config */
7422 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7425 /* Migrate deprecated 'bgp enforce-first-as'
7426 * config to 'neighbor * enforce-first-as' configs
7428 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7429 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7430 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7431 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7434 /* Router bgp ASN */
7435 vty_out(vty
, "router bgp %u", bgp
->as
);
7437 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7439 vty_out(vty
, " %s %s",
7441 == BGP_INSTANCE_TYPE_VIEW
)
7448 /* No Synchronization */
7449 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7450 vty_out(vty
, " no synchronization\n");
7452 /* BGP fast-external-failover. */
7453 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7454 vty_out(vty
, " no bgp fast-external-failover\n");
7456 /* BGP router ID. */
7457 if (bgp
->router_id_static
.s_addr
!= 0)
7458 vty_out(vty
, " bgp router-id %s\n",
7459 inet_ntoa(bgp
->router_id_static
));
7461 /* BGP log-neighbor-changes. */
7462 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7463 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7464 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7466 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7470 /* BGP configuration. */
7471 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7472 vty_out(vty
, " bgp always-compare-med\n");
7474 /* BGP default ipv4-unicast. */
7475 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7476 vty_out(vty
, " no bgp default ipv4-unicast\n");
7478 /* BGP default local-preference. */
7479 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7480 vty_out(vty
, " bgp default local-preference %u\n",
7481 bgp
->default_local_pref
);
7483 /* BGP default show-hostname */
7484 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7485 != DFLT_BGP_SHOW_HOSTNAME
)
7486 vty_out(vty
, " %sbgp default show-hostname\n",
7487 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7491 /* BGP default subgroup-pkt-queue-max. */
7492 if (bgp
->default_subgroup_pkt_queue_max
7493 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7494 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7495 bgp
->default_subgroup_pkt_queue_max
);
7497 /* BGP client-to-client reflection. */
7498 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7499 vty_out(vty
, " no bgp client-to-client reflection\n");
7501 /* BGP cluster ID. */
7502 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7503 vty_out(vty
, " bgp cluster-id %s\n",
7504 inet_ntoa(bgp
->cluster_id
));
7506 /* Disable ebgp connected nexthop check */
7507 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7509 " bgp disable-ebgp-connected-route-check\n");
7511 /* Confederation identifier*/
7512 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7513 vty_out(vty
, " bgp confederation identifier %i\n",
7516 /* Confederation peer */
7517 if (bgp
->confed_peers_cnt
> 0) {
7520 vty_out(vty
, " bgp confederation peers");
7522 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7523 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7528 /* BGP deterministic-med. */
7529 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7530 != DFLT_BGP_DETERMINISTIC_MED
)
7531 vty_out(vty
, " %sbgp deterministic-med\n",
7532 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7536 /* BGP update-delay. */
7537 bgp_config_write_update_delay(vty
, bgp
);
7539 if (bgp
->v_maxmed_onstartup
7540 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7541 vty_out(vty
, " bgp max-med on-startup %u",
7542 bgp
->v_maxmed_onstartup
);
7543 if (bgp
->maxmed_onstartup_value
7544 != BGP_MAXMED_VALUE_DEFAULT
)
7546 bgp
->maxmed_onstartup_value
);
7549 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7550 vty_out(vty
, " bgp max-med administrative");
7551 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7552 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7557 bgp_config_write_wpkt_quanta(vty
, bgp
);
7559 bgp_config_write_rpkt_quanta(vty
, bgp
);
7562 bgp_config_write_coalesce_time(vty
, bgp
);
7564 /* BGP graceful-restart. */
7565 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7567 " bgp graceful-restart stalepath-time %u\n",
7568 bgp
->stalepath_time
);
7569 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7570 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7572 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7573 vty_out(vty
, " bgp graceful-restart\n");
7575 /* BGP graceful-shutdown */
7576 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7577 vty_out(vty
, " bgp graceful-shutdown\n");
7579 /* BGP graceful-restart Preserve State F bit. */
7580 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7582 " bgp graceful-restart preserve-fw-state\n");
7584 /* BGP bestpath method. */
7585 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7586 vty_out(vty
, " bgp bestpath as-path ignore\n");
7587 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7588 vty_out(vty
, " bgp bestpath as-path confed\n");
7590 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7591 if (bgp_flag_check(bgp
,
7592 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7594 " bgp bestpath as-path multipath-relax as-set\n");
7597 " bgp bestpath as-path multipath-relax\n");
7601 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7603 " bgp route-reflector allow-outbound-policy\n");
7605 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7606 vty_out(vty
, " bgp bestpath compare-routerid\n");
7607 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7608 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7609 vty_out(vty
, " bgp bestpath med");
7610 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7611 vty_out(vty
, " confed");
7612 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7613 vty_out(vty
, " missing-as-worst");
7617 /* BGP network import check. */
7618 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7619 != DFLT_BGP_IMPORT_CHECK
)
7620 vty_out(vty
, " %sbgp network import-check\n",
7621 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7625 /* BGP flag dampening. */
7626 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7627 BGP_CONFIG_DAMPENING
))
7628 bgp_config_write_damp(vty
);
7630 /* BGP timers configuration. */
7631 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7632 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7633 vty_out(vty
, " timers bgp %u %u\n",
7634 bgp
->default_keepalive
, bgp
->default_holdtime
);
7637 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7638 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7641 /* Normal neighbor configuration. */
7642 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7643 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7644 bgp_config_write_peer_global(vty
, bgp
, peer
);
7647 /* listen range and limit for dynamic BGP neighbors */
7648 bgp_config_write_listen(vty
, bgp
);
7651 * BGP default autoshutdown neighbors
7653 * This must be placed after any peer and peer-group
7654 * configuration, to avoid setting all peers to shutdown after
7655 * a daemon restart, which is undesired behavior. (see #2286)
7657 if (bgp
->autoshutdown
)
7658 vty_out(vty
, " bgp default shutdown\n");
7660 /* No auto-summary */
7661 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7662 vty_out(vty
, " no auto-summary\n");
7664 /* IPv4 unicast configuration. */
7665 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7667 /* IPv4 multicast configuration. */
7668 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7670 /* IPv4 labeled-unicast configuration. */
7671 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7673 /* IPv4 VPN configuration. */
7674 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7676 /* ENCAPv4 configuration. */
7677 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7679 /* FLOWSPEC v4 configuration. */
7680 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7682 /* IPv6 unicast configuration. */
7683 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7685 /* IPv6 multicast configuration. */
7686 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7688 /* IPv6 labeled-unicast configuration. */
7689 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7690 SAFI_LABELED_UNICAST
);
7692 /* IPv6 VPN configuration. */
7693 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7695 /* ENCAPv6 configuration. */
7696 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7698 /* FLOWSPEC v6 configuration. */
7699 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7701 /* EVPN configuration. */
7702 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7705 bgp_rfapi_cfg_write(vty
, bgp
);
7708 vty_out(vty
, "!\n");
7713 void bgp_master_init(struct thread_master
*master
)
7717 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7720 bm
->bgp
= list_new();
7721 bm
->listen_sockets
= list_new();
7722 bm
->port
= BGP_PORT_DEFAULT
;
7723 bm
->master
= master
;
7724 bm
->start_time
= bgp_clock();
7725 bm
->t_rmap_update
= NULL
;
7726 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7727 bm
->terminating
= false;
7729 bgp_process_queue_init();
7731 /* init the rd id space.
7732 assign 0th index in the bitfield,
7733 so that we start with id 1
7735 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7736 bf_assign_zero_index(bm
->rd_idspace
);
7738 /* Enable multiple instances by default. */
7739 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7741 /* mpls label dynamic allocation pool */
7742 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7744 QOBJ_REG(bm
, bgp_master
);
7748 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7749 * instance delete (non-default only) or BGP exit.
7751 static void bgp_if_finish(struct bgp
*bgp
)
7753 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7754 struct interface
*ifp
;
7756 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7759 FOR_ALL_INTERFACES (vrf
, ifp
) {
7760 struct listnode
*c_node
, *c_nnode
;
7761 struct connected
*c
;
7763 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7764 bgp_connected_delete(bgp
, c
);
7768 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7770 struct vrf
*vrf
= NULL
;
7771 struct listnode
*next
;
7774 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7775 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7777 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7778 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7781 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7785 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7786 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7787 {.completions
= NULL
},
7790 struct frr_pthread
*bgp_pth_io
;
7791 struct frr_pthread
*bgp_pth_ka
;
7793 static void bgp_pthreads_init()
7795 assert(!bgp_pth_io
);
7796 assert(!bgp_pth_ka
);
7800 struct frr_pthread_attr io
= {
7801 .start
= frr_pthread_attr_default
.start
,
7802 .stop
= frr_pthread_attr_default
.stop
,
7804 struct frr_pthread_attr ka
= {
7805 .start
= bgp_keepalives_start
,
7806 .stop
= bgp_keepalives_stop
,
7808 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7809 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7812 void bgp_pthreads_run()
7814 frr_pthread_run(bgp_pth_io
, NULL
);
7815 frr_pthread_run(bgp_pth_ka
, NULL
);
7817 /* Wait until threads are ready. */
7818 frr_pthread_wait_running(bgp_pth_io
);
7819 frr_pthread_wait_running(bgp_pth_ka
);
7822 void bgp_pthreads_finish()
7824 frr_pthread_stop_all();
7825 frr_pthread_finish();
7828 void bgp_init(unsigned short instance
)
7831 /* allocates some vital data structures used by peer commands in
7834 /* pre-init pthreads */
7835 bgp_pthreads_init();
7838 bgp_zebra_init(bm
->master
, instance
);
7841 vnc_zebra_init(bm
->master
);
7844 /* BGP VTY commands installation. */
7852 bgp_route_map_init();
7853 bgp_scan_vty_init();
7858 bgp_ethernetvpn_init();
7859 bgp_flowspec_vty_init();
7861 /* Access list initialize. */
7863 access_list_add_hook(peer_distribute_update
);
7864 access_list_delete_hook(peer_distribute_update
);
7866 /* Filter list initialize. */
7868 as_list_add_hook(peer_aslist_add
);
7869 as_list_delete_hook(peer_aslist_del
);
7871 /* Prefix list initialize.*/
7873 prefix_list_add_hook(peer_prefix_list_update
);
7874 prefix_list_delete_hook(peer_prefix_list_update
);
7876 /* Community list initialize. */
7877 bgp_clist
= community_list_init();
7882 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7885 void bgp_terminate(void)
7889 struct listnode
*node
, *nnode
;
7890 struct listnode
*mnode
, *mnnode
;
7894 /* Close the listener sockets first as this prevents peers from
7896 * to reconnect on receiving the peer unconfig message. In the presence
7897 * of a large number of peers this will ensure that no peer is left with
7898 * a dangling connection
7900 /* reverse bgp_master_init */
7903 if (bm
->listen_sockets
)
7904 list_delete(&bm
->listen_sockets
);
7906 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7907 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7908 if (peer
->status
== Established
7909 || peer
->status
== OpenSent
7910 || peer
->status
== OpenConfirm
)
7911 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7912 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7914 if (bm
->process_main_queue
)
7915 work_queue_free_and_null(&bm
->process_main_queue
);
7917 if (bm
->t_rmap_update
)
7918 BGP_TIMER_OFF(bm
->t_rmap_update
);