1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
49 #include "bgpd/bgpd.h"
50 #include "bgpd/bgp_table.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_route.h"
53 #include "bgpd/bgp_dump.h"
54 #include "bgpd/bgp_debug.h"
55 #include "bgpd/bgp_errors.h"
56 #include "bgpd/bgp_community.h"
57 #include "bgpd/bgp_attr.h"
58 #include "bgpd/bgp_regex.h"
59 #include "bgpd/bgp_clist.h"
60 #include "bgpd/bgp_fsm.h"
61 #include "bgpd/bgp_packet.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_open.h"
64 #include "bgpd/bgp_filter.h"
65 #include "bgpd/bgp_nexthop.h"
66 #include "bgpd/bgp_damp.h"
67 #include "bgpd/bgp_mplsvpn.h"
69 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/bgp_evpn.h"
73 #include "bgpd/bgp_advertise.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_vty.h"
76 #include "bgpd/bgp_mpath.h"
77 #include "bgpd/bgp_nht.h"
78 #include "bgpd/bgp_updgrp.h"
79 #include "bgpd/bgp_bfd.h"
80 #include "bgpd/bgp_memory.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_keepalives.h"
83 #include "bgpd/bgp_io.h"
84 #include "bgpd/bgp_ecommunity.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_labelpool.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "bgpd/bgp_addpath.h"
89 #include "bgpd/bgp_evpn_private.h"
90 #include "bgpd/bgp_mac.h"
92 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
93 DEFINE_MTYPE_STATIC(BGPD
, BGP_EVPN_INFO
, "BGP EVPN instance information");
94 DEFINE_QOBJ_TYPE(bgp_master
)
96 DEFINE_QOBJ_TYPE(peer
)
97 DEFINE_HOOK(bgp_inst_delete
, (struct bgp
*bgp
), (bgp
))
99 /* BGP process wide configuration. */
100 static struct bgp_master bgp_master
;
102 /* BGP process wide configuration pointer to export. */
103 struct bgp_master
*bm
;
105 /* BGP community-list. */
106 struct community_list_handler
*bgp_clist
;
108 unsigned int multipath_num
= MULTIPATH_NUM
;
110 static void bgp_if_finish(struct bgp
*bgp
);
111 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
113 extern struct zclient
*zclient
;
115 /* handle main socket creation or deletion */
116 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
118 static int bgp_server_main_created
;
121 if (bgp_server_main_created
)
123 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
124 return BGP_ERR_INVALID_VALUE
;
125 bgp_server_main_created
= 1;
128 if (!bgp_server_main_created
)
131 bgp_server_main_created
= 0;
135 void bgp_session_reset(struct peer
*peer
)
137 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
138 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
139 peer_delete(peer
->doppelganger
);
141 BGP_EVENT_ADD(peer
, BGP_Stop
);
145 * During session reset, we may delete the doppelganger peer, which would
146 * be the next node to the current node. If the session reset was invoked
147 * during walk of peer list, we would end up accessing the freed next
148 * node. This function moves the next node along.
150 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
155 n
= (nnode
) ? *nnode
: NULL
;
156 npeer
= (n
) ? listgetdata(n
) : NULL
;
158 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
159 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
160 PEER_FLAG_CONFIG_NODE
))) {
161 if (peer
->doppelganger
== npeer
)
162 /* nnode and *nnode are confirmed to be non-NULL here */
163 *nnode
= (*nnode
)->next
;
164 peer_delete(peer
->doppelganger
);
167 BGP_EVENT_ADD(peer
, BGP_Stop
);
170 /* BGP global flag manipulation. */
171 int bgp_option_set(int flag
)
175 case BGP_OPT_NO_LISTEN
:
176 case BGP_OPT_NO_ZEBRA
:
177 SET_FLAG(bm
->options
, flag
);
180 return BGP_ERR_INVALID_FLAG
;
185 int bgp_option_unset(int flag
)
189 case BGP_OPT_NO_ZEBRA
:
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 /* Internal function to set BGP structure configureation flag. */
205 static void bgp_config_set(struct bgp
*bgp
, int config
)
207 SET_FLAG(bgp
->config
, config
);
210 static void bgp_config_unset(struct bgp
*bgp
, int config
)
212 UNSET_FLAG(bgp
->config
, config
);
215 static int bgp_config_check(struct bgp
*bgp
, int config
)
217 return CHECK_FLAG(bgp
->config
, config
);
220 /* Set BGP router identifier; distinguish between explicit config and other
223 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
,
227 struct listnode
*node
, *nnode
;
229 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
232 /* EVPN uses router id in RD, withdraw them */
233 if (is_evpn_enabled())
234 bgp_evpn_handle_router_id_update(bgp
, true);
236 vpn_handle_router_id_update(bgp
, true, is_config
);
238 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
240 /* Set all peer's local identifier with this value. */
241 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
242 IPV4_ADDR_COPY(&peer
->local_id
, id
);
244 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
245 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
246 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
247 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
251 /* EVPN uses router id in RD, update them */
252 if (is_evpn_enabled())
253 bgp_evpn_handle_router_id_update(bgp
, false);
255 vpn_handle_router_id_update(bgp
, false, is_config
);
260 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
262 struct listnode
*node
, *nnode
;
264 struct in_addr
*addr
= NULL
;
266 if (router_id
!= NULL
)
267 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
269 if (vrf_id
== VRF_DEFAULT
) {
270 /* Router-id change for default VRF has to also update all
272 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
273 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
277 bgp
->router_id_zebra
= *addr
;
279 addr
= &bgp
->router_id_zebra
;
281 if (!bgp
->router_id_static
.s_addr
) {
282 /* Router ID is updated if there are no active
285 if (bgp
->established_peers
== 0) {
286 if (BGP_DEBUG(zebra
, ZEBRA
))
288 "RID change : vrf %s(%u), RTR ID %s",
292 bgp_router_id_set(bgp
, addr
, false);
297 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
300 bgp
->router_id_zebra
= *addr
;
302 addr
= &bgp
->router_id_zebra
;
304 if (!bgp
->router_id_static
.s_addr
) {
305 /* Router ID is updated if there are no active
308 if (bgp
->established_peers
== 0) {
309 if (BGP_DEBUG(zebra
, ZEBRA
))
311 "RID change : vrf %s(%u), RTR ID %s",
315 bgp_router_id_set(bgp
, addr
, false);
323 void bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
325 bgp
->router_id_static
= id
;
326 bgp_router_id_set(bgp
,
327 id
.s_addr
!= INADDR_ANY
? &id
: &bgp
->router_id_zebra
,
328 true /* is config */);
331 /* BGP's cluster-id control. */
332 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
335 struct listnode
*node
, *nnode
;
337 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
338 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
341 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
342 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
344 /* Clear all IBGP peer. */
345 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
346 if (peer
->sort
!= BGP_PEER_IBGP
)
349 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
350 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
351 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
352 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
358 int bgp_cluster_id_unset(struct bgp
*bgp
)
361 struct listnode
*node
, *nnode
;
363 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
366 bgp
->cluster_id
.s_addr
= 0;
367 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
369 /* Clear all IBGP peer. */
370 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
371 if (peer
->sort
!= BGP_PEER_IBGP
)
374 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
375 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
376 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
377 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
383 /* time_t value that is monotonicly increasing
384 * and uneffected by adjustments to system clock
386 time_t bgp_clock(void)
394 /* BGP timer configuration. */
395 void bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
,
396 uint32_t connect_retry
)
398 bgp
->default_keepalive
=
399 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
400 bgp
->default_holdtime
= holdtime
;
401 bgp
->default_connect_retry
= connect_retry
;
404 /* mostly for completeness - CLI uses its own defaults */
405 void bgp_timers_unset(struct bgp
*bgp
)
407 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
408 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
409 bgp
->default_connect_retry
= BGP_DEFAULT_CONNECT_RETRY
;
412 /* BGP confederation configuration. */
413 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
416 struct listnode
*node
, *nnode
;
420 return BGP_ERR_INVALID_AS
;
422 /* Remember - were we doing confederation before? */
423 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
425 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
427 /* If we were doing confederation already, this is just an external
428 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
429 were not doing confederation before, reset all EBGP sessions. */
430 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
431 bgp_peer_sort_t ptype
= peer_sort(peer
);
433 /* We're looking for peers who's AS is not local or part of our
435 if (already_confed
) {
436 if (ptype
== BGP_PEER_EBGP
) {
438 if (BGP_IS_VALID_STATE_FOR_NOTIF(
441 PEER_DOWN_CONFED_ID_CHANGE
;
443 peer
, BGP_NOTIFY_CEASE
,
444 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
446 bgp_session_reset_safe(peer
, &nnode
);
449 /* Not doign confederation before, so reset every
452 if (ptype
!= BGP_PEER_IBGP
) {
453 /* Reset the local_as to be our EBGP one */
454 if (ptype
== BGP_PEER_EBGP
)
456 if (BGP_IS_VALID_STATE_FOR_NOTIF(
459 PEER_DOWN_CONFED_ID_CHANGE
;
461 peer
, BGP_NOTIFY_CEASE
,
462 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
464 bgp_session_reset_safe(peer
, &nnode
);
471 int bgp_confederation_id_unset(struct bgp
*bgp
)
474 struct listnode
*node
, *nnode
;
477 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
479 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
480 /* We're looking for peers who's AS is not local */
481 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
482 peer
->local_as
= bgp
->as
;
483 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
484 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
485 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
486 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
490 bgp_session_reset_safe(peer
, &nnode
);
496 /* Is an AS part of the confed or not? */
497 bool bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
504 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
505 if (bgp
->confed_peers
[i
] == as
)
511 /* Add an AS to the confederation set. */
512 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
515 struct listnode
*node
, *nnode
;
518 return BGP_ERR_INVALID_BGP
;
521 return BGP_ERR_INVALID_AS
;
523 if (bgp_confederation_peers_check(bgp
, as
))
526 if (bgp
->confed_peers
)
528 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
529 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
532 XMALLOC(MTYPE_BGP_CONFED_LIST
,
533 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
535 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
536 bgp
->confed_peers_cnt
++;
538 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
539 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
540 if (peer
->as
== as
) {
541 peer
->local_as
= bgp
->as
;
542 if (BGP_IS_VALID_STATE_FOR_NOTIF(
545 PEER_DOWN_CONFED_PEER_CHANGE
;
547 peer
, BGP_NOTIFY_CEASE
,
548 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
550 bgp_session_reset_safe(peer
, &nnode
);
557 /* Delete an AS from the confederation set. */
558 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
563 struct listnode
*node
, *nnode
;
568 if (!bgp_confederation_peers_check(bgp
, as
))
571 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
572 if (bgp
->confed_peers
[i
] == as
)
573 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
574 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
576 bgp
->confed_peers_cnt
--;
578 if (bgp
->confed_peers_cnt
== 0) {
579 if (bgp
->confed_peers
)
580 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
581 bgp
->confed_peers
= NULL
;
584 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
585 bgp
->confed_peers_cnt
* sizeof(as_t
));
587 /* Now reset any peer who's remote AS has just been removed from the
589 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
590 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
591 if (peer
->as
== as
) {
592 peer
->local_as
= bgp
->confed_id
;
593 if (BGP_IS_VALID_STATE_FOR_NOTIF(
596 PEER_DOWN_CONFED_PEER_CHANGE
;
598 peer
, BGP_NOTIFY_CEASE
,
599 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
601 bgp_session_reset_safe(peer
, &nnode
);
609 /* Local preference configuration. */
610 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
615 bgp
->default_local_pref
= local_pref
;
620 int bgp_default_local_preference_unset(struct bgp
*bgp
)
625 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
630 /* Local preference configuration. */
631 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
636 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
641 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
645 bgp
->default_subgroup_pkt_queue_max
=
646 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
651 /* Listen limit configuration. */
652 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
657 bgp
->dynamic_neighbors_limit
= listen_limit
;
662 int bgp_listen_limit_unset(struct bgp
*bgp
)
667 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
672 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
673 afi_t
*afi
, safi_t
*safi
)
675 /* Map from IANA values to internal values, return error if
676 * values are unrecognized.
678 *afi
= afi_iana2int(pkt_afi
);
679 *safi
= safi_iana2int(pkt_safi
);
680 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
686 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
687 iana_safi_t
*pkt_safi
)
689 /* Map from internal values to IANA values, return error if
690 * internal values are bad (unexpected).
692 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
694 *pkt_afi
= afi_int2iana(afi
);
695 *pkt_safi
= safi_int2iana(safi
);
699 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
708 afid
= afindex(afi
, safi
);
709 if (afid
>= BGP_AF_MAX
)
713 assert(peer
->peer_af_array
[afid
] == NULL
);
715 /* Allocate new peer af */
716 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
718 peer
->peer_af_array
[afid
] = af
;
723 bgp
->af_peer_count
[afi
][safi
]++;
728 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
735 afid
= afindex(afi
, safi
);
736 if (afid
>= BGP_AF_MAX
)
739 return peer
->peer_af_array
[afid
];
742 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
751 afid
= afindex(afi
, safi
);
752 if (afid
>= BGP_AF_MAX
)
755 af
= peer
->peer_af_array
[afid
];
760 bgp_stop_announce_route_timer(af
);
762 if (PAF_SUBGRP(af
)) {
763 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
764 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
765 af
->subgroup
->update_group
->id
,
766 af
->subgroup
->id
, peer
->host
);
770 update_subgroup_remove_peer(af
->subgroup
, af
);
772 if (bgp
->af_peer_count
[afi
][safi
])
773 bgp
->af_peer_count
[afi
][safi
]--;
775 peer
->peer_af_array
[afid
] = NULL
;
776 XFREE(MTYPE_BGP_PEER_AF
, af
);
780 /* Peer comparison function for sorting. */
781 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
783 if (p1
->group
&& !p2
->group
)
786 if (!p1
->group
&& p2
->group
)
789 if (p1
->group
== p2
->group
) {
790 if (p1
->conf_if
&& !p2
->conf_if
)
793 if (!p1
->conf_if
&& p2
->conf_if
)
796 if (p1
->conf_if
&& p2
->conf_if
)
797 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
799 return strcmp(p1
->group
->name
, p2
->group
->name
);
801 return sockunion_cmp(&p1
->su
, &p2
->su
);
804 static unsigned int peer_hash_key_make(const void *p
)
806 const struct peer
*peer
= p
;
807 return sockunion_hash(&peer
->su
);
810 static bool peer_hash_same(const void *p1
, const void *p2
)
812 const struct peer
*peer1
= p1
;
813 const struct peer
*peer2
= p2
;
814 return (sockunion_same(&peer1
->su
, &peer2
->su
)
815 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
816 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
819 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
823 /* Skip if peer is not a peer-group member. */
824 if (!peer_group_active(peer
))
827 /* Unset override flag to signal inheritance from peer-group. */
828 UNSET_FLAG(peer
->flags_override
, flag
);
831 * Inherit flag state from peer-group. If the flag of the peer-group is
832 * not being inverted, the peer must inherit the inverse of the current
833 * peer-group flag state.
835 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
836 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
837 && CHECK_FLAG(peer
->flags_invert
, flag
))
838 COND_FLAG(peer
->flags
, flag
, !group_val
);
840 COND_FLAG(peer
->flags
, flag
, group_val
);
843 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
845 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
848 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
853 /* Skip if peer is not a peer-group member. */
854 if (!peer_group_active(peer
))
857 /* Unset override flag to signal inheritance from peer-group. */
858 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
861 * Inherit flag state from peer-group. If the flag of the peer-group is
862 * not being inverted, the peer must inherit the inverse of the current
863 * peer-group flag state.
865 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
866 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
867 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
868 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
870 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
873 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
874 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
881 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
882 if (peer
->as_type
== AS_INTERNAL
)
883 return BGP_PEER_IBGP
;
885 else if (peer
->as_type
== AS_EXTERNAL
)
886 return BGP_PEER_EBGP
;
888 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
890 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
898 peer1
= listnode_head(peer
->group
->peer
);
903 return BGP_PEER_INTERNAL
;
907 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
908 if (peer
->local_as
== 0)
909 return BGP_PEER_INTERNAL
;
911 if (peer
->local_as
== peer
->as
) {
912 if (bgp
->as
== bgp
->confed_id
) {
913 if (peer
->local_as
== bgp
->as
)
914 return BGP_PEER_IBGP
;
916 return BGP_PEER_EBGP
;
918 if (peer
->local_as
== bgp
->confed_id
)
919 return BGP_PEER_EBGP
;
921 return BGP_PEER_IBGP
;
925 if (bgp_confederation_peers_check(bgp
, peer
->as
))
926 return BGP_PEER_CONFED
;
928 return BGP_PEER_EBGP
;
930 if (peer
->as_type
== AS_UNSPECIFIED
) {
931 /* check if in peer-group with AS information */
933 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
934 if (peer
->group
->conf
->as_type
937 == peer
->group
->conf
->as
)
938 return BGP_PEER_IBGP
;
940 return BGP_PEER_EBGP
;
941 } else if (peer
->group
->conf
->as_type
943 return BGP_PEER_IBGP
;
945 return BGP_PEER_EBGP
;
947 /* no AS information anywhere, let caller know */
948 return BGP_PEER_UNSPECIFIED
;
949 } else if (peer
->as_type
!= AS_SPECIFIED
)
950 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
953 return (peer
->local_as
== 0
955 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
960 /* Calculate and cache the peer "sort" */
961 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
963 peer
->sort
= peer_calc_sort(peer
);
967 bgp_peer_sort_t
peer_sort_lookup(struct peer
*peer
)
972 static void peer_free(struct peer
*peer
)
977 assert(peer
->status
== Deleted
);
981 /* this /ought/ to have been done already through bgp_stop earlier,
982 * but just to be sure..
986 bgp_writes_off(peer
);
987 assert(!peer
->t_write
);
988 assert(!peer
->t_read
);
989 BGP_EVENT_FLUSH(peer
);
991 pthread_mutex_destroy(&peer
->io_mtx
);
993 /* Free connected nexthop, if present */
994 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
995 && !peer_dynamic_neighbor(peer
))
996 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
999 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1001 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1002 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1003 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1004 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1006 /* Update source configuration. */
1007 if (peer
->update_source
) {
1008 sockunion_free(peer
->update_source
);
1009 peer
->update_source
= NULL
;
1012 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1014 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1015 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1017 if (peer
->clear_node_queue
)
1018 work_queue_free_and_null(&peer
->clear_node_queue
);
1020 bgp_sync_delete(peer
);
1022 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1024 bfd_info_free(&(peer
->bfd_info
));
1026 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1027 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1028 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1033 bgp_unlock(peer
->bgp
);
1035 memset(peer
, 0, sizeof(struct peer
));
1037 XFREE(MTYPE_BGP_PEER
, peer
);
1040 /* increase reference count on a struct peer */
1041 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1043 assert(peer
&& (peer
->lock
>= 0));
1046 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1054 /* decrease reference count on a struct peer
1055 * struct peer is freed and NULL returned if last reference
1057 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1059 assert(peer
&& (peer
->lock
> 0));
1062 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1067 if (peer
->lock
== 0) {
1074 /* BGP GR changes */
1076 int bgp_global_gr_init(struct bgp
*bgp
)
1078 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
1079 zlog_debug("%s called ..", __func__
);
1081 int local_GLOBAL_GR_FSM
[BGP_GLOBAL_GR_MODE
][BGP_GLOBAL_GR_EVENT_CMD
] = {
1082 /* GLOBAL_HELPER Mode */
1085 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1086 GLOBAL_GR
, GLOBAL_INVALID
,
1087 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1088 GLOBAL_DISABLE
, GLOBAL_INVALID
1090 /* GLOBAL_GR Mode */
1093 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1094 GLOBAL_INVALID
, GLOBAL_HELPER
,
1095 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1096 GLOBAL_DISABLE
, GLOBAL_INVALID
1098 /* GLOBAL_DISABLE Mode */
1101 /*GLOBAL_GR_cmd */ /*no_Global_GR_cmd*/
1102 GLOBAL_GR
, GLOBAL_INVALID
,
1103 /*GLOBAL_DISABLE_cmd*//*no_Global_Disable_cmd*/
1104 GLOBAL_INVALID
, GLOBAL_HELPER
1106 /* GLOBAL_INVALID Mode */
1109 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1110 GLOBAL_INVALID
, GLOBAL_INVALID
,
1111 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1112 GLOBAL_INVALID
, GLOBAL_INVALID
1115 memcpy(bgp
->GLOBAL_GR_FSM
, local_GLOBAL_GR_FSM
,
1116 sizeof(local_GLOBAL_GR_FSM
));
1118 bgp
->global_gr_present_state
= GLOBAL_HELPER
;
1119 bgp
->present_zebra_gr_state
= ZEBRA_GR_DISABLE
;
1121 return BGP_GR_SUCCESS
;
1124 int bgp_peer_gr_init(struct peer
*peer
)
1126 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
1127 zlog_debug("%s called ..", __func__
);
1129 struct bgp_peer_gr local_Peer_GR_FSM
[BGP_PEER_GR_MODE
]
1130 [BGP_PEER_GR_EVENT_CMD
] = {
1132 /* PEER_HELPER Mode */
1133 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1134 { PEER_GR
, bgp_peer_gr_action
}, {PEER_INVALID
, NULL
},
1135 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1136 {PEER_DISABLE
, bgp_peer_gr_action
}, {PEER_INVALID
, NULL
},
1137 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1138 { PEER_INVALID
, NULL
}, {PEER_GLOBAL_INHERIT
,
1139 bgp_peer_gr_action
}
1143 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1144 { PEER_INVALID
, NULL
}, { PEER_GLOBAL_INHERIT
,
1145 bgp_peer_gr_action
},
1146 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1147 {PEER_DISABLE
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1148 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1149 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1152 /* PEER_DISABLE Mode */
1153 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1154 { PEER_GR
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1155 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1156 { PEER_INVALID
, NULL
}, { PEER_GLOBAL_INHERIT
,
1157 bgp_peer_gr_action
},
1158 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1159 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1162 /* PEER_INVALID Mode */
1163 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1164 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1165 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1166 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1167 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1168 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1171 /* PEER_GLOBAL_INHERIT Mode */
1172 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1173 { PEER_GR
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1174 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1175 { PEER_DISABLE
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1176 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1177 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1180 memcpy(&peer
->PEER_GR_FSM
, local_Peer_GR_FSM
,
1181 sizeof(local_Peer_GR_FSM
));
1182 peer
->peer_gr_present_state
= PEER_GLOBAL_INHERIT
;
1183 bgp_peer_move_to_gr_mode(peer
, PEER_GLOBAL_INHERIT
);
1185 return BGP_GR_SUCCESS
;
1188 /* Allocate new peer object, implicitely locked. */
1189 struct peer
*peer_new(struct bgp
*bgp
)
1196 /* bgp argument is absolutely required */
1199 /* Allocate new peer. */
1200 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1202 /* Set default value. */
1204 peer
->v_start
= BGP_INIT_START_TIMER
;
1205 peer
->v_connect
= bgp
->default_connect_retry
;
1206 peer
->status
= Idle
;
1207 peer
->ostatus
= Idle
;
1208 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1209 peer
->bgp
= bgp_lock(bgp
);
1210 peer
= peer_lock(peer
); /* initial reference */
1211 peer
->password
= NULL
;
1213 /* Set default flags. */
1214 FOREACH_AFI_SAFI (afi
, safi
) {
1215 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
1216 SET_FLAG(peer
->af_flags
[afi
][safi
],
1217 PEER_FLAG_SEND_EXT_COMMUNITY
);
1218 SET_FLAG(peer
->af_flags
[afi
][safi
],
1219 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1221 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1222 PEER_FLAG_SEND_COMMUNITY
);
1223 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1224 PEER_FLAG_SEND_EXT_COMMUNITY
);
1225 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1226 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1227 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1230 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1232 /* Initialize per peer bgp GR FSM */
1233 bgp_peer_gr_init(peer
);
1235 /* Create buffers. */
1236 peer
->ibuf
= stream_fifo_new();
1237 peer
->obuf
= stream_fifo_new();
1238 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1240 /* We use a larger buffer for peer->obuf_work in the event that:
1241 * - We RX a BGP_UPDATE where the attributes alone are just
1242 * under BGP_MAX_PACKET_SIZE
1243 * - The user configures an outbound route-map that does many as-path
1244 * prepends or adds many communities. At most they can have
1245 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1246 * large they can make the attributes.
1248 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1249 * bounds checking for every single attribute as we construct an
1253 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1255 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1257 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1259 bgp_sync_init(peer
);
1261 /* Get service port number. */
1262 sp
= getservbyname("bgp", "tcp");
1263 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1265 QOBJ_REG(peer
, peer
);
1270 * This function is invoked when a duplicate peer structure associated with
1271 * a neighbor is being deleted. If this about-to-be-deleted structure is
1272 * the one with all the config, then we have to copy over the info.
1274 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1276 struct peer_af
*paf
;
1284 /* The following function is used by both peer group config copy to
1285 * individual peer and when we transfer config
1287 if (peer_src
->change_local_as
)
1288 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1290 /* peer flags apply */
1291 peer_dst
->flags
= peer_src
->flags
;
1292 peer_dst
->cap
= peer_src
->cap
;
1294 peer_dst
->peer_gr_present_state
= peer_src
->peer_gr_present_state
;
1295 peer_dst
->peer_gr_new_status_flag
= peer_src
->peer_gr_new_status_flag
;
1297 peer_dst
->local_as
= peer_src
->local_as
;
1298 peer_dst
->port
= peer_src
->port
;
1299 (void)peer_sort(peer_dst
);
1300 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1303 peer_dst
->holdtime
= peer_src
->holdtime
;
1304 peer_dst
->keepalive
= peer_src
->keepalive
;
1305 peer_dst
->connect
= peer_src
->connect
;
1306 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1307 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1308 peer_dst
->routeadv
= peer_src
->routeadv
;
1309 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1311 /* password apply */
1312 if (peer_src
->password
&& !peer_dst
->password
)
1313 peer_dst
->password
=
1314 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1316 FOREACH_AFI_SAFI (afi
, safi
) {
1317 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1318 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1319 peer_dst
->allowas_in
[afi
][safi
] =
1320 peer_src
->allowas_in
[afi
][safi
];
1321 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1322 peer_dst
->addpath_type
[afi
][safi
] =
1323 peer_src
->addpath_type
[afi
][safi
];
1326 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1327 paf
= peer_src
->peer_af_array
[afidx
];
1329 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1332 /* update-source apply */
1333 if (peer_src
->update_source
) {
1334 if (peer_dst
->update_source
)
1335 sockunion_free(peer_dst
->update_source
);
1336 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1337 peer_dst
->update_source
=
1338 sockunion_dup(peer_src
->update_source
);
1339 } else if (peer_src
->update_if
) {
1340 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1341 if (peer_dst
->update_source
) {
1342 sockunion_free(peer_dst
->update_source
);
1343 peer_dst
->update_source
= NULL
;
1345 peer_dst
->update_if
=
1346 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1349 if (peer_src
->ifname
) {
1350 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1353 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1357 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1358 struct interface
*ifp
)
1360 struct connected
*ifc
;
1363 struct listnode
*node
;
1365 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1366 * IPv4 address of the other end.
1368 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1369 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1370 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1371 if (p
.prefixlen
== 30) {
1372 peer
->su
.sa
.sa_family
= AF_INET
;
1373 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1375 peer
->su
.sin
.sin_addr
.s_addr
=
1377 else if (addr
% 4 == 2)
1378 peer
->su
.sin
.sin_addr
.s_addr
=
1380 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1381 peer
->su
.sin
.sin_len
=
1382 sizeof(struct sockaddr_in
);
1383 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1385 } else if (p
.prefixlen
== 31) {
1386 peer
->su
.sa
.sa_family
= AF_INET
;
1387 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1389 peer
->su
.sin
.sin_addr
.s_addr
=
1392 peer
->su
.sin
.sin_addr
.s_addr
=
1394 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1395 peer
->su
.sin
.sin_len
=
1396 sizeof(struct sockaddr_in
);
1397 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1399 } else if (bgp_debug_neighbor_events(peer
))
1401 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1409 static bool bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1410 struct interface
*ifp
)
1412 struct nbr_connected
*ifc_nbr
;
1414 /* Have we learnt the peer's IPv6 link-local address? */
1415 if (ifp
->nbr_connected
1416 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1417 peer
->su
.sa
.sa_family
= AF_INET6
;
1418 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1419 sizeof(struct in6_addr
));
1421 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1423 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1431 * Set or reset the peer address socketunion structure based on the
1432 * learnt/derived peer address. If the address has changed, update the
1433 * password on the listen socket, if needed.
1435 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1437 struct interface
*ifp
;
1439 int peer_addr_updated
= 0;
1445 * Our peer structure is stored in the bgp->peerhash
1446 * release it before we modify anything.
1448 hash_release(peer
->bgp
->peerhash
, peer
);
1450 prev_family
= peer
->su
.sa
.sa_family
;
1451 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1453 /* If BGP unnumbered is not "v6only", we first see if we can
1455 * peer's IPv4 address.
1457 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1459 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1461 /* If "v6only" or we can't derive peer's IPv4 address, see if
1463 * learnt the peer's IPv6 link-local address. This is from the
1465 * IPv6 address in router advertisement.
1467 if (!peer_addr_updated
)
1469 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1471 /* If we could derive the peer address, we may need to install the
1473 * configured for the peer, if any, on the listen socket. Otherwise,
1475 * that peer's address is not available and uninstall the password, if
1478 if (peer_addr_updated
) {
1479 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1480 && prev_family
== AF_UNSPEC
)
1483 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1484 && prev_family
!= AF_UNSPEC
)
1485 bgp_md5_unset(peer
);
1486 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1487 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1491 * Since our su changed we need to del/add peer to the peerhash
1493 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1496 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1499 struct bgp_dest
*dest
, *ndest
;
1500 struct bgp_table
*table
;
1502 for (dest
= bgp_table_top(bgp
->rib
[afi
][safi
]); dest
;
1503 dest
= bgp_route_next(dest
)) {
1504 table
= bgp_dest_get_bgp_table_info(dest
);
1505 if (table
!= NULL
) {
1506 /* Special handling for 2-level routing
1508 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1509 || safi
== SAFI_EVPN
) {
1510 for (ndest
= bgp_table_top(table
); ndest
;
1511 ndest
= bgp_route_next(ndest
))
1512 bgp_process(bgp
, ndest
, afi
, safi
);
1514 bgp_process(bgp
, dest
, afi
, safi
);
1519 /* Force a bestpath recalculation for all prefixes. This is used
1520 * when 'bgp bestpath' commands are entered.
1522 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1527 FOREACH_AFI_SAFI (afi
, safi
) {
1528 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1533 * Create new BGP peer.
1535 * conf_if and su are mutually exclusive if configuring from the cli.
1536 * If we are handing a doppelganger, then we *must* pass in both
1537 * the original peer's su and conf_if, so that we can appropriately
1538 * track the bgp->peerhash( ie we don't want to remove the current
1539 * one from the config ).
1541 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1542 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1543 int as_type
, afi_t afi
, safi_t safi
,
1544 struct peer_group
*group
)
1548 char buf
[SU_ADDRSTRLEN
];
1550 peer
= peer_new(bgp
);
1552 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1556 bgp_peer_conf_if_to_su_update(peer
);
1557 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1558 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1561 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1562 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1563 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1565 peer
->local_as
= local_as
;
1566 peer
->as
= remote_as
;
1567 peer
->as_type
= as_type
;
1568 peer
->local_id
= bgp
->router_id
;
1569 peer
->v_holdtime
= bgp
->default_holdtime
;
1570 peer
->v_keepalive
= bgp
->default_keepalive
;
1571 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1572 ? BGP_DEFAULT_IBGP_ROUTEADV
1573 : BGP_DEFAULT_EBGP_ROUTEADV
;
1575 peer
= peer_lock(peer
); /* bgp peer list reference */
1576 peer
->group
= group
;
1577 listnode_add_sort(bgp
->peer
, peer
);
1578 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1580 /* Adjust update-group coalesce timer heuristics for # peers. */
1581 if (bgp
->heuristic_coalesce
) {
1582 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1584 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1585 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1588 active
= peer_active(peer
);
1590 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
)
1591 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1593 peer
->last_reset
= PEER_DOWN_NOAFI_ACTIVATED
;
1596 /* Last read and reset time set */
1597 peer
->readtime
= peer
->resettime
= bgp_clock();
1599 /* Default TTL set. */
1600 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: BGP_DEFAULT_TTL
;
1602 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1605 peer
->afc
[afi
][safi
] = 1;
1606 peer_af_create(peer
, afi
, safi
);
1609 /* auto shutdown if configured */
1610 if (bgp
->autoshutdown
)
1611 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1612 /* Set up peer's events and timers. */
1613 else if (!active
&& peer_active(peer
))
1614 bgp_timer_set(peer
);
1616 bgp_peer_gr_flags_update(peer
);
1617 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp
, bgp
->peer
);
1622 /* Make accept BGP peer. This function is only called from the test code */
1623 struct peer
*peer_create_accept(struct bgp
*bgp
)
1627 peer
= peer_new(bgp
);
1629 peer
= peer_lock(peer
); /* bgp peer list reference */
1630 listnode_add_sort(bgp
->peer
, peer
);
1636 * Return true if we have a peer configured to use this afi/safi
1638 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1640 struct listnode
*node
;
1643 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1644 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1647 if (peer
->afc
[afi
][safi
])
1654 /* Change peer's AS number. */
1655 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1657 bgp_peer_sort_t origtype
, newtype
;
1660 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1661 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1662 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1663 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1664 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1666 bgp_session_reset(peer
);
1668 origtype
= peer_sort_lookup(peer
);
1670 peer
->as_type
= as_specified
;
1672 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1673 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1674 && peer
->bgp
->as
!= as
)
1675 peer
->local_as
= peer
->bgp
->confed_id
;
1677 peer
->local_as
= peer
->bgp
->as
;
1679 newtype
= peer_sort(peer
);
1680 /* Advertisement-interval reset */
1681 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1682 peer
->v_routeadv
= (newtype
== BGP_PEER_IBGP
)
1683 ? BGP_DEFAULT_IBGP_ROUTEADV
1684 : BGP_DEFAULT_EBGP_ROUTEADV
;
1688 if (newtype
== BGP_PEER_IBGP
)
1690 else if (origtype
== BGP_PEER_IBGP
)
1691 peer
->ttl
= BGP_DEFAULT_TTL
;
1693 /* reflector-client reset */
1694 if (newtype
!= BGP_PEER_IBGP
) {
1695 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1696 PEER_FLAG_REFLECTOR_CLIENT
);
1697 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1698 PEER_FLAG_REFLECTOR_CLIENT
);
1699 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1700 PEER_FLAG_REFLECTOR_CLIENT
);
1701 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1702 PEER_FLAG_REFLECTOR_CLIENT
);
1703 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1704 PEER_FLAG_REFLECTOR_CLIENT
);
1705 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1706 PEER_FLAG_REFLECTOR_CLIENT
);
1707 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1708 PEER_FLAG_REFLECTOR_CLIENT
);
1709 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1710 PEER_FLAG_REFLECTOR_CLIENT
);
1711 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1712 PEER_FLAG_REFLECTOR_CLIENT
);
1713 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1714 PEER_FLAG_REFLECTOR_CLIENT
);
1715 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1716 PEER_FLAG_REFLECTOR_CLIENT
);
1717 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1718 PEER_FLAG_REFLECTOR_CLIENT
);
1719 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1720 PEER_FLAG_REFLECTOR_CLIENT
);
1723 /* local-as reset */
1724 if (newtype
!= BGP_PEER_EBGP
) {
1725 peer
->change_local_as
= 0;
1726 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1727 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1728 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1732 /* If peer does not exist, create new one. If peer already exists,
1733 set AS number to the peer. */
1734 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1735 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1741 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1743 peer
= peer_lookup(bgp
, su
);
1746 /* Not allowed for a dynamic peer. */
1747 if (peer_dynamic_neighbor(peer
)) {
1749 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1752 /* When this peer is a member of peer-group. */
1754 /* peer-group already has AS number/internal/external */
1755 if (peer
->group
->conf
->as
1756 || peer
->group
->conf
->as_type
) {
1757 /* Return peer group's AS number. */
1758 *as
= peer
->group
->conf
->as
;
1759 return BGP_ERR_PEER_GROUP_MEMBER
;
1762 bgp_peer_sort_t peer_sort_type
=
1763 peer_sort(peer
->group
->conf
);
1765 /* Explicit AS numbers used, compare AS numbers */
1766 if (as_type
== AS_SPECIFIED
) {
1767 if (((peer_sort_type
== BGP_PEER_IBGP
)
1768 && (bgp
->as
!= *as
))
1769 || ((peer_sort_type
== BGP_PEER_EBGP
)
1770 && (bgp
->as
== *as
))) {
1772 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1775 /* internal/external used, compare as-types */
1776 if (((peer_sort_type
== BGP_PEER_IBGP
)
1777 && (as_type
!= AS_INTERNAL
))
1778 || ((peer_sort_type
== BGP_PEER_EBGP
)
1779 && (as_type
!= AS_EXTERNAL
))) {
1781 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1786 /* Existing peer's AS number change. */
1787 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1788 || (peer
->as_type
!= as_type
))
1789 peer_as_change(peer
, *as
, as_type
);
1792 return BGP_ERR_NO_INTERFACE_CONFIG
;
1794 /* If the peer is not part of our confederation, and its not an
1795 iBGP peer then spoof the source AS */
1796 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1797 && !bgp_confederation_peers_check(bgp
, *as
)
1799 local_as
= bgp
->confed_id
;
1803 /* If this is IPv4 unicast configuration and "no bgp default
1804 ipv4-unicast" is specified. */
1806 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_DEFAULT_IPV4
)
1807 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1808 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1811 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1818 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1819 struct peer
*peer
, afi_t afi
,
1823 int out
= FILTER_OUT
;
1825 uint32_t pflags_ovrd
;
1826 uint8_t *pfilter_ovrd
;
1830 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1831 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1833 /* peer af_flags apply */
1834 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1835 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1836 ^ peer
->af_flags_invert
[afi
][safi
];
1837 flags_tmp
&= ~pflags_ovrd
;
1839 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1840 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1841 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1842 conf
->af_flags_invert
[afi
][safi
]);
1844 /* maximum-prefix */
1845 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1846 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1847 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1848 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1852 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1853 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1856 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1857 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1859 /* default-originate route-map */
1860 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1861 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1862 MTYPE_ROUTE_MAP_NAME
);
1863 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1866 /* inbound filter apply */
1867 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1868 PEER_STR_ATTR_INHERIT(peer
, group
,
1869 filter
[afi
][safi
].dlist
[in
].name
,
1870 MTYPE_BGP_FILTER_NAME
);
1871 PEER_ATTR_INHERIT(peer
, group
,
1872 filter
[afi
][safi
].dlist
[in
].alist
);
1875 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1876 PEER_STR_ATTR_INHERIT(peer
, group
,
1877 filter
[afi
][safi
].plist
[in
].name
,
1878 MTYPE_BGP_FILTER_NAME
);
1879 PEER_ATTR_INHERIT(peer
, group
,
1880 filter
[afi
][safi
].plist
[in
].plist
);
1883 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1884 PEER_STR_ATTR_INHERIT(peer
, group
,
1885 filter
[afi
][safi
].aslist
[in
].name
,
1886 MTYPE_BGP_FILTER_NAME
);
1887 PEER_ATTR_INHERIT(peer
, group
,
1888 filter
[afi
][safi
].aslist
[in
].aslist
);
1891 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1892 PEER_STR_ATTR_INHERIT(peer
, group
,
1893 filter
[afi
][safi
].map
[in
].name
,
1894 MTYPE_BGP_FILTER_NAME
);
1895 PEER_ATTR_INHERIT(peer
, group
,
1896 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1899 /* outbound filter apply */
1900 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1901 PEER_STR_ATTR_INHERIT(peer
, group
,
1902 filter
[afi
][safi
].dlist
[out
].name
,
1903 MTYPE_BGP_FILTER_NAME
);
1904 PEER_ATTR_INHERIT(peer
, group
,
1905 filter
[afi
][safi
].dlist
[out
].alist
);
1908 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1909 PEER_STR_ATTR_INHERIT(peer
, group
,
1910 filter
[afi
][safi
].plist
[out
].name
,
1911 MTYPE_BGP_FILTER_NAME
);
1912 PEER_ATTR_INHERIT(peer
, group
,
1913 filter
[afi
][safi
].plist
[out
].plist
);
1916 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1917 PEER_STR_ATTR_INHERIT(peer
, group
,
1918 filter
[afi
][safi
].aslist
[out
].name
,
1919 MTYPE_BGP_FILTER_NAME
);
1920 PEER_ATTR_INHERIT(peer
, group
,
1921 filter
[afi
][safi
].aslist
[out
].aslist
);
1924 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1925 PEER_STR_ATTR_INHERIT(peer
, group
,
1926 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1927 MTYPE_BGP_FILTER_NAME
);
1928 PEER_ATTR_INHERIT(peer
, group
,
1929 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1932 /* nondirectional filter apply */
1933 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1934 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1935 MTYPE_BGP_FILTER_NAME
);
1936 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1939 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1940 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1941 bgp_addpath_type_changed(conf
->bgp
);
1945 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1950 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1951 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1952 __func__
, peer
->host
);
1956 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1958 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1959 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1960 return BGP_ERR_PEER_SAFI_CONFLICT
;
1962 /* Nothing to do if we've already activated this peer */
1963 if (peer
->afc
[afi
][safi
])
1966 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1969 active
= peer_active(peer
);
1970 peer
->afc
[afi
][safi
] = 1;
1973 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1975 if (!active
&& peer_active(peer
)) {
1976 bgp_timer_set(peer
);
1978 if (peer
->status
== Established
) {
1979 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1980 peer
->afc_adv
[afi
][safi
] = 1;
1981 bgp_capability_send(peer
, afi
, safi
,
1983 CAPABILITY_ACTION_SET
);
1984 if (peer
->afc_recv
[afi
][safi
]) {
1985 peer
->afc_nego
[afi
][safi
] = 1;
1986 bgp_announce_route(peer
, afi
, safi
);
1989 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1990 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1991 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1994 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1995 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1996 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1997 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2000 * If we are turning on a AFI/SAFI locally and we've
2001 * started bringing a peer up, we need to tell
2002 * the other peer to restart because we might loose
2003 * configuration here because when the doppelganger
2004 * gets to a established state due to how
2005 * we resolve we could just overwrite the afi/safi
2008 other
= peer
->doppelganger
;
2010 && (other
->status
== OpenSent
2011 || other
->status
== OpenConfirm
)) {
2012 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2013 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
2014 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2021 /* Activate the peer or peer group for specified AFI and SAFI. */
2022 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2025 struct peer_group
*group
;
2026 struct listnode
*node
, *nnode
;
2027 struct peer
*tmp_peer
;
2030 /* Nothing to do if we've already activated this peer */
2031 if (peer
->afc
[afi
][safi
])
2036 /* This is a peer-group so activate all of the members of the
2037 * peer-group as well */
2038 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2040 /* Do not activate a peer for both SAFI_UNICAST and
2041 * SAFI_LABELED_UNICAST */
2042 if ((safi
== SAFI_UNICAST
2043 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2044 || (safi
== SAFI_LABELED_UNICAST
2045 && peer
->afc
[afi
][SAFI_UNICAST
]))
2046 return BGP_ERR_PEER_SAFI_CONFLICT
;
2048 peer
->afc
[afi
][safi
] = 1;
2049 group
= peer
->group
;
2051 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2052 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2055 ret
|= peer_activate_af(peer
, afi
, safi
);
2058 /* If this is the first peer to be activated for this
2059 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2060 if (safi
== SAFI_LABELED_UNICAST
2061 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2063 if (BGP_DEBUG(zebra
, ZEBRA
))
2065 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2067 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2068 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2071 if (safi
== SAFI_FLOWSPEC
) {
2072 /* connect to table manager */
2073 bgp_zebra_init_tm_connect(bgp
);
2078 static bool non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2081 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2082 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2083 __func__
, peer
->host
);
2087 /* Nothing to do if we've already deactivated this peer */
2088 if (!peer
->afc
[afi
][safi
])
2091 /* De-activate the address family configuration. */
2092 peer
->afc
[afi
][safi
] = 0;
2094 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2095 flog_err(EC_BGP_PEER_DELETE
,
2096 "couldn't delete af structure for peer %s(%s, %s)",
2097 peer
->host
, afi2str(afi
), safi2str(safi
));
2101 if (peer
->status
== Established
) {
2102 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2103 peer
->afc_adv
[afi
][safi
] = 0;
2104 peer
->afc_nego
[afi
][safi
] = 0;
2106 if (peer_active_nego(peer
)) {
2107 bgp_capability_send(peer
, afi
, safi
,
2109 CAPABILITY_ACTION_UNSET
);
2110 bgp_clear_route(peer
, afi
, safi
);
2111 peer
->pcount
[afi
][safi
] = 0;
2113 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2114 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2115 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2118 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2119 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2120 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2127 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2130 struct peer_group
*group
;
2131 struct peer
*tmp_peer
;
2132 struct listnode
*node
, *nnode
;
2135 /* Nothing to do if we've already de-activated this peer */
2136 if (!peer
->afc
[afi
][safi
])
2139 /* This is a peer-group so de-activate all of the members of the
2140 * peer-group as well */
2141 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2142 peer
->afc
[afi
][safi
] = 0;
2143 group
= peer
->group
;
2145 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2148 "couldn't delete af structure for peer %s(%s, %s)",
2149 peer
->host
, afi2str(afi
), safi2str(safi
));
2152 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2153 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2156 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2161 /* If this is the last peer to be deactivated for this
2162 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2163 if (safi
== SAFI_LABELED_UNICAST
2164 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2165 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2167 if (BGP_DEBUG(zebra
, ZEBRA
))
2169 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2171 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2172 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2177 void peer_nsf_stop(struct peer
*peer
)
2182 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2183 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2185 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2186 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2187 peer
->nsf
[afi
][safi
] = 0;
2189 if (peer
->t_gr_restart
) {
2190 BGP_TIMER_OFF(peer
->t_gr_restart
);
2191 if (bgp_debug_neighbor_events(peer
))
2192 zlog_debug("%s graceful restart timer stopped",
2195 if (peer
->t_gr_stale
) {
2196 BGP_TIMER_OFF(peer
->t_gr_stale
);
2197 if (bgp_debug_neighbor_events(peer
))
2199 "%s graceful restart stalepath timer stopped",
2202 bgp_clear_route_all(peer
);
2205 /* Delete peer from confguration.
2207 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2208 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2210 * This function /should/ take care to be idempotent, to guard against
2211 * it being called multiple times through stray events that come in
2212 * that happen to result in this function being called again. That
2213 * said, getting here for a "Deleted" peer is a bug in the neighbour
2216 int peer_delete(struct peer
*peer
)
2222 struct bgp_filter
*filter
;
2223 struct listnode
*pn
;
2226 assert(peer
->status
!= Deleted
);
2229 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2231 bgp_keepalives_off(peer
);
2232 bgp_reads_off(peer
);
2233 bgp_writes_off(peer
);
2234 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2235 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2236 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_KEEPALIVES_ON
));
2238 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2239 peer_nsf_stop(peer
);
2241 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2243 bgp_bfd_deregister_peer(peer
);
2245 /* If this peer belongs to peer group, clear up the
2248 if (peer_dynamic_neighbor(peer
))
2249 peer_drop_dynamic_neighbor(peer
);
2251 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2253 peer
); /* group->peer list reference */
2254 list_delete_node(peer
->group
->peer
, pn
);
2259 /* Withdraw all information from routing table. We can not use
2260 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2261 * executed after peer structure is deleted.
2263 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2265 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2267 if (peer
->doppelganger
) {
2268 peer
->doppelganger
->doppelganger
= NULL
;
2269 peer
->doppelganger
= NULL
;
2272 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2273 bgp_fsm_change_status(peer
, Deleted
);
2275 /* Remove from NHT */
2276 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2277 bgp_unlink_nexthop_by_peer(peer
);
2279 /* Password configuration */
2280 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2281 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2283 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2284 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2285 bgp_md5_unset(peer
);
2288 bgp_timer_set(peer
); /* stops all timers for Deleted */
2290 /* Delete from all peer list. */
2291 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2292 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2293 peer_unlock(peer
); /* bgp peer list reference */
2294 list_delete_node(bgp
->peer
, pn
);
2295 hash_release(bgp
->peerhash
, peer
);
2300 stream_fifo_free(peer
->ibuf
);
2305 stream_fifo_free(peer
->obuf
);
2309 if (peer
->ibuf_work
) {
2310 ringbuf_del(peer
->ibuf_work
);
2311 peer
->ibuf_work
= NULL
;
2314 if (peer
->obuf_work
) {
2315 stream_free(peer
->obuf_work
);
2316 peer
->obuf_work
= NULL
;
2319 if (peer
->scratch
) {
2320 stream_free(peer
->scratch
);
2321 peer
->scratch
= NULL
;
2324 /* Local and remote addresses. */
2325 if (peer
->su_local
) {
2326 sockunion_free(peer
->su_local
);
2327 peer
->su_local
= NULL
;
2330 if (peer
->su_remote
) {
2331 sockunion_free(peer
->su_remote
);
2332 peer
->su_remote
= NULL
;
2335 /* Free filter related memory. */
2336 FOREACH_AFI_SAFI (afi
, safi
) {
2337 filter
= &peer
->filter
[afi
][safi
];
2339 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2340 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
2341 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
2342 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
2345 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2346 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
2349 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2350 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
2353 FOREACH_AFI_SAFI (afi
, safi
)
2354 peer_af_delete(peer
, afi
, safi
);
2356 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2357 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2359 peer_unlock(peer
); /* initial reference */
2364 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2366 return strcmp(g1
->name
, g2
->name
);
2369 /* Peer group cofiguration. */
2370 static struct peer_group
*peer_group_new(void)
2372 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2375 static void peer_group_free(struct peer_group
*group
)
2377 XFREE(MTYPE_PEER_GROUP
, group
);
2380 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2382 struct peer_group
*group
;
2383 struct listnode
*node
, *nnode
;
2385 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2386 if (strcmp(group
->name
, name
) == 0)
2392 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2394 struct peer_group
*group
;
2397 group
= peer_group_lookup(bgp
, name
);
2401 group
= peer_group_new();
2403 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2404 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2405 group
->peer
= list_new();
2406 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2407 group
->listen_range
[afi
] = list_new();
2408 group
->conf
= peer_new(bgp
);
2409 if (!CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_DEFAULT_IPV4
))
2410 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2411 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2412 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2413 group
->conf
->group
= group
;
2414 group
->conf
->as
= 0;
2415 group
->conf
->ttl
= BGP_DEFAULT_TTL
;
2416 group
->conf
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
2417 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2418 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2419 listnode_add_sort(bgp
->group
, group
);
2424 static void peer_group2peer_config_copy(struct peer_group
*group
,
2434 peer
->as
= conf
->as
;
2437 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2438 peer
->change_local_as
= conf
->change_local_as
;
2440 /* If peer-group has configured TTL then override it */
2441 if (conf
->ttl
!= BGP_DEFAULT_TTL
)
2442 peer
->ttl
= conf
->ttl
;
2445 peer
->gtsm_hops
= conf
->gtsm_hops
;
2447 /* peer flags apply */
2448 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2449 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2450 flags_tmp
&= ~peer
->flags_override
;
2452 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2453 SET_FLAG(peer
->flags
, flags_tmp
);
2454 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2456 /* peer timers apply */
2457 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2458 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2459 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2462 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2463 PEER_ATTR_INHERIT(peer
, group
, connect
);
2464 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2465 peer
->v_connect
= conf
->connect
;
2467 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
2470 /* advertisement-interval apply */
2471 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2472 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2473 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2474 peer
->v_routeadv
= conf
->routeadv
;
2476 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2477 ? BGP_DEFAULT_IBGP_ROUTEADV
2478 : BGP_DEFAULT_EBGP_ROUTEADV
;
2481 /* capability extended-nexthop apply */
2482 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_CAPABILITY_ENHE
))
2483 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2484 SET_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
);
2486 /* password apply */
2487 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2488 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2489 MTYPE_PEER_PASSWORD
);
2491 if (!BGP_PEER_SU_UNSPEC(peer
))
2494 /* update-source apply */
2495 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2496 if (conf
->update_source
) {
2497 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2498 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2499 } else if (conf
->update_if
) {
2500 sockunion_free(peer
->update_source
);
2501 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2502 MTYPE_PEER_UPDATE_SOURCE
);
2506 /* Update GR flags for the peer. */
2507 bgp_peer_gr_flags_update(peer
);
2509 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2512 /* Peer group's remote AS configuration. */
2513 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2516 struct peer_group
*group
;
2518 struct listnode
*node
, *nnode
;
2520 group
= peer_group_lookup(bgp
, group_name
);
2524 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2528 /* When we setup peer-group AS number all peer group member's AS
2529 number must be updated to same number. */
2530 peer_as_change(group
->conf
, *as
, as_type
);
2532 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2533 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2534 || (peer
->as_type
!= as_type
))
2535 peer_as_change(peer
, *as
, as_type
);
2541 void peer_notify_unconfig(struct peer
*peer
)
2543 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2544 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2545 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
2548 void peer_group_notify_unconfig(struct peer_group
*group
)
2550 struct peer
*peer
, *other
;
2551 struct listnode
*node
, *nnode
;
2553 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2554 other
= peer
->doppelganger
;
2555 if (other
&& other
->status
!= Deleted
) {
2556 other
->group
= NULL
;
2557 peer_notify_unconfig(other
);
2559 peer_notify_unconfig(peer
);
2563 int peer_group_delete(struct peer_group
*group
)
2567 struct prefix
*prefix
;
2569 struct listnode
*node
, *nnode
;
2574 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2575 other
= peer
->doppelganger
;
2577 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2578 bgp_zebra_terminate_radv(bgp
, peer
);
2581 if (other
&& other
->status
!= Deleted
) {
2582 other
->group
= NULL
;
2586 list_delete(&group
->peer
);
2588 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2589 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2591 prefix_free(&prefix
);
2593 list_delete(&group
->listen_range
[afi
]);
2596 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2599 bfd_info_free(&(group
->conf
->bfd_info
));
2601 group
->conf
->group
= NULL
;
2602 peer_delete(group
->conf
);
2604 /* Delete from all peer_group list. */
2605 listnode_delete(bgp
->group
, group
);
2607 peer_group_free(group
);
2612 int peer_group_remote_as_delete(struct peer_group
*group
)
2614 struct peer
*peer
, *other
;
2615 struct listnode
*node
, *nnode
;
2617 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2618 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2621 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2622 other
= peer
->doppelganger
;
2624 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2625 bgp_zebra_terminate_radv(peer
->bgp
, peer
);
2629 if (other
&& other
->status
!= Deleted
) {
2630 other
->group
= NULL
;
2634 list_delete_all_node(group
->peer
);
2636 group
->conf
->as
= 0;
2637 group
->conf
->as_type
= AS_UNSPECIFIED
;
2642 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2644 struct prefix
*prefix
;
2645 struct listnode
*node
, *nnode
;
2648 afi
= family2afi(range
->family
);
2650 /* Group needs remote AS configured. */
2651 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2652 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2654 /* Ensure no duplicates. Currently we don't care about overlaps. */
2655 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2656 if (prefix_same(range
, prefix
))
2660 prefix
= prefix_new();
2661 prefix_copy(prefix
, range
);
2662 listnode_add(group
->listen_range
[afi
], prefix
);
2664 /* Update passwords for new ranges */
2665 if (group
->conf
->password
)
2666 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2671 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2673 struct prefix
*prefix
, prefix2
;
2674 struct listnode
*node
, *nnode
;
2677 char buf
[PREFIX2STR_BUFFER
];
2679 afi
= family2afi(range
->family
);
2681 /* Identify the listen range. */
2682 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2683 if (prefix_same(range
, prefix
))
2688 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2690 prefix2str(prefix
, buf
, sizeof(buf
));
2692 /* Dispose off any dynamic neighbors that exist due to this listen range
2694 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2695 if (!peer_dynamic_neighbor(peer
))
2698 sockunion2hostprefix(&peer
->su
, &prefix2
);
2699 if (prefix_match(prefix
, &prefix2
)) {
2700 if (bgp_debug_neighbor_events(peer
))
2702 "Deleting dynamic neighbor %s group %s upon delete of listen range %s",
2703 peer
->host
, group
->name
, buf
);
2708 /* Get rid of the listen range */
2709 listnode_delete(group
->listen_range
[afi
], prefix
);
2711 /* Remove passwords for deleted ranges */
2712 if (group
->conf
->password
)
2713 bgp_md5_unset_prefix(prefix
);
2718 /* Bind specified peer to peer group. */
2719 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2720 struct peer_group
*group
, as_t
*as
)
2722 int first_member
= 0;
2725 bgp_peer_sort_t ptype
, gtype
;
2727 /* Lookup the peer. */
2729 peer
= peer_lookup(bgp
, su
);
2731 /* The peer exist, bind it to the peer-group */
2733 /* When the peer already belongs to a peer-group, check the
2735 if (peer_group_active(peer
)) {
2737 /* The peer is already bound to the peer-group,
2740 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2743 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2746 /* The peer has not specified a remote-as, inherit it from the
2748 if (peer
->as_type
== AS_UNSPECIFIED
) {
2749 peer
->as_type
= group
->conf
->as_type
;
2750 peer
->as
= group
->conf
->as
;
2751 peer
->sort
= group
->conf
->sort
;
2754 ptype
= peer_sort(peer
);
2755 if (!group
->conf
->as
&& ptype
!= BGP_PEER_UNSPECIFIED
) {
2756 gtype
= peer_sort(group
->conf
);
2757 if ((gtype
!= BGP_PEER_INTERNAL
) && (gtype
!= ptype
)) {
2760 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2763 if (gtype
== BGP_PEER_INTERNAL
)
2767 peer_group2peer_config_copy(group
, peer
);
2769 FOREACH_AFI_SAFI (afi
, safi
) {
2770 if (group
->conf
->afc
[afi
][safi
]) {
2771 peer
->afc
[afi
][safi
] = 1;
2773 if (peer_af_find(peer
, afi
, safi
)
2774 || peer_af_create(peer
, afi
, safi
)) {
2775 peer_group2peer_config_copy_af(
2776 group
, peer
, afi
, safi
);
2778 } else if (peer
->afc
[afi
][safi
])
2779 peer_deactivate(peer
, afi
, safi
);
2783 assert(group
&& peer
->group
== group
);
2785 listnode_delete(bgp
->peer
, peer
);
2787 peer
->group
= group
;
2788 listnode_add_sort(bgp
->peer
, peer
);
2790 peer
= peer_lock(peer
); /* group->peer list reference */
2791 listnode_add(group
->peer
, peer
);
2795 gtype
= peer_sort(group
->conf
);
2796 /* Advertisement-interval reset */
2797 if (!CHECK_FLAG(group
->conf
->flags
,
2798 PEER_FLAG_ROUTEADV
)) {
2799 group
->conf
->v_routeadv
=
2800 (gtype
== BGP_PEER_IBGP
)
2801 ? BGP_DEFAULT_IBGP_ROUTEADV
2802 : BGP_DEFAULT_EBGP_ROUTEADV
;
2805 /* ebgp-multihop reset */
2806 if (gtype
== BGP_PEER_IBGP
)
2807 group
->conf
->ttl
= MAXTTL
;
2809 /* local-as reset */
2810 if (gtype
!= BGP_PEER_EBGP
) {
2811 group
->conf
->change_local_as
= 0;
2812 peer_flag_unset(group
->conf
,
2813 PEER_FLAG_LOCAL_AS
);
2814 peer_flag_unset(group
->conf
,
2815 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2816 peer_flag_unset(group
->conf
,
2817 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2821 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2823 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2824 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2825 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2826 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2828 bgp_session_reset(peer
);
2832 /* Create a new peer. */
2834 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2835 && (!group
->conf
->as
)) {
2836 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2839 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2840 group
->conf
->as_type
, 0, 0, group
);
2842 peer
= peer_lock(peer
); /* group->peer list reference */
2843 listnode_add(group
->peer
, peer
);
2845 peer_group2peer_config_copy(group
, peer
);
2847 /* If the peer-group is active for this afi/safi then activate
2849 FOREACH_AFI_SAFI (afi
, safi
) {
2850 if (group
->conf
->afc
[afi
][safi
]) {
2851 peer
->afc
[afi
][safi
] = 1;
2852 peer_af_create(peer
, afi
, safi
);
2853 peer_group2peer_config_copy_af(group
, peer
, afi
,
2855 } else if (peer
->afc
[afi
][safi
])
2856 peer_deactivate(peer
, afi
, safi
);
2859 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2861 /* Set up peer's events and timers. */
2862 if (peer_active(peer
))
2863 bgp_timer_set(peer
);
2869 static int bgp_startup_timer_expire(struct thread
*thread
)
2873 bgp
= THREAD_ARG(thread
);
2874 bgp
->t_startup
= NULL
;
2880 * On shutdown we call the cleanup function which
2881 * does a free of the link list nodes, free up
2882 * the data we are pointing at too.
2884 static void bgp_vrf_string_name_delete(void *data
)
2888 XFREE(MTYPE_TMP
, vname
);
2891 /* BGP instance creation by `router bgp' commands. */
2892 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2893 enum bgp_instance_type inst_type
)
2899 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2902 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2903 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2904 zlog_debug("Creating Default VRF, AS %u", *as
);
2906 zlog_debug("Creating %s %s, AS %u",
2907 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2913 /* Default the EVPN VRF to the default one */
2914 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
2920 bgp
->heuristic_coalesce
= true;
2921 bgp
->inst_type
= inst_type
;
2922 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2924 bgp
->peer_self
= peer_new(bgp
);
2925 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2926 bgp
->peer_self
->host
=
2927 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2928 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2929 if (cmd_hostname_get())
2930 bgp
->peer_self
->hostname
=
2931 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2933 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2934 if (cmd_domainname_get())
2935 bgp
->peer_self
->domainname
=
2936 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2937 bgp
->peer
= list_new();
2938 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2939 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2941 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2943 bgp
->group
= list_new();
2944 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2946 FOREACH_AFI_SAFI (afi
, safi
) {
2947 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2948 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2949 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2951 /* Enable maximum-paths */
2952 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2954 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2956 /* Initialize graceful restart info */
2957 bgp
->gr_info
[afi
][safi
].eor_required
= 0;
2958 bgp
->gr_info
[afi
][safi
].eor_received
= 0;
2959 bgp
->gr_info
[afi
][safi
].t_select_deferral
= NULL
;
2960 bgp
->gr_info
[afi
][safi
].t_route_select
= NULL
;
2961 bgp
->gr_info
[afi
][safi
].route_list
= list_new();
2964 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2965 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2966 bgp
->default_subgroup_pkt_queue_max
=
2967 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2968 bgp_timers_unset(bgp
);
2969 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2970 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2971 bgp
->select_defer_time
= BGP_DEFAULT_SELECT_DEFERRAL_TIME
;
2972 bgp
->rib_stale_time
= BGP_DEFAULT_RIB_STALE_TIME
;
2973 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2974 bgp
->dynamic_neighbors_count
= 0;
2975 bgp
->lb_ref_bw
= BGP_LINK_BW_REF_BW
;
2976 bgp
->lb_handling
= BGP_LINK_BW_ECMP
;
2977 bgp
->reject_as_sets
= false;
2978 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2982 #ifdef ENABLE_BGP_VNC
2983 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2984 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2986 assert(bgp
->rfapi_cfg
);
2988 #endif /* ENABLE_BGP_VNC */
2990 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2991 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2992 bgp
->vpn_policy
[afi
].afi
= afi
;
2993 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2994 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2997 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2998 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2999 bgp_vrf_string_name_delete
;
3000 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
3001 bgp
->vpn_policy
[afi
].export_vrf
->del
=
3002 bgp_vrf_string_name_delete
;
3005 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
3007 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3008 bgp
->restart_time
, &bgp
->t_startup
);
3010 /* printable name we can use in debug messages */
3011 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3012 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3022 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3024 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3025 snprintf(bgp
->name_pretty
, len
, "%s %s",
3026 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3032 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3033 memory_order_relaxed
);
3034 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3035 memory_order_relaxed
);
3036 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3040 update_bgp_group_init(bgp
);
3042 /* assign a unique rd id for auto derivation of vrf's RD */
3043 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3045 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3046 sizeof(struct bgp_evpn_info
));
3051 /*initilize global GR FSM */
3052 bgp_global_gr_init(bgp
);
3056 /* Return the "default VRF" instance of BGP. */
3057 struct bgp
*bgp_get_default(void)
3060 struct listnode
*node
, *nnode
;
3062 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3063 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3068 /* Lookup BGP entry. */
3069 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3072 struct listnode
*node
, *nnode
;
3074 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3076 && ((bgp
->name
== NULL
&& name
== NULL
)
3077 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3082 /* Lookup BGP structure by view name. */
3083 struct bgp
*bgp_lookup_by_name(const char *name
)
3086 struct listnode
*node
, *nnode
;
3088 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3089 if ((bgp
->name
== NULL
&& name
== NULL
)
3090 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3095 /* Lookup BGP instance based on VRF id. */
3096 /* Note: Only to be used for incoming messages from Zebra. */
3097 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3101 /* Lookup VRF (in tree) and follow link. */
3102 vrf
= vrf_lookup_by_id(vrf_id
);
3105 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3108 /* Sets the BGP instance where EVPN is enabled */
3109 void bgp_set_evpn(struct bgp
*bgp
)
3111 if (bm
->bgp_evpn
== bgp
)
3114 /* First, release the reference count we hold on the instance */
3116 bgp_unlock(bm
->bgp_evpn
);
3120 /* Increase the reference count on this new VRF */
3122 bgp_lock(bm
->bgp_evpn
);
3125 /* Returns the BGP instance where EVPN is enabled, if any */
3126 struct bgp
*bgp_get_evpn(void)
3128 return bm
->bgp_evpn
;
3131 /* handle socket creation or deletion, if necessary
3132 * this is called for all new BGP instances
3134 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3139 /* Create BGP server socket, if listen mode not disabled */
3140 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3142 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3144 * suppress vrf socket
3147 bgp_close_vrf_socket(bgp
);
3151 return BGP_ERR_INVALID_VALUE
;
3153 * if vrf_id did not change
3155 if (vrf
->vrf_id
== old_vrf_id
)
3157 if (old_vrf_id
!= VRF_UNKNOWN
) {
3158 /* look for old socket. close it. */
3159 bgp_close_vrf_socket(bgp
);
3161 /* if backend is not yet identified ( VRF_UNKNOWN) then
3162 * creation will be done later
3164 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3166 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3168 return BGP_ERR_INVALID_VALUE
;
3171 return bgp_check_main_socket(create
, bgp
);
3174 /* Called from VTY commands. */
3175 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3176 enum bgp_instance_type inst_type
)
3179 struct vrf
*vrf
= NULL
;
3181 /* Multiple instance check. */
3183 bgp
= bgp_lookup_by_name(name
);
3185 bgp
= bgp_get_default();
3187 /* Already exists. */
3189 if (bgp
->as
!= *as
) {
3191 return BGP_ERR_INSTANCE_MISMATCH
;
3193 if (bgp
->inst_type
!= inst_type
)
3194 return BGP_ERR_INSTANCE_MISMATCH
;
3199 bgp
= bgp_create(as
, name
, inst_type
);
3200 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3201 bgp
->vrf_id
= vrf_generate_id();
3202 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3203 bgp_address_init(bgp
);
3204 bgp_tip_hash_init(bgp
);
3208 bgp
->t_rmap_def_originate_eval
= NULL
;
3210 /* If Default instance or VRF, link to the VRF structure, if present. */
3211 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3212 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3213 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3215 bgp_vrf_link(bgp
, vrf
);
3217 /* BGP server socket already processed if BGP instance
3218 * already part of the list
3220 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3221 listnode_add(bm
->bgp
, bgp
);
3223 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3224 if (BGP_DEBUG(zebra
, ZEBRA
))
3225 zlog_debug("%s: Registering BGP instance %s to zebra",
3227 bgp_zebra_instance_register(bgp
);
3234 * Make BGP instance "up". Applies only to VRFs (non-default) and
3235 * implies the VRF has been learnt from Zebra.
3237 void bgp_instance_up(struct bgp
*bgp
)
3240 struct listnode
*node
, *next
;
3242 /* Register with zebra. */
3243 bgp_zebra_instance_register(bgp
);
3245 /* Kick off any peers that may have been configured. */
3246 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3247 if (!BGP_PEER_START_SUPPRESSED(peer
))
3248 BGP_EVENT_ADD(peer
, BGP_Start
);
3251 /* Process any networks that have been configured. */
3252 bgp_static_add(bgp
);
3256 * Make BGP instance "down". Applies only to VRFs (non-default) and
3257 * implies the VRF has been deleted by Zebra.
3259 void bgp_instance_down(struct bgp
*bgp
)
3262 struct listnode
*node
;
3263 struct listnode
*next
;
3266 if (bgp
->t_rmap_def_originate_eval
) {
3267 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3268 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3272 /* Bring down peers, so corresponding routes are purged. */
3273 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3274 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3275 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3276 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3278 bgp_session_reset(peer
);
3281 /* Purge network and redistributed routes. */
3282 bgp_purge_static_redist_routes(bgp
);
3284 /* Cleanup registered nexthops (flags) */
3285 bgp_cleanup_nexthops(bgp
);
3288 /* Delete BGP instance. */
3289 int bgp_delete(struct bgp
*bgp
)
3292 struct peer_group
*group
;
3293 struct listnode
*node
, *next
;
3298 struct graceful_restart_info
*gr_info
;
3302 hook_call(bgp_inst_delete
, bgp
);
3304 THREAD_OFF(bgp
->t_startup
);
3305 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3306 THREAD_OFF(bgp
->t_update_delay
);
3307 THREAD_OFF(bgp
->t_establish_wait
);
3309 /* Set flag indicating bgp instance delete in progress */
3310 SET_FLAG(bgp
->flags
, BGP_FLAG_DELETE_IN_PROGRESS
);
3312 /* Delete the graceful restart info */
3313 FOREACH_AFI_SAFI (afi
, safi
) {
3314 gr_info
= &bgp
->gr_info
[afi
][safi
];
3318 BGP_TIMER_OFF(gr_info
->t_select_deferral
);
3319 BGP_TIMER_OFF(gr_info
->t_route_select
);
3320 if (gr_info
->route_list
)
3321 list_delete(&gr_info
->route_list
);
3324 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3325 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3326 zlog_debug("Deleting Default VRF");
3328 zlog_debug("Deleting %s %s",
3329 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3335 /* unmap from RT list */
3336 bgp_evpn_vrf_delete(bgp
);
3338 /* unmap bgp vrf label */
3339 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3340 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3343 if (bgp
->t_rmap_def_originate_eval
) {
3344 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3345 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3349 /* Inform peers we're going down. */
3350 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3351 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3352 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3353 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3356 /* Delete static routes (networks). */
3357 bgp_static_delete(bgp
);
3359 /* Unset redistribution. */
3360 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3361 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3362 if (i
!= ZEBRA_ROUTE_BGP
)
3363 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3365 /* Free peers and peer-groups. */
3366 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3367 peer_group_delete(group
);
3369 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3372 if (bgp
->peer_self
) {
3373 peer_delete(bgp
->peer_self
);
3374 bgp
->peer_self
= NULL
;
3377 update_bgp_group_free(bgp
);
3379 /* TODO - Other memory may need to be freed - e.g., NHT */
3381 #ifdef ENABLE_BGP_VNC
3384 bgp_cleanup_routes(bgp
);
3386 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3387 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3390 &bgp
->vpn_policy
[afi
]
3391 .import_redirect_rtlist
);
3392 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3395 /* Deregister from Zebra, if needed */
3396 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3397 if (BGP_DEBUG(zebra
, ZEBRA
))
3399 "%s: deregistering this bgp %s instance from zebra",
3400 __func__
, bgp
->name
);
3401 bgp_zebra_instance_deregister(bgp
);
3404 /* Remove visibility via the master list - there may however still be
3405 * routes to be processed still referencing the struct bgp.
3407 listnode_delete(bm
->bgp
, bgp
);
3409 /* Free interfaces in this instance. */
3412 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3413 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3415 bgp_vrf_unlink(bgp
, vrf
);
3417 /* Update EVPN VRF pointer */
3418 if (bm
->bgp_evpn
== bgp
) {
3419 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3422 bgp_set_evpn(bgp_get_default());
3425 thread_master_free_unused(bm
->master
);
3426 bgp_unlock(bgp
); /* initial reference */
3431 void bgp_free(struct bgp
*bgp
)
3435 struct bgp_table
*table
;
3436 struct bgp_dest
*dest
;
3437 struct bgp_rmap
*rmap
;
3441 list_delete(&bgp
->group
);
3442 list_delete(&bgp
->peer
);
3444 if (bgp
->peerhash
) {
3445 hash_free(bgp
->peerhash
);
3446 bgp
->peerhash
= NULL
;
3449 FOREACH_AFI_SAFI (afi
, safi
) {
3450 /* Special handling for 2-level routing tables. */
3451 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3452 || safi
== SAFI_EVPN
) {
3453 for (dest
= bgp_table_top(bgp
->rib
[afi
][safi
]); dest
;
3454 dest
= bgp_route_next(dest
)) {
3455 table
= bgp_dest_get_bgp_table_info(dest
);
3456 bgp_table_finish(&table
);
3459 if (bgp
->route
[afi
][safi
])
3460 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3461 if (bgp
->aggregate
[afi
][safi
])
3462 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3463 if (bgp
->rib
[afi
][safi
])
3464 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3465 rmap
= &bgp
->table_map
[afi
][safi
];
3466 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3469 bgp_scan_finish(bgp
);
3470 bgp_address_destroy(bgp
);
3471 bgp_tip_hash_destroy(bgp
);
3473 /* release the auto RD id */
3474 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3476 bgp_evpn_cleanup(bgp
);
3477 bgp_pbr_cleanup(bgp
);
3478 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3480 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3481 vpn_policy_direction_t dir
;
3483 if (bgp
->vpn_policy
[afi
].import_vrf
)
3484 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3485 if (bgp
->vpn_policy
[afi
].export_vrf
)
3486 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3488 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3489 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3490 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3491 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3492 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3493 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3496 XFREE(MTYPE_BGP
, bgp
->name
);
3497 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3499 XFREE(MTYPE_BGP
, bgp
);
3502 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3505 struct listnode
*node
, *nnode
;
3511 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3512 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3513 && !CHECK_FLAG(peer
->sflags
,
3514 PEER_STATUS_ACCEPT_PEER
))
3516 } else if (bm
->bgp
!= NULL
) {
3517 struct listnode
*bgpnode
, *nbgpnode
;
3519 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3520 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3522 && !strcmp(peer
->conf_if
, conf_if
)
3523 && !CHECK_FLAG(peer
->sflags
,
3524 PEER_STATUS_ACCEPT_PEER
))
3530 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3533 struct listnode
*node
, *nnode
;
3539 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3540 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3541 && !CHECK_FLAG(peer
->sflags
,
3542 PEER_STATUS_ACCEPT_PEER
))
3544 } else if (bm
->bgp
!= NULL
) {
3545 struct listnode
*bgpnode
, *nbgpnode
;
3547 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3548 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3550 && !strcmp(peer
->hostname
, hostname
)
3551 && !CHECK_FLAG(peer
->sflags
,
3552 PEER_STATUS_ACCEPT_PEER
))
3558 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3560 struct peer
*peer
= NULL
;
3561 struct peer tmp_peer
;
3563 memset(&tmp_peer
, 0, sizeof(struct peer
));
3566 * We do not want to find the doppelganger peer so search for the peer
3568 * the hash that has PEER_FLAG_CONFIG_NODE
3570 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3575 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3576 } else if (bm
->bgp
!= NULL
) {
3577 struct listnode
*bgpnode
, *nbgpnode
;
3579 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3580 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3589 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3590 union sockunion
*su
,
3591 struct peer_group
*group
)
3597 /* Create peer first; we've already checked group config is valid. */
3598 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3599 group
->conf
->as_type
, 0, 0, group
);
3604 peer
= peer_lock(peer
);
3605 listnode_add(group
->peer
, peer
);
3607 peer_group2peer_config_copy(group
, peer
);
3610 * Bind peer for all AFs configured for the group. We don't call
3611 * peer_group_bind as that is sub-optimal and does some stuff we don't
3614 FOREACH_AFI_SAFI (afi
, safi
) {
3615 if (!group
->conf
->afc
[afi
][safi
])
3617 peer
->afc
[afi
][safi
] = 1;
3619 if (!peer_af_find(peer
, afi
, safi
))
3620 peer_af_create(peer
, afi
, safi
);
3622 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3625 /* Mark as dynamic, but also as a "config node" for other things to
3627 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3628 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3634 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3635 struct prefix
*prefix
)
3637 struct listnode
*node
, *nnode
;
3638 struct prefix
*range
;
3641 afi
= family2afi(prefix
->family
);
3643 if (group
->listen_range
[afi
])
3644 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3646 if (prefix_match(range
, prefix
))
3653 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3654 struct prefix
**listen_range
)
3656 struct prefix
*range
= NULL
;
3657 struct peer_group
*group
= NULL
;
3658 struct listnode
*node
, *nnode
;
3660 *listen_range
= NULL
;
3662 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3663 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3666 } else if (bm
->bgp
!= NULL
) {
3667 struct listnode
*bgpnode
, *nbgpnode
;
3669 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3670 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3671 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3677 *listen_range
= range
;
3678 return (group
&& range
) ? group
: NULL
;
3681 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3683 struct peer_group
*group
;
3686 struct prefix prefix
;
3687 struct prefix
*listen_range
;
3689 char buf
[PREFIX2STR_BUFFER
];
3690 char buf1
[PREFIX2STR_BUFFER
];
3692 sockunion2hostprefix(su
, &prefix
);
3694 /* See if incoming connection matches a configured listen range. */
3695 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3706 prefix2str(&prefix
, buf
, sizeof(buf
));
3707 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3709 if (bgp_debug_neighbor_events(NULL
))
3711 "Dynamic Neighbor %s matches group %s listen range %s",
3712 buf
, group
->name
, buf1
);
3714 /* Are we within the listen limit? */
3715 dncount
= gbgp
->dynamic_neighbors_count
;
3717 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3718 if (bgp_debug_neighbor_events(NULL
))
3719 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3720 inet_sutop(su
, buf
),
3721 gbgp
->dynamic_neighbors_limit
);
3725 /* Ensure group is not disabled. */
3726 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3727 if (bgp_debug_neighbor_events(NULL
))
3729 "Dynamic Neighbor %s rejected - group %s disabled",
3734 /* Check that at least one AF is activated for the group. */
3735 if (!peer_group_af_configured(group
)) {
3736 if (bgp_debug_neighbor_events(NULL
))
3738 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3743 /* Create dynamic peer and bind to associated group. */
3744 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3747 gbgp
->dynamic_neighbors_count
= ++dncount
;
3749 if (bgp_debug_neighbor_events(peer
))
3750 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3751 peer
->host
, group
->name
, dncount
);
3756 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3759 if (peer
->group
->bgp
) {
3760 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3762 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3764 if (bgp_debug_neighbor_events(peer
))
3765 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3766 peer
->group
->name
, dncount
);
3769 /* If peer is configured at least one address family return 1. */
3770 bool peer_active(struct peer
*peer
)
3772 if (BGP_PEER_SU_UNSPEC(peer
))
3774 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3775 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3776 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3777 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3778 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3779 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3780 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3781 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3782 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3783 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3784 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3789 /* If peer is negotiated at least one address family return 1. */
3790 bool peer_active_nego(struct peer
*peer
)
3792 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3793 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3794 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3795 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3796 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3797 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3798 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3799 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3800 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3801 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3802 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3803 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3804 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3809 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3810 enum peer_change_type type
)
3812 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3815 if (peer
->status
!= Established
)
3818 if (type
== peer_change_reset
) {
3819 /* If we're resetting session, we've to delete both peer struct
3821 if ((peer
->doppelganger
)
3822 && (peer
->doppelganger
->status
!= Deleted
)
3823 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3824 PEER_FLAG_CONFIG_NODE
)))
3825 peer_delete(peer
->doppelganger
);
3827 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3828 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3829 } else if (type
== peer_change_reset_in
) {
3830 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3831 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3832 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3834 if ((peer
->doppelganger
)
3835 && (peer
->doppelganger
->status
!= Deleted
)
3836 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3837 PEER_FLAG_CONFIG_NODE
)))
3838 peer_delete(peer
->doppelganger
);
3840 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3841 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3843 } else if (type
== peer_change_reset_out
) {
3844 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3845 bgp_announce_route(peer
, afi
, safi
);
3849 struct peer_flag_action
{
3853 /* This flag can be set for peer-group member. */
3854 uint8_t not_for_member
;
3856 /* Action when the flag is changed. */
3857 enum peer_change_type type
;
3860 static const struct peer_flag_action peer_flag_action_list
[] = {
3861 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3862 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3863 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3864 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3865 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3866 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3867 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3868 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3869 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3870 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3871 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3872 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3873 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3874 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3875 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3876 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3877 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3878 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3881 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3882 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3883 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3884 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3885 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3886 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3887 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3888 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3889 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3890 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3891 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3892 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3893 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3894 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3895 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3896 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3897 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3898 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3899 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3900 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3901 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3902 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3903 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3904 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3905 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3906 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3909 /* Proper action set. */
3910 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3911 int size
, struct peer_flag_action
*action
,
3918 const struct peer_flag_action
*match
= NULL
;
3920 /* Check peer's frag action. */
3921 for (i
= 0; i
< size
; i
++) {
3922 match
= &action_list
[i
];
3924 if (match
->flag
== 0)
3927 if (match
->flag
& flag
) {
3930 if (match
->type
== peer_change_reset_in
)
3932 if (match
->type
== peer_change_reset_out
)
3934 if (match
->type
== peer_change_reset
) {
3938 if (match
->not_for_member
)
3939 action
->not_for_member
= 1;
3943 /* Set peer clear type. */
3944 if (reset_in
&& reset_out
)
3945 action
->type
= peer_change_reset
;
3947 action
->type
= peer_change_reset_in
;
3949 action
->type
= peer_change_reset_out
;
3951 action
->type
= peer_change_none
;
3956 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3958 if (flag
== PEER_FLAG_SHUTDOWN
) {
3959 if (CHECK_FLAG(peer
->flags
, flag
)) {
3960 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3961 peer_nsf_stop(peer
);
3963 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3964 if (peer
->t_pmax_restart
) {
3965 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3966 if (bgp_debug_neighbor_events(peer
))
3968 "%s Maximum-prefix restart timer canceled",
3972 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3973 peer_nsf_stop(peer
);
3975 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3976 char *msg
= peer
->tx_shutdown_message
;
3979 if (!msg
&& peer_group_active(peer
))
3980 msg
= peer
->group
->conf
3981 ->tx_shutdown_message
;
3982 msglen
= msg
? strlen(msg
) : 0;
3987 uint8_t msgbuf
[129];
3990 memcpy(msgbuf
+ 1, msg
, msglen
);
3992 bgp_notify_send_with_data(
3993 peer
, BGP_NOTIFY_CEASE
,
3994 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3995 msgbuf
, msglen
+ 1);
3998 peer
, BGP_NOTIFY_CEASE
,
3999 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
4001 bgp_session_reset(peer
);
4003 peer
->v_start
= BGP_INIT_START_TIMER
;
4004 BGP_EVENT_ADD(peer
, BGP_Stop
);
4006 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4007 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
4008 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4009 else if (flag
== PEER_FLAG_PASSIVE
)
4010 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
4011 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
4012 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
4014 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4015 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4017 bgp_session_reset(peer
);
4020 /* Change specified peer flag. */
4021 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
4025 bool invert
, member_invert
;
4026 struct peer
*member
;
4027 struct listnode
*node
, *nnode
;
4028 struct peer_flag_action action
;
4030 memset(&action
, 0, sizeof(struct peer_flag_action
));
4031 size
= sizeof(peer_flag_action_list
) / sizeof(struct peer_flag_action
);
4033 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4034 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4037 /* Abort if no flag action exists. */
4039 return BGP_ERR_INVALID_FLAG
;
4041 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4042 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4043 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4044 return BGP_ERR_PEER_FLAG_CONFLICT
;
4046 /* Handle flag updates where desired state matches current state. */
4047 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4048 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4049 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4053 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4054 COND_FLAG(peer
->flags_override
, flag
, invert
);
4059 /* Inherit from peer-group or set/unset flags accordingly. */
4060 if (peer_group_active(peer
) && set
== invert
)
4061 peer_flag_inherit(peer
, flag
);
4063 COND_FLAG(peer
->flags
, flag
, set
);
4065 /* Check if handling a regular peer. */
4066 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4067 /* Update flag override state accordingly. */
4068 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4071 * For the extended next-hop encoding flag we need to turn RAs
4072 * on if flag is being set, but only turn RAs off if the flag
4073 * is being unset on this peer and if this peer is a member of a
4074 * peer-group, the peer-group also doesn't have the flag set.
4076 if (flag
== PEER_FLAG_CAPABILITY_ENHE
) {
4078 bgp_zebra_initiate_radv(peer
->bgp
, peer
);
4079 } else if (peer_group_active(peer
)) {
4080 if (!CHECK_FLAG(peer
->group
->conf
->flags
, flag
))
4081 bgp_zebra_terminate_radv(peer
->bgp
,
4084 bgp_zebra_terminate_radv(peer
->bgp
, peer
);
4087 /* Execute flag action on peer. */
4088 if (action
.type
== peer_change_reset
)
4089 peer_flag_modify_action(peer
, flag
);
4091 /* Skip peer-group mechanics for regular peers. */
4096 * Update peer-group members, unless they are explicitely overriding
4097 * peer-group configuration.
4099 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4100 /* Skip peers with overridden configuration. */
4101 if (CHECK_FLAG(member
->flags_override
, flag
))
4104 /* Check if only member without group is inverted. */
4106 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4108 /* Skip peers with equivalent configuration. */
4109 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4112 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4115 /* Update flag on peer-group member. */
4116 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4118 if (flag
== PEER_FLAG_CAPABILITY_ENHE
)
4119 set
? bgp_zebra_initiate_radv(member
->bgp
, member
)
4120 : bgp_zebra_terminate_radv(member
->bgp
, member
);
4122 /* Execute flag action on peer-group member. */
4123 if (action
.type
== peer_change_reset
)
4124 peer_flag_modify_action(member
, flag
);
4130 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4132 return peer_flag_modify(peer
, flag
, 1);
4135 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4137 return peer_flag_modify(peer
, flag
, 0);
4140 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4141 uint32_t flag
, bool set
)
4145 bool invert
, member_invert
;
4146 struct peer
*member
;
4147 struct listnode
*node
, *nnode
;
4148 struct peer_flag_action action
;
4149 bgp_peer_sort_t ptype
;
4151 memset(&action
, 0, sizeof(struct peer_flag_action
));
4152 size
= sizeof(peer_af_flag_action_list
)
4153 / sizeof(struct peer_flag_action
);
4155 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4156 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4159 /* Abort if flag action exists. */
4161 return BGP_ERR_INVALID_FLAG
;
4163 ptype
= peer_sort(peer
);
4164 /* Special check for reflector client. */
4165 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
&& ptype
!= BGP_PEER_IBGP
)
4166 return BGP_ERR_NOT_INTERNAL_PEER
;
4168 /* Special check for remove-private-AS. */
4169 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
&& ptype
== BGP_PEER_IBGP
)
4170 return BGP_ERR_REMOVE_PRIVATE_AS
;
4172 /* as-override is not allowed for IBGP peers */
4173 if (flag
& PEER_FLAG_AS_OVERRIDE
&& ptype
== BGP_PEER_IBGP
)
4174 return BGP_ERR_AS_OVERRIDE
;
4176 /* Handle flag updates where desired state matches current state. */
4177 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4178 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4179 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4184 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4185 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4192 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4193 * if we are setting/unsetting flags which conflict with this flag
4194 * handle accordingly
4196 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4200 * if we are setting NEXTHOP_SELF, we need to unset the
4201 * NEXTHOP_UNCHANGED flag
4203 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4204 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4205 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4206 PEER_FLAG_NEXTHOP_UNCHANGED
);
4210 * if we are unsetting NEXTHOP_SELF, we need to set the
4211 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4213 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4214 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4215 SET_FLAG(peer
->af_flags
[afi
][safi
],
4216 PEER_FLAG_NEXTHOP_UNCHANGED
);
4221 * If the peer is a route server client let's not
4222 * muck with the nexthop on the way out the door
4224 if (flag
& PEER_FLAG_RSERVER_CLIENT
) {
4226 SET_FLAG(peer
->af_flags
[afi
][safi
],
4227 PEER_FLAG_NEXTHOP_UNCHANGED
);
4229 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4230 PEER_FLAG_NEXTHOP_UNCHANGED
);
4233 /* Inherit from peer-group or set/unset flags accordingly. */
4234 if (peer_group_active(peer
) && set
== invert
)
4235 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4237 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4239 /* Execute action when peer is established. */
4240 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4241 && peer
->status
== Established
) {
4242 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4243 bgp_clear_adj_in(peer
, afi
, safi
);
4245 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4246 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4247 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4248 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4249 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4250 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4251 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4252 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4254 peer_change_action(peer
, afi
, safi
, action
.type
);
4258 /* Check if handling a regular peer. */
4259 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4260 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4264 * Update peer-group members, unless they are explicitely
4265 * overriding peer-group configuration.
4267 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4269 /* Skip peers with overridden configuration. */
4270 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4274 /* Check if only member without group is inverted. */
4276 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4280 /* Skip peers with equivalent configuration. */
4281 if (set
!= member_invert
4282 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4285 if (set
== member_invert
4286 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4289 /* Update flag on peer-group member. */
4290 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4291 set
!= member_invert
);
4293 /* Execute flag action on peer-group member. */
4294 if (member
->status
== Established
) {
4295 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4296 bgp_clear_adj_in(member
, afi
, safi
);
4298 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4299 member
->last_reset
=
4300 PEER_DOWN_RR_CLIENT_CHANGE
;
4302 == PEER_FLAG_RSERVER_CLIENT
)
4303 member
->last_reset
=
4304 PEER_DOWN_RS_CLIENT_CHANGE
;
4306 == PEER_FLAG_ORF_PREFIX_SM
)
4307 member
->last_reset
=
4308 PEER_DOWN_CAPABILITY_CHANGE
;
4310 == PEER_FLAG_ORF_PREFIX_RM
)
4311 member
->last_reset
=
4312 PEER_DOWN_CAPABILITY_CHANGE
;
4314 peer_change_action(member
, afi
, safi
,
4324 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4326 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4329 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4331 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4335 void peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4337 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4338 peer
->tx_shutdown_message
=
4339 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4342 void peer_tx_shutdown_message_unset(struct peer
*peer
)
4344 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4348 /* EBGP multihop configuration. */
4349 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4351 struct peer_group
*group
;
4352 struct listnode
*node
, *nnode
;
4355 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4358 /* see comment in peer_ttl_security_hops_set() */
4359 if (ttl
!= MAXTTL
) {
4360 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4361 group
= peer
->group
;
4362 if (group
->conf
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4363 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4365 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4367 if (peer1
->sort
== BGP_PEER_IBGP
)
4370 if (peer1
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4371 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4374 if (peer
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4375 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4381 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4382 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4383 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4384 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4385 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4387 bgp_session_reset(peer
);
4390 group
= peer
->group
;
4391 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4392 if (peer
->sort
== BGP_PEER_IBGP
)
4395 peer
->ttl
= group
->conf
->ttl
;
4397 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4398 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4399 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4401 bgp_session_reset(peer
);
4407 int peer_ebgp_multihop_unset(struct peer
*peer
)
4409 struct peer_group
*group
;
4410 struct listnode
*node
, *nnode
;
4412 if (peer
->sort
== BGP_PEER_IBGP
)
4415 if (peer
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
&& peer
->ttl
!= MAXTTL
)
4416 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4418 if (peer_group_active(peer
))
4419 peer
->ttl
= peer
->group
->conf
->ttl
;
4421 peer
->ttl
= BGP_DEFAULT_TTL
;
4423 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4424 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4425 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4426 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4428 bgp_session_reset(peer
);
4430 group
= peer
->group
;
4431 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4432 if (peer
->sort
== BGP_PEER_IBGP
)
4435 peer
->ttl
= BGP_DEFAULT_TTL
;
4437 if (peer
->fd
>= 0) {
4438 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4440 peer
, BGP_NOTIFY_CEASE
,
4441 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4443 bgp_session_reset(peer
);
4450 /* Neighbor description. */
4451 void peer_description_set(struct peer
*peer
, const char *desc
)
4453 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4455 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4458 void peer_description_unset(struct peer
*peer
)
4460 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4463 /* Neighbor update-source. */
4464 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4466 struct peer
*member
;
4467 struct listnode
*node
, *nnode
;
4469 /* Set flag and configuration on peer. */
4470 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4471 if (peer
->update_if
) {
4472 if (strcmp(peer
->update_if
, ifname
) == 0)
4474 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4476 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4477 sockunion_free(peer
->update_source
);
4478 peer
->update_source
= NULL
;
4480 /* Check if handling a regular peer. */
4481 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4482 /* Send notification or reset peer depending on state. */
4483 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4484 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4485 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4486 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4488 bgp_session_reset(peer
);
4490 /* Skip peer-group mechanics for regular peers. */
4495 * Set flag and configuration on all peer-group members, unless they are
4496 * explicitely overriding peer-group configuration.
4498 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4499 /* Skip peers with overridden configuration. */
4500 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4503 /* Skip peers with the same configuration. */
4504 if (member
->update_if
) {
4505 if (strcmp(member
->update_if
, ifname
) == 0)
4507 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4510 /* Set flag and configuration on peer-group member. */
4511 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4512 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4513 sockunion_free(member
->update_source
);
4514 member
->update_source
= NULL
;
4516 /* Send notification or reset peer depending on state. */
4517 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4518 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4519 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4520 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4522 bgp_session_reset(member
);
4528 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4530 struct peer
*member
;
4531 struct listnode
*node
, *nnode
;
4533 /* Set flag and configuration on peer. */
4534 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4535 if (peer
->update_source
) {
4536 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4538 sockunion_free(peer
->update_source
);
4540 peer
->update_source
= sockunion_dup(su
);
4541 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4543 /* Check if handling a regular peer. */
4544 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4545 /* Send notification or reset peer depending on state. */
4546 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4547 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4548 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4549 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4551 bgp_session_reset(peer
);
4553 /* Skip peer-group mechanics for regular peers. */
4558 * Set flag and configuration on all peer-group members, unless they are
4559 * explicitely overriding peer-group configuration.
4561 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4562 /* Skip peers with overridden configuration. */
4563 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4566 /* Skip peers with the same configuration. */
4567 if (member
->update_source
) {
4568 if (sockunion_cmp(member
->update_source
, su
) == 0)
4570 sockunion_free(member
->update_source
);
4573 /* Set flag and configuration on peer-group member. */
4574 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4575 member
->update_source
= sockunion_dup(su
);
4576 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4578 /* Send notification or reset peer depending on state. */
4579 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4580 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4581 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4582 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4584 bgp_session_reset(member
);
4590 int peer_update_source_unset(struct peer
*peer
)
4592 struct peer
*member
;
4593 struct listnode
*node
, *nnode
;
4595 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4598 /* Inherit configuration from peer-group if peer is member. */
4599 if (peer_group_active(peer
)) {
4600 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4601 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4602 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4603 MTYPE_PEER_UPDATE_SOURCE
);
4605 /* Otherwise remove flag and configuration from peer. */
4606 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4607 sockunion_free(peer
->update_source
);
4608 peer
->update_source
= NULL
;
4609 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4612 /* Check if handling a regular peer. */
4613 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4614 /* Send notification or reset peer depending on state. */
4615 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4616 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4617 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4618 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4620 bgp_session_reset(peer
);
4622 /* Skip peer-group mechanics for regular peers. */
4627 * Set flag and configuration on all peer-group members, unless they are
4628 * explicitely overriding peer-group configuration.
4630 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4631 /* Skip peers with overridden configuration. */
4632 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4635 /* Skip peers with the same configuration. */
4636 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4637 && !member
->update_source
&& !member
->update_if
)
4640 /* Remove flag and configuration on peer-group member. */
4641 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4642 sockunion_free(member
->update_source
);
4643 member
->update_source
= NULL
;
4644 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4646 /* Send notification or reset peer depending on state. */
4647 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4648 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4649 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4650 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4652 bgp_session_reset(member
);
4658 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4659 const char *rmap
, struct route_map
*route_map
)
4661 struct peer
*member
;
4662 struct listnode
*node
, *nnode
;
4664 /* Set flag and configuration on peer. */
4665 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4667 if (!peer
->default_rmap
[afi
][safi
].name
4668 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4669 if (peer
->default_rmap
[afi
][safi
].name
)
4670 XFREE(MTYPE_ROUTE_MAP_NAME
,
4671 peer
->default_rmap
[afi
][safi
].name
);
4673 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4674 peer
->default_rmap
[afi
][safi
].name
=
4675 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4676 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4677 route_map_counter_increment(route_map
);
4680 if (peer
->default_rmap
[afi
][safi
].name
)
4681 XFREE(MTYPE_ROUTE_MAP_NAME
,
4682 peer
->default_rmap
[afi
][safi
].name
);
4684 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4685 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4686 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4689 /* Check if handling a regular peer. */
4690 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4691 /* Update peer route announcements. */
4692 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4693 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4694 bgp_default_originate(peer
, afi
, safi
, 0);
4695 bgp_announce_route(peer
, afi
, safi
);
4698 /* Skip peer-group mechanics for regular peers. */
4703 * Set flag and configuration on all peer-group members, unless they are
4704 * explicitely overriding peer-group configuration.
4706 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4707 /* Skip peers with overridden configuration. */
4708 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4709 PEER_FLAG_DEFAULT_ORIGINATE
))
4712 /* Set flag and configuration on peer-group member. */
4713 SET_FLAG(member
->af_flags
[afi
][safi
],
4714 PEER_FLAG_DEFAULT_ORIGINATE
);
4716 if (member
->default_rmap
[afi
][safi
].name
)
4717 XFREE(MTYPE_ROUTE_MAP_NAME
,
4718 member
->default_rmap
[afi
][safi
].name
);
4719 route_map_counter_decrement(
4720 member
->default_rmap
[afi
][safi
].map
);
4721 member
->default_rmap
[afi
][safi
].name
=
4722 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4723 member
->default_rmap
[afi
][safi
].map
= route_map
;
4724 route_map_counter_increment(route_map
);
4727 /* Update peer route announcements. */
4728 if (member
->status
== Established
4729 && member
->afc_nego
[afi
][safi
]) {
4730 update_group_adjust_peer(
4731 peer_af_find(member
, afi
, safi
));
4732 bgp_default_originate(member
, afi
, safi
, 0);
4733 bgp_announce_route(member
, afi
, safi
);
4740 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4742 struct peer
*member
;
4743 struct listnode
*node
, *nnode
;
4745 /* Inherit configuration from peer-group if peer is member. */
4746 if (peer_group_active(peer
)) {
4747 peer_af_flag_inherit(peer
, afi
, safi
,
4748 PEER_FLAG_DEFAULT_ORIGINATE
);
4749 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4750 default_rmap
[afi
][safi
].name
,
4751 MTYPE_ROUTE_MAP_NAME
);
4752 PEER_ATTR_INHERIT(peer
, peer
->group
,
4753 default_rmap
[afi
][safi
].map
);
4755 /* Otherwise remove flag and configuration from peer. */
4756 peer_af_flag_unset(peer
, afi
, safi
,
4757 PEER_FLAG_DEFAULT_ORIGINATE
);
4758 if (peer
->default_rmap
[afi
][safi
].name
)
4759 XFREE(MTYPE_ROUTE_MAP_NAME
,
4760 peer
->default_rmap
[afi
][safi
].name
);
4761 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4762 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4763 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4766 /* Check if handling a regular peer. */
4767 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4768 /* Update peer route announcements. */
4769 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4770 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4771 bgp_default_originate(peer
, afi
, safi
, 1);
4772 bgp_announce_route(peer
, afi
, safi
);
4775 /* Skip peer-group mechanics for regular peers. */
4780 * Remove flag and configuration from all peer-group members, unless
4781 * they are explicitely overriding peer-group configuration.
4783 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4784 /* Skip peers with overridden configuration. */
4785 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4786 PEER_FLAG_DEFAULT_ORIGINATE
))
4789 /* Remove flag and configuration on peer-group member. */
4790 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4791 PEER_FLAG_DEFAULT_ORIGINATE
);
4792 if (peer
->default_rmap
[afi
][safi
].name
)
4793 XFREE(MTYPE_ROUTE_MAP_NAME
,
4794 peer
->default_rmap
[afi
][safi
].name
);
4795 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4796 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4797 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4799 /* Update peer route announcements. */
4800 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4801 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4802 bgp_default_originate(peer
, afi
, safi
, 1);
4803 bgp_announce_route(peer
, afi
, safi
);
4810 void peer_port_set(struct peer
*peer
, uint16_t port
)
4815 void peer_port_unset(struct peer
*peer
)
4817 peer
->port
= BGP_PORT_DEFAULT
;
4821 * Helper function that is called after the name of the policy
4822 * being used by a peer has changed (AF specific). Automatically
4823 * initiates inbound or outbound processing as needed.
4825 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4829 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4830 if (peer
->status
== Established
)
4831 bgp_announce_route(peer
, afi
, safi
);
4833 if (peer
->status
!= Established
)
4836 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4837 PEER_FLAG_SOFT_RECONFIG
))
4838 bgp_soft_reconfig_in(peer
, afi
, safi
);
4839 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4840 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4841 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4846 /* neighbor weight. */
4847 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4849 struct peer
*member
;
4850 struct listnode
*node
, *nnode
;
4852 /* Set flag and configuration on peer. */
4853 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4854 if (peer
->weight
[afi
][safi
] != weight
) {
4855 peer
->weight
[afi
][safi
] = weight
;
4856 peer_on_policy_change(peer
, afi
, safi
, 0);
4859 /* Skip peer-group mechanics for regular peers. */
4860 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4864 * Set flag and configuration on all peer-group members, unless they are
4865 * explicitely overriding peer-group configuration.
4867 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4868 /* Skip peers with overridden configuration. */
4869 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4873 /* Set flag and configuration on peer-group member. */
4874 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4875 if (member
->weight
[afi
][safi
] != weight
) {
4876 member
->weight
[afi
][safi
] = weight
;
4877 peer_on_policy_change(member
, afi
, safi
, 0);
4884 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4886 struct peer
*member
;
4887 struct listnode
*node
, *nnode
;
4889 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4892 /* Inherit configuration from peer-group if peer is member. */
4893 if (peer_group_active(peer
)) {
4894 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4895 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4897 peer_on_policy_change(peer
, afi
, safi
, 0);
4901 /* Remove flag and configuration from peer. */
4902 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4903 peer
->weight
[afi
][safi
] = 0;
4904 peer_on_policy_change(peer
, afi
, safi
, 0);
4906 /* Skip peer-group mechanics for regular peers. */
4907 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4911 * Remove flag and configuration from all peer-group members, unless
4912 * they are explicitely overriding peer-group configuration.
4914 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4915 /* Skip peers with overridden configuration. */
4916 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4920 /* Skip peers where flag is already disabled. */
4921 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4924 /* Remove flag and configuration on peer-group member. */
4925 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4926 member
->weight
[afi
][safi
] = 0;
4927 peer_on_policy_change(member
, afi
, safi
, 0);
4933 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4935 struct peer
*member
;
4936 struct listnode
*node
, *nnode
;
4938 if (keepalive
> 65535)
4939 return BGP_ERR_INVALID_VALUE
;
4941 if (holdtime
> 65535)
4942 return BGP_ERR_INVALID_VALUE
;
4944 if (holdtime
< 3 && holdtime
!= 0)
4945 return BGP_ERR_INVALID_VALUE
;
4947 /* Set flag and configuration on peer. */
4948 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4949 peer
->holdtime
= holdtime
;
4950 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4952 /* Skip peer-group mechanics for regular peers. */
4953 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4957 * Set flag and configuration on all peer-group members, unless they are
4958 * explicitely overriding peer-group configuration.
4960 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4961 /* Skip peers with overridden configuration. */
4962 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4965 /* Set flag and configuration on peer-group member. */
4966 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4967 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4968 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4974 int peer_timers_unset(struct peer
*peer
)
4976 struct peer
*member
;
4977 struct listnode
*node
, *nnode
;
4979 /* Inherit configuration from peer-group if peer is member. */
4980 if (peer_group_active(peer
)) {
4981 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4982 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4983 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4985 /* Otherwise remove flag and configuration from peer. */
4986 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4988 peer
->keepalive
= 0;
4991 /* Skip peer-group mechanics for regular peers. */
4992 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4996 * Remove flag and configuration from all peer-group members, unless
4997 * they are explicitely overriding peer-group configuration.
4999 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5000 /* Skip peers with overridden configuration. */
5001 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
5004 /* Remove flag and configuration on peer-group member. */
5005 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
5006 member
->holdtime
= 0;
5007 member
->keepalive
= 0;
5013 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
5015 struct peer
*member
;
5016 struct listnode
*node
, *nnode
;
5018 if (connect
> 65535)
5019 return BGP_ERR_INVALID_VALUE
;
5021 /* Set flag and configuration on peer. */
5022 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
5023 peer
->connect
= connect
;
5024 peer
->v_connect
= connect
;
5026 /* Skip peer-group mechanics for regular peers. */
5027 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5031 * Set flag and configuration on all peer-group members, unless they are
5032 * explicitely overriding peer-group configuration.
5034 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5035 /* Skip peers with overridden configuration. */
5036 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5039 /* Set flag and configuration on peer-group member. */
5040 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5041 member
->connect
= connect
;
5042 member
->v_connect
= connect
;
5048 int peer_timers_connect_unset(struct peer
*peer
)
5050 struct peer
*member
;
5051 struct listnode
*node
, *nnode
;
5053 /* Inherit configuration from peer-group if peer is member. */
5054 if (peer_group_active(peer
)) {
5055 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5056 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5058 /* Otherwise remove flag and configuration from peer. */
5059 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5063 /* Set timer with fallback to default value. */
5065 peer
->v_connect
= peer
->connect
;
5067 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
5069 /* Skip peer-group mechanics for regular peers. */
5070 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5074 * Remove flag and configuration from all peer-group members, unless
5075 * they are explicitely overriding peer-group configuration.
5077 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5078 /* Skip peers with overridden configuration. */
5079 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5082 /* Remove flag and configuration on peer-group member. */
5083 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5084 member
->connect
= 0;
5085 member
->v_connect
= peer
->bgp
->default_connect_retry
;
5091 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5093 struct peer
*member
;
5094 struct listnode
*node
, *nnode
;
5097 return BGP_ERR_INVALID_VALUE
;
5099 /* Set flag and configuration on peer. */
5100 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5101 peer
->routeadv
= routeadv
;
5102 peer
->v_routeadv
= routeadv
;
5104 /* Check if handling a regular peer. */
5105 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5106 /* Update peer route announcements. */
5107 update_group_adjust_peer_afs(peer
);
5108 if (peer
->status
== Established
)
5109 bgp_announce_route_all(peer
);
5111 /* Skip peer-group mechanics for regular peers. */
5116 * Set flag and configuration on all peer-group members, unless they are
5117 * explicitely overriding peer-group configuration.
5119 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5120 /* Skip peers with overridden configuration. */
5121 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5124 /* Set flag and configuration on peer-group member. */
5125 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5126 member
->routeadv
= routeadv
;
5127 member
->v_routeadv
= routeadv
;
5129 /* Update peer route announcements. */
5130 update_group_adjust_peer_afs(member
);
5131 if (member
->status
== Established
)
5132 bgp_announce_route_all(member
);
5138 int peer_advertise_interval_unset(struct peer
*peer
)
5140 struct peer
*member
;
5141 struct listnode
*node
, *nnode
;
5143 /* Inherit configuration from peer-group if peer is member. */
5144 if (peer_group_active(peer
)) {
5145 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5146 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5148 /* Otherwise remove flag and configuration from peer. */
5149 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5153 /* Set timer with fallback to default value. */
5155 peer
->v_routeadv
= peer
->routeadv
;
5157 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5158 ? BGP_DEFAULT_IBGP_ROUTEADV
5159 : BGP_DEFAULT_EBGP_ROUTEADV
;
5161 /* Check if handling a regular peer. */
5162 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5163 /* Update peer route announcements. */
5164 update_group_adjust_peer_afs(peer
);
5165 if (peer
->status
== Established
)
5166 bgp_announce_route_all(peer
);
5168 /* Skip peer-group mechanics for regular peers. */
5173 * Remove flag and configuration from all peer-group members, unless
5174 * they are explicitely overriding peer-group configuration.
5176 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5177 /* Skip peers with overridden configuration. */
5178 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5181 /* Remove flag and configuration on peer-group member. */
5182 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5183 member
->routeadv
= 0;
5184 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5185 ? BGP_DEFAULT_IBGP_ROUTEADV
5186 : BGP_DEFAULT_EBGP_ROUTEADV
;
5188 /* Update peer route announcements. */
5189 update_group_adjust_peer_afs(member
);
5190 if (member
->status
== Established
)
5191 bgp_announce_route_all(member
);
5197 /* neighbor interface */
5198 void peer_interface_set(struct peer
*peer
, const char *str
)
5200 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5201 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5204 void peer_interface_unset(struct peer
*peer
)
5206 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5210 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5211 int allow_num
, int origin
)
5213 struct peer
*member
;
5214 struct listnode
*node
, *nnode
;
5216 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5217 return BGP_ERR_INVALID_VALUE
;
5219 /* Set flag and configuration on peer. */
5220 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5222 if (peer
->allowas_in
[afi
][safi
] != 0
5223 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5224 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5225 peer_af_flag_set(peer
, afi
, safi
,
5226 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5227 peer
->allowas_in
[afi
][safi
] = 0;
5228 peer_on_policy_change(peer
, afi
, safi
, 0);
5231 if (peer
->allowas_in
[afi
][safi
] != allow_num
5232 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5233 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5235 peer_af_flag_unset(peer
, afi
, safi
,
5236 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5237 peer
->allowas_in
[afi
][safi
] = allow_num
;
5238 peer_on_policy_change(peer
, afi
, safi
, 0);
5242 /* Skip peer-group mechanics for regular peers. */
5243 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5247 * Set flag and configuration on all peer-group members, unless
5248 * they are explicitely overriding peer-group configuration.
5250 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5251 /* Skip peers with overridden configuration. */
5252 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5253 PEER_FLAG_ALLOWAS_IN
))
5256 /* Set flag and configuration on peer-group member. */
5257 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5259 if (member
->allowas_in
[afi
][safi
] != 0
5260 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5261 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5262 SET_FLAG(member
->af_flags
[afi
][safi
],
5263 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5264 member
->allowas_in
[afi
][safi
] = 0;
5265 peer_on_policy_change(peer
, afi
, safi
, 0);
5268 if (member
->allowas_in
[afi
][safi
] != allow_num
5269 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5270 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5271 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5272 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5273 member
->allowas_in
[afi
][safi
] = allow_num
;
5274 peer_on_policy_change(peer
, afi
, safi
, 0);
5282 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5284 struct peer
*member
;
5285 struct listnode
*node
, *nnode
;
5287 /* Skip peer if flag is already disabled. */
5288 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5291 /* Inherit configuration from peer-group if peer is member. */
5292 if (peer_group_active(peer
)) {
5293 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5294 peer_af_flag_inherit(peer
, afi
, safi
,
5295 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5296 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5297 peer_on_policy_change(peer
, afi
, safi
, 0);
5302 /* Remove flag and configuration from peer. */
5303 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5304 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5305 peer
->allowas_in
[afi
][safi
] = 0;
5306 peer_on_policy_change(peer
, afi
, safi
, 0);
5308 /* Skip peer-group mechanics if handling a regular peer. */
5309 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5313 * Remove flags and configuration from all peer-group members, unless
5314 * they are explicitely overriding peer-group configuration.
5316 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5317 /* Skip peers with overridden configuration. */
5318 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5319 PEER_FLAG_ALLOWAS_IN
))
5322 /* Skip peers where flag is already disabled. */
5323 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5324 PEER_FLAG_ALLOWAS_IN
))
5327 /* Remove flags and configuration on peer-group member. */
5328 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5329 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5330 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5331 member
->allowas_in
[afi
][safi
] = 0;
5332 peer_on_policy_change(member
, afi
, safi
, 0);
5338 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5341 bool old_no_prepend
, old_replace_as
;
5342 struct bgp
*bgp
= peer
->bgp
;
5343 struct peer
*member
;
5344 struct listnode
*node
, *nnode
;
5345 bgp_peer_sort_t ptype
= peer_sort(peer
);
5347 if (ptype
!= BGP_PEER_EBGP
&& ptype
!= BGP_PEER_INTERNAL
)
5348 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5351 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5354 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5356 /* Save previous flag states. */
5358 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5360 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5362 /* Set flag and configuration on peer. */
5363 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5364 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5365 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5367 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5368 && old_replace_as
== replace_as
)
5370 peer
->change_local_as
= as
;
5372 /* Check if handling a regular peer. */
5373 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5374 /* Send notification or reset peer depending on state. */
5375 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5376 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5377 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5378 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5380 bgp_session_reset(peer
);
5382 /* Skip peer-group mechanics for regular peers. */
5387 * Set flag and configuration on all peer-group members, unless they are
5388 * explicitely overriding peer-group configuration.
5390 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5391 /* Skip peers with overridden configuration. */
5392 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5395 /* Skip peers with the same configuration. */
5396 old_no_prepend
= CHECK_FLAG(member
->flags
,
5397 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5398 old_replace_as
= CHECK_FLAG(member
->flags
,
5399 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5400 if (member
->change_local_as
== as
5401 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5402 && old_no_prepend
== no_prepend
5403 && old_replace_as
== replace_as
)
5406 /* Set flag and configuration on peer-group member. */
5407 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5408 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5410 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5412 member
->change_local_as
= as
;
5414 /* Send notification or stop peer depending on state. */
5415 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5416 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5417 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5418 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5420 BGP_EVENT_ADD(member
, BGP_Stop
);
5426 int peer_local_as_unset(struct peer
*peer
)
5428 struct peer
*member
;
5429 struct listnode
*node
, *nnode
;
5431 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5434 /* Inherit configuration from peer-group if peer is member. */
5435 if (peer_group_active(peer
)) {
5436 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5437 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5438 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5439 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5441 /* Otherwise remove flag and configuration from peer. */
5442 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5443 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5444 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5445 peer
->change_local_as
= 0;
5448 /* Check if handling a regular peer. */
5449 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5450 /* Send notification or stop peer depending on state. */
5451 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5452 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5453 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5454 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5456 BGP_EVENT_ADD(peer
, BGP_Stop
);
5458 /* Skip peer-group mechanics for regular peers. */
5463 * Remove flag and configuration from all peer-group members, unless
5464 * they are explicitely overriding peer-group configuration.
5466 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5467 /* Skip peers with overridden configuration. */
5468 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5471 /* Remove flag and configuration on peer-group member. */
5472 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5473 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5474 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5475 member
->change_local_as
= 0;
5477 /* Send notification or stop peer depending on state. */
5478 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5479 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5480 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5481 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5483 bgp_session_reset(member
);
5489 /* Set password for authenticating with the peer. */
5490 int peer_password_set(struct peer
*peer
, const char *password
)
5492 struct peer
*member
;
5493 struct listnode
*node
, *nnode
;
5494 int len
= password
? strlen(password
) : 0;
5495 int ret
= BGP_SUCCESS
;
5497 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5498 return BGP_ERR_INVALID_VALUE
;
5500 /* Set flag and configuration on peer. */
5501 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5502 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5504 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5505 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5507 /* Check if handling a regular peer. */
5508 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5509 /* Send notification or reset peer depending on state. */
5510 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5511 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5512 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5514 bgp_session_reset(peer
);
5517 * Attempt to install password on socket and skip peer-group
5520 if (BGP_PEER_SU_UNSPEC(peer
))
5522 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5523 : BGP_ERR_TCPSIG_FAILED
;
5527 * Set flag and configuration on all peer-group members, unless they are
5528 * explicitely overriding peer-group configuration.
5530 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5531 /* Skip peers with overridden configuration. */
5532 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5535 /* Skip peers with the same password. */
5536 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5539 /* Set flag and configuration on peer-group member. */
5540 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5541 if (member
->password
)
5542 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5543 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5545 /* Send notification or reset peer depending on state. */
5546 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5547 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5548 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5550 bgp_session_reset(member
);
5552 /* Attempt to install password on socket. */
5553 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5554 ret
= BGP_ERR_TCPSIG_FAILED
;
5557 /* Set flag and configuration on all peer-group listen ranges */
5558 struct listnode
*ln
;
5561 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5562 bgp_md5_set_prefix(lr
, password
);
5563 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5564 bgp_md5_set_prefix(lr
, password
);
5569 int peer_password_unset(struct peer
*peer
)
5571 struct peer
*member
;
5572 struct listnode
*node
, *nnode
;
5574 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5577 /* Inherit configuration from peer-group if peer is member. */
5578 if (peer_group_active(peer
)) {
5579 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5580 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5581 MTYPE_PEER_PASSWORD
);
5583 /* Otherwise remove flag and configuration from peer. */
5584 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5585 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5588 /* Check if handling a regular peer. */
5589 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5590 /* Send notification or reset peer depending on state. */
5591 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5592 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5593 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5595 bgp_session_reset(peer
);
5597 /* Attempt to uninstall password on socket. */
5598 if (!BGP_PEER_SU_UNSPEC(peer
))
5599 bgp_md5_unset(peer
);
5601 /* Skip peer-group mechanics for regular peers. */
5606 * Remove flag and configuration from all peer-group members, unless
5607 * they are explicitely overriding peer-group configuration.
5609 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5610 /* Skip peers with overridden configuration. */
5611 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5614 /* Remove flag and configuration on peer-group member. */
5615 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5616 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5618 /* Send notification or reset peer depending on state. */
5619 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5620 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5621 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5623 bgp_session_reset(member
);
5625 /* Attempt to uninstall password on socket. */
5626 if (!BGP_PEER_SU_UNSPEC(member
))
5627 bgp_md5_unset(member
);
5630 /* Set flag and configuration on all peer-group listen ranges */
5631 struct listnode
*ln
;
5634 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5635 bgp_md5_unset_prefix(lr
);
5636 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5637 bgp_md5_unset_prefix(lr
);
5643 /* Set distribute list to the peer. */
5644 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5647 struct peer
*member
;
5648 struct bgp_filter
*filter
;
5649 struct listnode
*node
, *nnode
;
5651 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5652 return BGP_ERR_INVALID_VALUE
;
5654 /* Set configuration on peer. */
5655 filter
= &peer
->filter
[afi
][safi
];
5656 if (filter
->plist
[direct
].name
)
5657 return BGP_ERR_PEER_FILTER_CONFLICT
;
5658 if (filter
->dlist
[direct
].name
)
5659 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5660 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5661 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5663 /* Check if handling a regular peer. */
5664 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5665 /* Set override-flag and process peer route updates. */
5666 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5667 PEER_FT_DISTRIBUTE_LIST
);
5668 peer_on_policy_change(peer
, afi
, safi
,
5669 (direct
== FILTER_OUT
) ? 1 : 0);
5671 /* Skip peer-group mechanics for regular peers. */
5676 * Set configuration on all peer-group members, un less they are
5677 * explicitely overriding peer-group configuration.
5679 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5680 /* Skip peers with overridden configuration. */
5681 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5682 PEER_FT_DISTRIBUTE_LIST
))
5685 /* Set configuration on peer-group member. */
5686 filter
= &member
->filter
[afi
][safi
];
5687 if (filter
->dlist
[direct
].name
)
5688 XFREE(MTYPE_BGP_FILTER_NAME
,
5689 filter
->dlist
[direct
].name
);
5690 filter
->dlist
[direct
].name
=
5691 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5692 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5694 /* Process peer route updates. */
5695 peer_on_policy_change(member
, afi
, safi
,
5696 (direct
== FILTER_OUT
) ? 1 : 0);
5702 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5704 struct peer
*member
;
5705 struct bgp_filter
*filter
;
5706 struct listnode
*node
, *nnode
;
5708 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5709 return BGP_ERR_INVALID_VALUE
;
5711 /* Unset override-flag unconditionally. */
5712 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5713 PEER_FT_DISTRIBUTE_LIST
);
5715 /* Inherit configuration from peer-group if peer is member. */
5716 if (peer_group_active(peer
)) {
5717 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5718 filter
[afi
][safi
].dlist
[direct
].name
,
5719 MTYPE_BGP_FILTER_NAME
);
5720 PEER_ATTR_INHERIT(peer
, peer
->group
,
5721 filter
[afi
][safi
].dlist
[direct
].alist
);
5723 /* Otherwise remove configuration from peer. */
5724 filter
= &peer
->filter
[afi
][safi
];
5725 if (filter
->dlist
[direct
].name
)
5726 XFREE(MTYPE_BGP_FILTER_NAME
,
5727 filter
->dlist
[direct
].name
);
5728 filter
->dlist
[direct
].name
= NULL
;
5729 filter
->dlist
[direct
].alist
= NULL
;
5732 /* Check if handling a regular peer. */
5733 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5734 /* Process peer route updates. */
5735 peer_on_policy_change(peer
, afi
, safi
,
5736 (direct
== FILTER_OUT
) ? 1 : 0);
5738 /* Skip peer-group mechanics for regular peers. */
5743 * Remove configuration on all peer-group members, unless they are
5744 * explicitely overriding peer-group configuration.
5746 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5747 /* Skip peers with overridden configuration. */
5748 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5749 PEER_FT_DISTRIBUTE_LIST
))
5752 /* Remove configuration on peer-group member. */
5753 filter
= &member
->filter
[afi
][safi
];
5754 if (filter
->dlist
[direct
].name
)
5755 XFREE(MTYPE_BGP_FILTER_NAME
,
5756 filter
->dlist
[direct
].name
);
5757 filter
->dlist
[direct
].name
= NULL
;
5758 filter
->dlist
[direct
].alist
= NULL
;
5760 /* Process peer route updates. */
5761 peer_on_policy_change(member
, afi
, safi
,
5762 (direct
== FILTER_OUT
) ? 1 : 0);
5768 /* Update distribute list. */
5769 static void peer_distribute_update(struct access_list
*access
)
5774 struct listnode
*mnode
, *mnnode
;
5775 struct listnode
*node
, *nnode
;
5778 struct peer_group
*group
;
5779 struct bgp_filter
*filter
;
5781 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5783 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5784 access
->name
, 0, 0);
5785 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5786 FOREACH_AFI_SAFI (afi
, safi
) {
5787 filter
= &peer
->filter
[afi
][safi
];
5789 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5791 if (filter
->dlist
[direct
].name
)
5792 filter
->dlist
[direct
]
5793 .alist
= access_list_lookup(
5795 filter
->dlist
[direct
]
5798 filter
->dlist
[direct
].alist
=
5803 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5804 FOREACH_AFI_SAFI (afi
, safi
) {
5805 filter
= &group
->conf
->filter
[afi
][safi
];
5807 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5809 if (filter
->dlist
[direct
].name
)
5810 filter
->dlist
[direct
]
5811 .alist
= access_list_lookup(
5813 filter
->dlist
[direct
]
5816 filter
->dlist
[direct
].alist
=
5821 #ifdef ENABLE_BGP_VNC
5822 vnc_prefix_list_update(bgp
);
5827 /* Set prefix list to the peer. */
5828 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5831 struct peer
*member
;
5832 struct bgp_filter
*filter
;
5833 struct listnode
*node
, *nnode
;
5835 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5836 return BGP_ERR_INVALID_VALUE
;
5838 /* Set configuration on peer. */
5839 filter
= &peer
->filter
[afi
][safi
];
5840 if (filter
->dlist
[direct
].name
)
5841 return BGP_ERR_PEER_FILTER_CONFLICT
;
5842 if (filter
->plist
[direct
].name
)
5843 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5844 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5845 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5847 /* Check if handling a regular peer. */
5848 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5849 /* Set override-flag and process peer route updates. */
5850 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5851 PEER_FT_PREFIX_LIST
);
5852 peer_on_policy_change(peer
, afi
, safi
,
5853 (direct
== FILTER_OUT
) ? 1 : 0);
5855 /* Skip peer-group mechanics for regular peers. */
5860 * Set configuration on all peer-group members, unless they are
5861 * explicitely overriding peer-group configuration.
5863 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5864 /* Skip peers with overridden configuration. */
5865 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5866 PEER_FT_PREFIX_LIST
))
5869 /* Set configuration on peer-group member. */
5870 filter
= &member
->filter
[afi
][safi
];
5871 if (filter
->plist
[direct
].name
)
5872 XFREE(MTYPE_BGP_FILTER_NAME
,
5873 filter
->plist
[direct
].name
);
5874 filter
->plist
[direct
].name
=
5875 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5876 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5878 /* Process peer route updates. */
5879 peer_on_policy_change(member
, afi
, safi
,
5880 (direct
== FILTER_OUT
) ? 1 : 0);
5886 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5889 struct peer
*member
;
5890 struct bgp_filter
*filter
;
5891 struct listnode
*node
, *nnode
;
5893 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5894 return BGP_ERR_INVALID_VALUE
;
5896 /* Unset override-flag unconditionally. */
5897 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5898 PEER_FT_PREFIX_LIST
);
5900 /* Inherit configuration from peer-group if peer is member. */
5901 if (peer_group_active(peer
)) {
5902 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5903 filter
[afi
][safi
].plist
[direct
].name
,
5904 MTYPE_BGP_FILTER_NAME
);
5905 PEER_ATTR_INHERIT(peer
, peer
->group
,
5906 filter
[afi
][safi
].plist
[direct
].plist
);
5908 /* Otherwise remove configuration from peer. */
5909 filter
= &peer
->filter
[afi
][safi
];
5910 if (filter
->plist
[direct
].name
)
5911 XFREE(MTYPE_BGP_FILTER_NAME
,
5912 filter
->plist
[direct
].name
);
5913 filter
->plist
[direct
].name
= NULL
;
5914 filter
->plist
[direct
].plist
= NULL
;
5917 /* Check if handling a regular peer. */
5918 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5919 /* Process peer route updates. */
5920 peer_on_policy_change(peer
, afi
, safi
,
5921 (direct
== FILTER_OUT
) ? 1 : 0);
5923 /* Skip peer-group mechanics for regular peers. */
5928 * Remove configuration on all peer-group members, unless they are
5929 * explicitely overriding peer-group configuration.
5931 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5932 /* Skip peers with overridden configuration. */
5933 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5934 PEER_FT_PREFIX_LIST
))
5937 /* Remove configuration on peer-group member. */
5938 filter
= &member
->filter
[afi
][safi
];
5939 if (filter
->plist
[direct
].name
)
5940 XFREE(MTYPE_BGP_FILTER_NAME
,
5941 filter
->plist
[direct
].name
);
5942 filter
->plist
[direct
].name
= NULL
;
5943 filter
->plist
[direct
].plist
= NULL
;
5945 /* Process peer route updates. */
5946 peer_on_policy_change(member
, afi
, safi
,
5947 (direct
== FILTER_OUT
) ? 1 : 0);
5953 /* Update prefix-list list. */
5954 static void peer_prefix_list_update(struct prefix_list
*plist
)
5956 struct listnode
*mnode
, *mnnode
;
5957 struct listnode
*node
, *nnode
;
5960 struct peer_group
*group
;
5961 struct bgp_filter
*filter
;
5966 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5969 * Update the prefix-list on update groups.
5971 update_group_policy_update(
5972 bgp
, BGP_POLICY_PREFIX_LIST
,
5973 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5975 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5976 FOREACH_AFI_SAFI (afi
, safi
) {
5977 filter
= &peer
->filter
[afi
][safi
];
5979 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5981 if (filter
->plist
[direct
].name
)
5982 filter
->plist
[direct
]
5983 .plist
= prefix_list_lookup(
5985 filter
->plist
[direct
]
5988 filter
->plist
[direct
].plist
=
5993 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5994 FOREACH_AFI_SAFI (afi
, safi
) {
5995 filter
= &group
->conf
->filter
[afi
][safi
];
5997 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5999 if (filter
->plist
[direct
].name
)
6000 filter
->plist
[direct
]
6001 .plist
= prefix_list_lookup(
6003 filter
->plist
[direct
]
6006 filter
->plist
[direct
].plist
=
6014 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6017 struct peer
*member
;
6018 struct bgp_filter
*filter
;
6019 struct listnode
*node
, *nnode
;
6021 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6022 return BGP_ERR_INVALID_VALUE
;
6024 /* Set configuration on peer. */
6025 filter
= &peer
->filter
[afi
][safi
];
6026 if (filter
->aslist
[direct
].name
)
6027 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
6028 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6029 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6031 /* Check if handling a regular peer. */
6032 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6033 /* Set override-flag and process peer route updates. */
6034 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6035 PEER_FT_FILTER_LIST
);
6036 peer_on_policy_change(peer
, afi
, safi
,
6037 (direct
== FILTER_OUT
) ? 1 : 0);
6039 /* Skip peer-group mechanics for regular peers. */
6044 * Set configuration on all peer-group members, unless they are
6045 * explicitely overriding peer-group configuration.
6047 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6048 /* Skip peers with overridden configuration. */
6049 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6050 PEER_FT_FILTER_LIST
))
6053 /* Set configuration on peer-group member. */
6054 filter
= &member
->filter
[afi
][safi
];
6055 if (filter
->aslist
[direct
].name
)
6056 XFREE(MTYPE_BGP_FILTER_NAME
,
6057 filter
->aslist
[direct
].name
);
6058 filter
->aslist
[direct
].name
=
6059 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6060 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6062 /* Process peer route updates. */
6063 peer_on_policy_change(member
, afi
, safi
,
6064 (direct
== FILTER_OUT
) ? 1 : 0);
6070 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6072 struct peer
*member
;
6073 struct bgp_filter
*filter
;
6074 struct listnode
*node
, *nnode
;
6076 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6077 return BGP_ERR_INVALID_VALUE
;
6079 /* Unset override-flag unconditionally. */
6080 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6081 PEER_FT_FILTER_LIST
);
6083 /* Inherit configuration from peer-group if peer is member. */
6084 if (peer_group_active(peer
)) {
6085 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6086 filter
[afi
][safi
].aslist
[direct
].name
,
6087 MTYPE_BGP_FILTER_NAME
);
6088 PEER_ATTR_INHERIT(peer
, peer
->group
,
6089 filter
[afi
][safi
].aslist
[direct
].aslist
);
6091 /* Otherwise remove configuration from peer. */
6092 filter
= &peer
->filter
[afi
][safi
];
6093 if (filter
->aslist
[direct
].name
)
6094 XFREE(MTYPE_BGP_FILTER_NAME
,
6095 filter
->aslist
[direct
].name
);
6096 filter
->aslist
[direct
].name
= NULL
;
6097 filter
->aslist
[direct
].aslist
= NULL
;
6100 /* Check if handling a regular peer. */
6101 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6102 /* Process peer route updates. */
6103 peer_on_policy_change(peer
, afi
, safi
,
6104 (direct
== FILTER_OUT
) ? 1 : 0);
6106 /* Skip peer-group mechanics for regular peers. */
6111 * Remove configuration on all peer-group members, unless they are
6112 * explicitely overriding peer-group configuration.
6114 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6115 /* Skip peers with overridden configuration. */
6116 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6117 PEER_FT_FILTER_LIST
))
6120 /* Remove configuration on peer-group member. */
6121 filter
= &member
->filter
[afi
][safi
];
6122 if (filter
->aslist
[direct
].name
)
6123 XFREE(MTYPE_BGP_FILTER_NAME
,
6124 filter
->aslist
[direct
].name
);
6125 filter
->aslist
[direct
].name
= NULL
;
6126 filter
->aslist
[direct
].aslist
= NULL
;
6128 /* Process peer route updates. */
6129 peer_on_policy_change(member
, afi
, safi
,
6130 (direct
== FILTER_OUT
) ? 1 : 0);
6136 static void peer_aslist_update(const char *aslist_name
)
6141 struct listnode
*mnode
, *mnnode
;
6142 struct listnode
*node
, *nnode
;
6145 struct peer_group
*group
;
6146 struct bgp_filter
*filter
;
6148 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6149 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6152 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6153 FOREACH_AFI_SAFI (afi
, safi
) {
6154 filter
= &peer
->filter
[afi
][safi
];
6156 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6158 if (filter
->aslist
[direct
].name
)
6159 filter
->aslist
[direct
]
6160 .aslist
= as_list_lookup(
6161 filter
->aslist
[direct
]
6164 filter
->aslist
[direct
].aslist
=
6169 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6170 FOREACH_AFI_SAFI (afi
, safi
) {
6171 filter
= &group
->conf
->filter
[afi
][safi
];
6173 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6175 if (filter
->aslist
[direct
].name
)
6176 filter
->aslist
[direct
]
6177 .aslist
= as_list_lookup(
6178 filter
->aslist
[direct
]
6181 filter
->aslist
[direct
].aslist
=
6189 static void peer_aslist_add(char *aslist_name
)
6191 peer_aslist_update(aslist_name
);
6192 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_ADDED
);
6195 static void peer_aslist_del(const char *aslist_name
)
6197 peer_aslist_update(aslist_name
);
6198 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6202 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6203 const char *name
, struct route_map
*route_map
)
6205 struct peer
*member
;
6206 struct bgp_filter
*filter
;
6207 struct listnode
*node
, *nnode
;
6209 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6210 return BGP_ERR_INVALID_VALUE
;
6212 /* Set configuration on peer. */
6213 filter
= &peer
->filter
[afi
][safi
];
6214 if (filter
->map
[direct
].name
) {
6215 /* If the neighbor is configured with the same route-map
6216 * again then, ignore the duplicate configuration.
6218 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6221 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6223 route_map_counter_decrement(filter
->map
[direct
].map
);
6224 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6225 filter
->map
[direct
].map
= route_map
;
6226 route_map_counter_increment(route_map
);
6228 /* Check if handling a regular peer. */
6229 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6230 /* Set override-flag and process peer route updates. */
6231 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6233 peer_on_policy_change(peer
, afi
, safi
,
6234 (direct
== RMAP_OUT
) ? 1 : 0);
6236 /* Skip peer-group mechanics for regular peers. */
6241 * Set configuration on all peer-group members, unless they are
6242 * explicitely overriding peer-group configuration.
6244 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6245 /* Skip peers with overridden configuration. */
6246 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6250 /* Set configuration on peer-group member. */
6251 filter
= &member
->filter
[afi
][safi
];
6252 if (filter
->map
[direct
].name
)
6253 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6254 route_map_counter_decrement(filter
->map
[direct
].map
);
6255 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6256 filter
->map
[direct
].map
= route_map
;
6257 route_map_counter_increment(route_map
);
6259 /* Process peer route updates. */
6260 peer_on_policy_change(member
, afi
, safi
,
6261 (direct
== RMAP_OUT
) ? 1 : 0);
6266 /* Unset route-map from the peer. */
6267 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6269 struct peer
*member
;
6270 struct bgp_filter
*filter
;
6271 struct listnode
*node
, *nnode
;
6273 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6274 return BGP_ERR_INVALID_VALUE
;
6276 /* Unset override-flag unconditionally. */
6277 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6279 /* Inherit configuration from peer-group if peer is member. */
6280 if (peer_group_active(peer
)) {
6281 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6282 filter
[afi
][safi
].map
[direct
].name
,
6283 MTYPE_BGP_FILTER_NAME
);
6284 PEER_ATTR_INHERIT(peer
, peer
->group
,
6285 filter
[afi
][safi
].map
[direct
].map
);
6287 /* Otherwise remove configuration from peer. */
6288 filter
= &peer
->filter
[afi
][safi
];
6289 if (filter
->map
[direct
].name
)
6290 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6291 route_map_counter_decrement(filter
->map
[direct
].map
);
6292 filter
->map
[direct
].name
= NULL
;
6293 filter
->map
[direct
].map
= NULL
;
6296 /* Check if handling a regular peer. */
6297 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6298 /* Process peer route updates. */
6299 peer_on_policy_change(peer
, afi
, safi
,
6300 (direct
== RMAP_OUT
) ? 1 : 0);
6302 /* Skip peer-group mechanics for regular peers. */
6307 * Remove configuration on all peer-group members, unless they are
6308 * explicitely overriding peer-group configuration.
6310 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6311 /* Skip peers with overridden configuration. */
6312 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6316 /* Remove configuration on peer-group member. */
6317 filter
= &member
->filter
[afi
][safi
];
6318 if (filter
->map
[direct
].name
)
6319 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6320 route_map_counter_decrement(filter
->map
[direct
].map
);
6321 filter
->map
[direct
].name
= NULL
;
6322 filter
->map
[direct
].map
= NULL
;
6324 /* Process peer route updates. */
6325 peer_on_policy_change(member
, afi
, safi
,
6326 (direct
== RMAP_OUT
) ? 1 : 0);
6332 /* Set unsuppress-map to the peer. */
6333 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6334 const char *name
, struct route_map
*route_map
)
6336 struct peer
*member
;
6337 struct bgp_filter
*filter
;
6338 struct listnode
*node
, *nnode
;
6340 /* Set configuration on peer. */
6341 filter
= &peer
->filter
[afi
][safi
];
6342 if (filter
->usmap
.name
)
6343 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6344 route_map_counter_decrement(filter
->usmap
.map
);
6345 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6346 filter
->usmap
.map
= route_map
;
6347 route_map_counter_increment(route_map
);
6349 /* Check if handling a regular peer. */
6350 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6351 /* Set override-flag and process peer route updates. */
6352 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6353 PEER_FT_UNSUPPRESS_MAP
);
6354 peer_on_policy_change(peer
, afi
, safi
, 1);
6356 /* Skip peer-group mechanics for regular peers. */
6361 * Set configuration on all peer-group members, unless they are
6362 * explicitely overriding peer-group configuration.
6364 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6365 /* Skip peers with overridden configuration. */
6366 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6367 PEER_FT_UNSUPPRESS_MAP
))
6370 /* Set configuration on peer-group member. */
6371 filter
= &member
->filter
[afi
][safi
];
6372 if (filter
->usmap
.name
)
6373 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6374 route_map_counter_decrement(filter
->usmap
.map
);
6375 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6376 filter
->usmap
.map
= route_map
;
6377 route_map_counter_increment(route_map
);
6379 /* Process peer route updates. */
6380 peer_on_policy_change(member
, afi
, safi
, 1);
6386 /* Unset route-map from the peer. */
6387 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6389 struct peer
*member
;
6390 struct bgp_filter
*filter
;
6391 struct listnode
*node
, *nnode
;
6393 /* Unset override-flag unconditionally. */
6394 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6396 /* Inherit configuration from peer-group if peer is member. */
6397 if (peer_group_active(peer
)) {
6398 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6399 filter
[afi
][safi
].usmap
.name
,
6400 MTYPE_BGP_FILTER_NAME
);
6401 PEER_ATTR_INHERIT(peer
, peer
->group
,
6402 filter
[afi
][safi
].usmap
.map
);
6404 /* Otherwise remove configuration from peer. */
6405 filter
= &peer
->filter
[afi
][safi
];
6406 if (filter
->usmap
.name
)
6407 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6408 route_map_counter_decrement(filter
->usmap
.map
);
6409 filter
->usmap
.name
= NULL
;
6410 filter
->usmap
.map
= NULL
;
6413 /* Check if handling a regular peer. */
6414 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6415 /* Process peer route updates. */
6416 peer_on_policy_change(peer
, afi
, safi
, 1);
6418 /* Skip peer-group mechanics for regular peers. */
6423 * Remove configuration on all peer-group members, unless they are
6424 * explicitely overriding peer-group configuration.
6426 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6427 /* Skip peers with overridden configuration. */
6428 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6429 PEER_FT_UNSUPPRESS_MAP
))
6432 /* Remove configuration on peer-group member. */
6433 filter
= &member
->filter
[afi
][safi
];
6434 if (filter
->usmap
.name
)
6435 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6436 route_map_counter_decrement(filter
->usmap
.map
);
6437 filter
->usmap
.name
= NULL
;
6438 filter
->usmap
.map
= NULL
;
6440 /* Process peer route updates. */
6441 peer_on_policy_change(member
, afi
, safi
, 1);
6447 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6448 uint32_t max
, uint8_t threshold
, int warning
,
6451 struct peer
*member
;
6452 struct listnode
*node
, *nnode
;
6454 /* Set flags and configuration on peer. */
6455 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6457 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6459 peer_af_flag_unset(peer
, afi
, safi
,
6460 PEER_FLAG_MAX_PREFIX_WARNING
);
6462 peer
->pmax
[afi
][safi
] = max
;
6463 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6464 peer
->pmax_restart
[afi
][safi
] = restart
;
6466 /* Check if handling a regular peer. */
6467 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6468 /* Re-check if peer violates maximum-prefix. */
6469 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6470 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6472 /* Skip peer-group mechanics for regular peers. */
6477 * Set flags and configuration on all peer-group members, unless they
6478 * are explicitely overriding peer-group configuration.
6480 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6481 /* Skip peers with overridden configuration. */
6482 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6483 PEER_FLAG_MAX_PREFIX
))
6486 /* Set flag and configuration on peer-group member. */
6487 member
->pmax
[afi
][safi
] = max
;
6488 member
->pmax_threshold
[afi
][safi
] = threshold
;
6489 member
->pmax_restart
[afi
][safi
] = restart
;
6491 SET_FLAG(member
->af_flags
[afi
][safi
],
6492 PEER_FLAG_MAX_PREFIX_WARNING
);
6494 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6495 PEER_FLAG_MAX_PREFIX_WARNING
);
6497 /* Re-check if peer violates maximum-prefix. */
6498 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6499 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6505 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6507 /* Inherit configuration from peer-group if peer is member. */
6508 if (peer_group_active(peer
)) {
6509 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6510 peer_af_flag_inherit(peer
, afi
, safi
,
6511 PEER_FLAG_MAX_PREFIX_WARNING
);
6512 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6513 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6514 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6519 /* Remove flags and configuration from peer. */
6520 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6521 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6522 peer
->pmax
[afi
][safi
] = 0;
6523 peer
->pmax_threshold
[afi
][safi
] = 0;
6524 peer
->pmax_restart
[afi
][safi
] = 0;
6527 * Remove flags and configuration from all peer-group members, unless
6528 * they are explicitely overriding peer-group configuration.
6530 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6531 struct peer
*member
;
6532 struct listnode
*node
;
6534 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6535 /* Skip peers with overridden configuration. */
6536 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6537 PEER_FLAG_MAX_PREFIX
))
6540 /* Remove flag and configuration on peer-group member.
6542 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6543 PEER_FLAG_MAX_PREFIX
);
6544 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6545 PEER_FLAG_MAX_PREFIX_WARNING
);
6546 member
->pmax
[afi
][safi
] = 0;
6547 member
->pmax_threshold
[afi
][safi
] = 0;
6548 member
->pmax_restart
[afi
][safi
] = 0;
6555 int is_ebgp_multihop_configured(struct peer
*peer
)
6557 struct peer_group
*group
;
6558 struct listnode
*node
, *nnode
;
6561 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6562 group
= peer
->group
;
6563 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6564 && (group
->conf
->ttl
!= BGP_DEFAULT_TTL
))
6567 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6568 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6569 && (peer1
->ttl
!= BGP_DEFAULT_TTL
))
6573 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6574 && (peer
->ttl
!= BGP_DEFAULT_TTL
))
6580 /* Set # of hops between us and BGP peer. */
6581 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6583 struct peer_group
*group
;
6584 struct listnode
*node
, *nnode
;
6587 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6588 gtsm_hops
, peer
->host
);
6590 /* We cannot configure ttl-security hops when ebgp-multihop is already
6591 set. For non peer-groups, the check is simple. For peer-groups,
6593 slightly messy, because we need to check both the peer-group
6595 and all peer-group members for any trace of ebgp-multihop
6597 before actually applying the ttl-security rules. Cisco really made a
6598 mess of this configuration parameter, and OpenBGPD got it right.
6601 if ((peer
->gtsm_hops
== BGP_GTSM_HOPS_DISABLED
)
6602 && (peer
->sort
!= BGP_PEER_IBGP
)) {
6603 if (is_ebgp_multihop_configured(peer
))
6604 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6606 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6607 peer
->gtsm_hops
= gtsm_hops
;
6609 /* Calling ebgp multihop also resets the session.
6610 * On restart, NHT will get setup correctly as will the
6611 * min & max ttls on the socket. The return value is
6614 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6619 group
= peer
->group
;
6620 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6622 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6624 /* Calling ebgp multihop also resets the
6626 * On restart, NHT will get setup correctly as
6628 * min & max ttls on the socket. The return
6632 peer_ebgp_multihop_set(peer
, MAXTTL
);
6636 /* Post the first gtsm setup or if its ibgp, maxttl setting
6638 * necessary, just set the minttl.
6640 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6641 peer
->gtsm_hops
= gtsm_hops
;
6644 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6645 MAXTTL
+ 1 - gtsm_hops
);
6646 if ((peer
->status
< Established
) && peer
->doppelganger
6647 && (peer
->doppelganger
->fd
>= 0))
6648 sockopt_minttl(peer
->su
.sa
.sa_family
,
6649 peer
->doppelganger
->fd
,
6650 MAXTTL
+ 1 - gtsm_hops
);
6652 group
= peer
->group
;
6653 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6655 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6657 /* Change setting of existing peer
6658 * established then change value (may break
6660 * not established yet (teardown session and
6662 * no session then do nothing (will get
6663 * handled by next connection)
6667 != BGP_GTSM_HOPS_DISABLED
)
6669 peer
->su
.sa
.sa_family
, peer
->fd
,
6670 MAXTTL
+ 1 - peer
->gtsm_hops
);
6671 if ((peer
->status
< Established
)
6672 && peer
->doppelganger
6673 && (peer
->doppelganger
->fd
>= 0))
6674 sockopt_minttl(peer
->su
.sa
.sa_family
,
6675 peer
->doppelganger
->fd
,
6676 MAXTTL
+ 1 - gtsm_hops
);
6684 int peer_ttl_security_hops_unset(struct peer
*peer
)
6686 struct peer_group
*group
;
6687 struct listnode
*node
, *nnode
;
6690 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6693 /* if a peer-group member, then reset to peer-group default rather than
6695 if (peer_group_active(peer
))
6696 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6698 peer
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
6700 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6701 /* Invoking ebgp_multihop_set will set the TTL back to the
6703 * value as well as restting the NHT and such. The session is
6706 if (peer
->sort
== BGP_PEER_EBGP
)
6707 ret
= peer_ebgp_multihop_unset(peer
);
6710 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6713 if ((peer
->status
< Established
) && peer
->doppelganger
6714 && (peer
->doppelganger
->fd
>= 0))
6715 sockopt_minttl(peer
->su
.sa
.sa_family
,
6716 peer
->doppelganger
->fd
, 0);
6719 group
= peer
->group
;
6720 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6721 peer
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
6722 if (peer
->sort
== BGP_PEER_EBGP
)
6723 ret
= peer_ebgp_multihop_unset(peer
);
6726 sockopt_minttl(peer
->su
.sa
.sa_family
,
6729 if ((peer
->status
< Established
)
6730 && peer
->doppelganger
6731 && (peer
->doppelganger
->fd
>= 0))
6732 sockopt_minttl(peer
->su
.sa
.sa_family
,
6733 peer
->doppelganger
->fd
,
6743 * If peer clear is invoked in a loop for all peers on the BGP instance,
6744 * it may end up freeing the doppelganger, and if this was the next node
6745 * to the current node, we would end up accessing the freed next node.
6746 * Pass along additional parameter which can be updated if next node
6747 * is freed; only required when walking the peer list on BGP instance.
6749 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6751 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6752 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6753 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6754 if (peer
->t_pmax_restart
) {
6755 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6756 if (bgp_debug_neighbor_events(peer
))
6758 "%s Maximum-prefix restart timer canceled",
6761 BGP_EVENT_ADD(peer
, BGP_Start
);
6765 peer
->v_start
= BGP_INIT_START_TIMER
;
6766 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6767 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6768 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6770 bgp_session_reset_safe(peer
, nnode
);
6775 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6776 enum bgp_clear_type stype
)
6778 struct peer_af
*paf
;
6780 if (peer
->status
!= Established
)
6783 if (!peer
->afc
[afi
][safi
])
6784 return BGP_ERR_AF_UNCONFIGURED
;
6786 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6788 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6789 /* Clear the "neighbor x.x.x.x default-originate" flag */
6790 paf
= peer_af_find(peer
, afi
, safi
);
6791 if (paf
&& paf
->subgroup
6792 && CHECK_FLAG(paf
->subgroup
->sflags
,
6793 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6794 UNSET_FLAG(paf
->subgroup
->sflags
,
6795 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6797 bgp_announce_route(peer
, afi
, safi
);
6800 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6801 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6802 PEER_CAP_ORF_PREFIX_SM_ADV
)
6803 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6804 PEER_CAP_ORF_PREFIX_RM_RCV
)
6805 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6806 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6807 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6808 uint8_t prefix_type
;
6810 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6811 PEER_CAP_ORF_PREFIX_RM_RCV
))
6812 prefix_type
= ORF_TYPE_PREFIX
;
6814 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6816 if (filter
->plist
[FILTER_IN
].plist
) {
6817 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6818 PEER_STATUS_ORF_PREFIX_SEND
))
6819 bgp_route_refresh_send(
6820 peer
, afi
, safi
, prefix_type
,
6822 bgp_route_refresh_send(peer
, afi
, safi
,
6824 REFRESH_IMMEDIATE
, 0);
6826 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6827 PEER_STATUS_ORF_PREFIX_SEND
))
6828 bgp_route_refresh_send(
6829 peer
, afi
, safi
, prefix_type
,
6830 REFRESH_IMMEDIATE
, 1);
6832 bgp_route_refresh_send(peer
, afi
, safi
,
6839 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6840 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6841 /* If neighbor has soft reconfiguration inbound flag.
6842 Use Adj-RIB-In database. */
6843 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6844 PEER_FLAG_SOFT_RECONFIG
))
6845 bgp_soft_reconfig_in(peer
, afi
, safi
);
6847 /* If neighbor has route refresh capability, send route
6849 message to the peer. */
6850 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6851 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6852 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6855 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6861 /* Display peer uptime.*/
6862 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6865 time_t uptime1
, epoch_tbuf
;
6868 /* If there is no connection has been done before print `never'. */
6871 json_object_string_add(json
, "peerUptime", "never");
6872 json_object_int_add(json
, "peerUptimeMsec", 0);
6874 snprintf(buf
, len
, "never");
6878 /* Get current time. */
6879 uptime1
= bgp_clock();
6881 gmtime_r(&uptime1
, &tm
);
6883 if (uptime1
< ONE_DAY_SECOND
)
6884 snprintf(buf
, len
, "%02d:%02d:%02d", tm
.tm_hour
, tm
.tm_min
,
6886 else if (uptime1
< ONE_WEEK_SECOND
)
6887 snprintf(buf
, len
, "%dd%02dh%02dm", tm
.tm_yday
, tm
.tm_hour
,
6889 else if (uptime1
< ONE_YEAR_SECOND
)
6890 snprintf(buf
, len
, "%02dw%dd%02dh", tm
.tm_yday
/ 7,
6891 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7), tm
.tm_hour
);
6893 snprintf(buf
, len
, "%02dy%02dw%dd", tm
.tm_year
- 70,
6895 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7));
6898 epoch_tbuf
= time(NULL
) - uptime1
;
6899 json_object_string_add(json
, "peerUptime", buf
);
6900 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6901 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6908 void bgp_master_init(struct thread_master
*master
, const int buffer_size
)
6912 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
6915 bm
->bgp
= list_new();
6916 bm
->listen_sockets
= list_new();
6917 bm
->port
= BGP_PORT_DEFAULT
;
6918 bm
->master
= master
;
6919 bm
->start_time
= bgp_clock();
6920 bm
->t_rmap_update
= NULL
;
6921 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
6922 bm
->terminating
= false;
6923 bm
->socket_buffer
= buffer_size
;
6925 bgp_process_queue_init();
6928 /* init the rd id space.
6929 assign 0th index in the bitfield,
6930 so that we start with id 1
6932 bf_init(bm
->rd_idspace
, UINT16_MAX
);
6933 bf_assign_zero_index(bm
->rd_idspace
);
6935 /* mpls label dynamic allocation pool */
6936 bgp_lp_init(bm
->master
, &bm
->labelpool
);
6938 QOBJ_REG(bm
, bgp_master
);
6942 * Free up connected routes and interfaces for a BGP instance. Invoked upon
6943 * instance delete (non-default only) or BGP exit.
6945 static void bgp_if_finish(struct bgp
*bgp
)
6948 struct interface
*ifp
;
6950 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
6952 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
6955 FOR_ALL_INTERFACES (vrf
, ifp
) {
6956 struct listnode
*c_node
, *c_nnode
;
6957 struct connected
*c
;
6959 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
6960 bgp_connected_delete(bgp
, c
);
6964 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
6966 struct vrf
*vrf
= NULL
;
6967 struct listnode
*next
;
6970 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
6971 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
6973 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6974 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
6977 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
6981 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
6983 struct listnode
*next
, *next2
;
6984 struct bgp
*bgp
, *bgp2
;
6987 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6989 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
6990 if (bgp2
->as
== bgp
->as
)
6998 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
6999 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
7003 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7004 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7005 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
7006 {.completions
= NULL
},
7009 struct frr_pthread
*bgp_pth_io
;
7010 struct frr_pthread
*bgp_pth_ka
;
7012 static void bgp_pthreads_init(void)
7014 assert(!bgp_pth_io
);
7015 assert(!bgp_pth_ka
);
7017 struct frr_pthread_attr io
= {
7018 .start
= frr_pthread_attr_default
.start
,
7019 .stop
= frr_pthread_attr_default
.stop
,
7021 struct frr_pthread_attr ka
= {
7022 .start
= bgp_keepalives_start
,
7023 .stop
= bgp_keepalives_stop
,
7025 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7026 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7029 void bgp_pthreads_run(void)
7031 frr_pthread_run(bgp_pth_io
, NULL
);
7032 frr_pthread_run(bgp_pth_ka
, NULL
);
7034 /* Wait until threads are ready. */
7035 frr_pthread_wait_running(bgp_pth_io
);
7036 frr_pthread_wait_running(bgp_pth_ka
);
7039 void bgp_pthreads_finish(void)
7041 frr_pthread_stop_all();
7044 void bgp_init(unsigned short instance
)
7047 /* allocates some vital data structures used by peer commands in
7050 /* pre-init pthreads */
7051 bgp_pthreads_init();
7054 bgp_zebra_init(bm
->master
, instance
);
7056 #ifdef ENABLE_BGP_VNC
7057 vnc_zebra_init(bm
->master
);
7060 /* BGP VTY commands installation. */
7068 bgp_route_map_init();
7069 bgp_scan_vty_init();
7071 #ifdef ENABLE_BGP_VNC
7074 bgp_ethernetvpn_init();
7075 bgp_flowspec_vty_init();
7077 /* Access list initialize. */
7079 access_list_add_hook(peer_distribute_update
);
7080 access_list_delete_hook(peer_distribute_update
);
7082 /* Filter list initialize. */
7084 as_list_add_hook(peer_aslist_add
);
7085 as_list_delete_hook(peer_aslist_del
);
7087 /* Prefix list initialize.*/
7089 prefix_list_add_hook(peer_prefix_list_update
);
7090 prefix_list_delete_hook(peer_prefix_list_update
);
7092 /* Community list initialize. */
7093 bgp_clist
= community_list_init();
7098 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7101 void bgp_terminate(void)
7105 struct listnode
*node
, *nnode
;
7106 struct listnode
*mnode
, *mnnode
;
7110 /* Close the listener sockets first as this prevents peers from
7112 * to reconnect on receiving the peer unconfig message. In the presence
7113 * of a large number of peers this will ensure that no peer is left with
7114 * a dangling connection
7116 /* reverse bgp_master_init */
7119 if (bm
->listen_sockets
)
7120 list_delete(&bm
->listen_sockets
);
7122 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7123 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7124 if (peer
->status
== Established
7125 || peer
->status
== OpenSent
7126 || peer
->status
== OpenConfirm
)
7127 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7128 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7130 if (bm
->process_main_queue
)
7131 work_queue_free_and_null(&bm
->process_main_queue
);
7133 if (bm
->t_rmap_update
)
7134 BGP_TIMER_OFF(bm
->t_rmap_update
);
7139 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
7140 const char *ip_str
, bool use_json
)
7146 /* Get peer sockunion. */
7147 ret
= str2sockunion(ip_str
, &su
);
7149 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
7151 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
7155 json_object
*json_no
= NULL
;
7156 json_no
= json_object_new_object();
7157 json_object_string_add(
7159 "malformedAddressOrName",
7161 vty_out(vty
, "%s\n",
7162 json_object_to_json_string_ext(
7164 JSON_C_TO_STRING_PRETTY
));
7165 json_object_free(json_no
);
7168 "%% Malformed address or name: %s\n",
7176 /* Peer structure lookup. */
7177 peer
= peer_lookup(bgp
, &su
);
7180 json_object
*json_no
= NULL
;
7181 json_no
= json_object_new_object();
7182 json_object_string_add(json_no
, "warning",
7183 "No such neighbor in this view/vrf");
7184 vty_out(vty
, "%s\n",
7185 json_object_to_json_string_ext(
7186 json_no
, JSON_C_TO_STRING_PRETTY
));
7187 json_object_free(json_no
);
7189 vty_out(vty
, "No such neighbor in this view/vrf\n");
7196 void bgp_gr_apply_running_config(void)
7198 struct peer
*peer
= NULL
;
7199 struct bgp
*bgp
= NULL
;
7200 struct listnode
*node
, *nnode
;
7201 bool gr_router_detected
= false;
7203 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
7204 zlog_debug("[BGP_GR] %s called !", __func__
);
7206 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
7207 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7208 bgp_peer_gr_flags_update(peer
);
7209 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
))
7210 gr_router_detected
= true;
7213 if (gr_router_detected
7214 && bgp
->present_zebra_gr_state
== ZEBRA_GR_DISABLE
) {
7215 bgp_zebra_send_capabilities(bgp
, true);
7216 } else if (!gr_router_detected
7217 && bgp
->present_zebra_gr_state
== ZEBRA_GR_ENABLE
) {
7218 bgp_zebra_send_capabilities(bgp
, false);
7221 gr_router_detected
= false;