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 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2180 return peer_activate(peer
, afi
, safi
);
2182 return peer_deactivate(peer
, afi
, safi
);
2185 void peer_nsf_stop(struct peer
*peer
)
2190 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2191 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2193 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2194 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2195 peer
->nsf
[afi
][safi
] = 0;
2197 if (peer
->t_gr_restart
) {
2198 BGP_TIMER_OFF(peer
->t_gr_restart
);
2199 if (bgp_debug_neighbor_events(peer
))
2200 zlog_debug("%s graceful restart timer stopped",
2203 if (peer
->t_gr_stale
) {
2204 BGP_TIMER_OFF(peer
->t_gr_stale
);
2205 if (bgp_debug_neighbor_events(peer
))
2207 "%s graceful restart stalepath timer stopped",
2210 bgp_clear_route_all(peer
);
2213 /* Delete peer from confguration.
2215 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2216 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2218 * This function /should/ take care to be idempotent, to guard against
2219 * it being called multiple times through stray events that come in
2220 * that happen to result in this function being called again. That
2221 * said, getting here for a "Deleted" peer is a bug in the neighbour
2224 int peer_delete(struct peer
*peer
)
2230 struct bgp_filter
*filter
;
2231 struct listnode
*pn
;
2234 assert(peer
->status
!= Deleted
);
2237 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2239 bgp_keepalives_off(peer
);
2240 bgp_reads_off(peer
);
2241 bgp_writes_off(peer
);
2242 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2243 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2244 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_KEEPALIVES_ON
));
2246 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2247 peer_nsf_stop(peer
);
2249 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2251 bgp_bfd_deregister_peer(peer
);
2253 /* If this peer belongs to peer group, clear up the
2256 if (peer_dynamic_neighbor(peer
))
2257 peer_drop_dynamic_neighbor(peer
);
2259 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2261 peer
); /* group->peer list reference */
2262 list_delete_node(peer
->group
->peer
, pn
);
2267 /* Withdraw all information from routing table. We can not use
2268 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2269 * executed after peer structure is deleted.
2271 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2273 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2275 if (peer
->doppelganger
) {
2276 peer
->doppelganger
->doppelganger
= NULL
;
2277 peer
->doppelganger
= NULL
;
2280 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2281 bgp_fsm_change_status(peer
, Deleted
);
2283 /* Remove from NHT */
2284 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2285 bgp_unlink_nexthop_by_peer(peer
);
2287 /* Password configuration */
2288 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2289 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2291 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2292 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2293 bgp_md5_unset(peer
);
2296 bgp_timer_set(peer
); /* stops all timers for Deleted */
2298 /* Delete from all peer list. */
2299 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2300 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2301 peer_unlock(peer
); /* bgp peer list reference */
2302 list_delete_node(bgp
->peer
, pn
);
2303 hash_release(bgp
->peerhash
, peer
);
2308 stream_fifo_free(peer
->ibuf
);
2313 stream_fifo_free(peer
->obuf
);
2317 if (peer
->ibuf_work
) {
2318 ringbuf_del(peer
->ibuf_work
);
2319 peer
->ibuf_work
= NULL
;
2322 if (peer
->obuf_work
) {
2323 stream_free(peer
->obuf_work
);
2324 peer
->obuf_work
= NULL
;
2327 if (peer
->scratch
) {
2328 stream_free(peer
->scratch
);
2329 peer
->scratch
= NULL
;
2332 /* Local and remote addresses. */
2333 if (peer
->su_local
) {
2334 sockunion_free(peer
->su_local
);
2335 peer
->su_local
= NULL
;
2338 if (peer
->su_remote
) {
2339 sockunion_free(peer
->su_remote
);
2340 peer
->su_remote
= NULL
;
2343 /* Free filter related memory. */
2344 FOREACH_AFI_SAFI (afi
, safi
) {
2345 filter
= &peer
->filter
[afi
][safi
];
2347 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2348 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
2349 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
2350 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
2353 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2354 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
2357 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2358 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
2361 FOREACH_AFI_SAFI (afi
, safi
)
2362 peer_af_delete(peer
, afi
, safi
);
2364 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2365 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2367 peer_unlock(peer
); /* initial reference */
2372 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2374 return strcmp(g1
->name
, g2
->name
);
2377 /* Peer group cofiguration. */
2378 static struct peer_group
*peer_group_new(void)
2380 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2383 static void peer_group_free(struct peer_group
*group
)
2385 XFREE(MTYPE_PEER_GROUP
, group
);
2388 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2390 struct peer_group
*group
;
2391 struct listnode
*node
, *nnode
;
2393 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2394 if (strcmp(group
->name
, name
) == 0)
2400 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2402 struct peer_group
*group
;
2405 group
= peer_group_lookup(bgp
, name
);
2409 group
= peer_group_new();
2411 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2412 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2413 group
->peer
= list_new();
2414 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2415 group
->listen_range
[afi
] = list_new();
2416 group
->conf
= peer_new(bgp
);
2417 if (!CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_DEFAULT_IPV4
))
2418 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2419 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2420 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2421 group
->conf
->group
= group
;
2422 group
->conf
->as
= 0;
2423 group
->conf
->ttl
= BGP_DEFAULT_TTL
;
2424 group
->conf
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
2425 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2426 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2427 listnode_add_sort(bgp
->group
, group
);
2432 static void peer_group2peer_config_copy(struct peer_group
*group
,
2442 peer
->as
= conf
->as
;
2445 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2446 peer
->change_local_as
= conf
->change_local_as
;
2448 /* If peer-group has configured TTL then override it */
2449 if (conf
->ttl
!= BGP_DEFAULT_TTL
)
2450 peer
->ttl
= conf
->ttl
;
2453 peer
->gtsm_hops
= conf
->gtsm_hops
;
2455 /* peer flags apply */
2456 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2457 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2458 flags_tmp
&= ~peer
->flags_override
;
2460 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2461 SET_FLAG(peer
->flags
, flags_tmp
);
2462 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2464 /* peer timers apply */
2465 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2466 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2467 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2470 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2471 PEER_ATTR_INHERIT(peer
, group
, connect
);
2472 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2473 peer
->v_connect
= conf
->connect
;
2475 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
2478 /* advertisement-interval apply */
2479 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2480 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2481 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2482 peer
->v_routeadv
= conf
->routeadv
;
2484 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2485 ? BGP_DEFAULT_IBGP_ROUTEADV
2486 : BGP_DEFAULT_EBGP_ROUTEADV
;
2489 /* capability extended-nexthop apply */
2490 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_CAPABILITY_ENHE
))
2491 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2492 SET_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
);
2494 /* password apply */
2495 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2496 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2497 MTYPE_PEER_PASSWORD
);
2499 if (!BGP_PEER_SU_UNSPEC(peer
))
2502 /* update-source apply */
2503 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2504 if (conf
->update_source
) {
2505 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2506 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2507 } else if (conf
->update_if
) {
2508 sockunion_free(peer
->update_source
);
2509 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2510 MTYPE_PEER_UPDATE_SOURCE
);
2514 /* Update GR flags for the peer. */
2515 bgp_peer_gr_flags_update(peer
);
2517 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2520 /* Peer group's remote AS configuration. */
2521 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2524 struct peer_group
*group
;
2526 struct listnode
*node
, *nnode
;
2528 group
= peer_group_lookup(bgp
, group_name
);
2532 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2536 /* When we setup peer-group AS number all peer group member's AS
2537 number must be updated to same number. */
2538 peer_as_change(group
->conf
, *as
, as_type
);
2540 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2541 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2542 || (peer
->as_type
!= as_type
))
2543 peer_as_change(peer
, *as
, as_type
);
2549 void peer_notify_unconfig(struct peer
*peer
)
2551 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2552 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2553 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
2556 void peer_group_notify_unconfig(struct peer_group
*group
)
2558 struct peer
*peer
, *other
;
2559 struct listnode
*node
, *nnode
;
2561 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2562 other
= peer
->doppelganger
;
2563 if (other
&& other
->status
!= Deleted
) {
2564 other
->group
= NULL
;
2565 peer_notify_unconfig(other
);
2567 peer_notify_unconfig(peer
);
2571 int peer_group_delete(struct peer_group
*group
)
2575 struct prefix
*prefix
;
2577 struct listnode
*node
, *nnode
;
2582 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2583 other
= peer
->doppelganger
;
2585 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2586 bgp_zebra_terminate_radv(bgp
, peer
);
2589 if (other
&& other
->status
!= Deleted
) {
2590 other
->group
= NULL
;
2594 list_delete(&group
->peer
);
2596 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2597 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2599 prefix_free(&prefix
);
2601 list_delete(&group
->listen_range
[afi
]);
2604 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2607 bfd_info_free(&(group
->conf
->bfd_info
));
2609 group
->conf
->group
= NULL
;
2610 peer_delete(group
->conf
);
2612 /* Delete from all peer_group list. */
2613 listnode_delete(bgp
->group
, group
);
2615 peer_group_free(group
);
2620 int peer_group_remote_as_delete(struct peer_group
*group
)
2622 struct peer
*peer
, *other
;
2623 struct listnode
*node
, *nnode
;
2625 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2626 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2629 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2630 other
= peer
->doppelganger
;
2632 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2633 bgp_zebra_terminate_radv(peer
->bgp
, peer
);
2637 if (other
&& other
->status
!= Deleted
) {
2638 other
->group
= NULL
;
2642 list_delete_all_node(group
->peer
);
2644 group
->conf
->as
= 0;
2645 group
->conf
->as_type
= AS_UNSPECIFIED
;
2650 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2652 struct prefix
*prefix
;
2653 struct listnode
*node
, *nnode
;
2656 afi
= family2afi(range
->family
);
2658 /* Group needs remote AS configured. */
2659 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2660 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2662 /* Ensure no duplicates. Currently we don't care about overlaps. */
2663 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2664 if (prefix_same(range
, prefix
))
2668 prefix
= prefix_new();
2669 prefix_copy(prefix
, range
);
2670 listnode_add(group
->listen_range
[afi
], prefix
);
2672 /* Update passwords for new ranges */
2673 if (group
->conf
->password
)
2674 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2679 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2681 struct prefix
*prefix
, prefix2
;
2682 struct listnode
*node
, *nnode
;
2685 char buf
[PREFIX2STR_BUFFER
];
2687 afi
= family2afi(range
->family
);
2689 /* Identify the listen range. */
2690 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2691 if (prefix_same(range
, prefix
))
2696 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2698 prefix2str(prefix
, buf
, sizeof(buf
));
2700 /* Dispose off any dynamic neighbors that exist due to this listen range
2702 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2703 if (!peer_dynamic_neighbor(peer
))
2706 sockunion2hostprefix(&peer
->su
, &prefix2
);
2707 if (prefix_match(prefix
, &prefix2
)) {
2708 if (bgp_debug_neighbor_events(peer
))
2710 "Deleting dynamic neighbor %s group %s upon delete of listen range %s",
2711 peer
->host
, group
->name
, buf
);
2716 /* Get rid of the listen range */
2717 listnode_delete(group
->listen_range
[afi
], prefix
);
2719 /* Remove passwords for deleted ranges */
2720 if (group
->conf
->password
)
2721 bgp_md5_unset_prefix(prefix
);
2726 /* Bind specified peer to peer group. */
2727 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2728 struct peer_group
*group
, as_t
*as
)
2730 int first_member
= 0;
2733 bgp_peer_sort_t ptype
, gtype
;
2735 /* Lookup the peer. */
2737 peer
= peer_lookup(bgp
, su
);
2739 /* The peer exist, bind it to the peer-group */
2741 /* When the peer already belongs to a peer-group, check the
2743 if (peer_group_active(peer
)) {
2745 /* The peer is already bound to the peer-group,
2748 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2751 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2754 /* The peer has not specified a remote-as, inherit it from the
2756 if (peer
->as_type
== AS_UNSPECIFIED
) {
2757 peer
->as_type
= group
->conf
->as_type
;
2758 peer
->as
= group
->conf
->as
;
2759 peer
->sort
= group
->conf
->sort
;
2762 ptype
= peer_sort(peer
);
2763 if (!group
->conf
->as
&& ptype
!= BGP_PEER_UNSPECIFIED
) {
2764 gtype
= peer_sort(group
->conf
);
2765 if ((gtype
!= BGP_PEER_INTERNAL
) && (gtype
!= ptype
)) {
2768 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2771 if (gtype
== BGP_PEER_INTERNAL
)
2775 peer_group2peer_config_copy(group
, peer
);
2777 FOREACH_AFI_SAFI (afi
, safi
) {
2778 if (group
->conf
->afc
[afi
][safi
]) {
2779 peer
->afc
[afi
][safi
] = 1;
2781 if (peer_af_find(peer
, afi
, safi
)
2782 || peer_af_create(peer
, afi
, safi
)) {
2783 peer_group2peer_config_copy_af(
2784 group
, peer
, afi
, safi
);
2786 } else if (peer
->afc
[afi
][safi
])
2787 peer_deactivate(peer
, afi
, safi
);
2791 assert(group
&& peer
->group
== group
);
2793 listnode_delete(bgp
->peer
, peer
);
2795 peer
->group
= group
;
2796 listnode_add_sort(bgp
->peer
, peer
);
2798 peer
= peer_lock(peer
); /* group->peer list reference */
2799 listnode_add(group
->peer
, peer
);
2803 gtype
= peer_sort(group
->conf
);
2804 /* Advertisement-interval reset */
2805 if (!CHECK_FLAG(group
->conf
->flags
,
2806 PEER_FLAG_ROUTEADV
)) {
2807 group
->conf
->v_routeadv
=
2808 (gtype
== BGP_PEER_IBGP
)
2809 ? BGP_DEFAULT_IBGP_ROUTEADV
2810 : BGP_DEFAULT_EBGP_ROUTEADV
;
2813 /* ebgp-multihop reset */
2814 if (gtype
== BGP_PEER_IBGP
)
2815 group
->conf
->ttl
= MAXTTL
;
2817 /* local-as reset */
2818 if (gtype
!= BGP_PEER_EBGP
) {
2819 group
->conf
->change_local_as
= 0;
2820 peer_flag_unset(group
->conf
,
2821 PEER_FLAG_LOCAL_AS
);
2822 peer_flag_unset(group
->conf
,
2823 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2824 peer_flag_unset(group
->conf
,
2825 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2829 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2831 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2832 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2833 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2834 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2836 bgp_session_reset(peer
);
2840 /* Create a new peer. */
2842 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2843 && (!group
->conf
->as
)) {
2844 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2847 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2848 group
->conf
->as_type
, 0, 0, group
);
2850 peer
= peer_lock(peer
); /* group->peer list reference */
2851 listnode_add(group
->peer
, peer
);
2853 peer_group2peer_config_copy(group
, peer
);
2855 /* If the peer-group is active for this afi/safi then activate
2857 FOREACH_AFI_SAFI (afi
, safi
) {
2858 if (group
->conf
->afc
[afi
][safi
]) {
2859 peer
->afc
[afi
][safi
] = 1;
2860 peer_af_create(peer
, afi
, safi
);
2861 peer_group2peer_config_copy_af(group
, peer
, afi
,
2863 } else if (peer
->afc
[afi
][safi
])
2864 peer_deactivate(peer
, afi
, safi
);
2867 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2869 /* Set up peer's events and timers. */
2870 if (peer_active(peer
))
2871 bgp_timer_set(peer
);
2877 static int bgp_startup_timer_expire(struct thread
*thread
)
2881 bgp
= THREAD_ARG(thread
);
2882 bgp
->t_startup
= NULL
;
2888 * On shutdown we call the cleanup function which
2889 * does a free of the link list nodes, free up
2890 * the data we are pointing at too.
2892 static void bgp_vrf_string_name_delete(void *data
)
2896 XFREE(MTYPE_TMP
, vname
);
2899 /* BGP instance creation by `router bgp' commands. */
2900 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2901 enum bgp_instance_type inst_type
)
2907 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2910 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2911 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2912 zlog_debug("Creating Default VRF, AS %u", *as
);
2914 zlog_debug("Creating %s %s, AS %u",
2915 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2921 /* Default the EVPN VRF to the default one */
2922 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
2928 bgp
->heuristic_coalesce
= true;
2929 bgp
->inst_type
= inst_type
;
2930 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2932 bgp
->peer_self
= peer_new(bgp
);
2933 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2934 bgp
->peer_self
->host
=
2935 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2936 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2937 if (cmd_hostname_get())
2938 bgp
->peer_self
->hostname
=
2939 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2941 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2942 if (cmd_domainname_get())
2943 bgp
->peer_self
->domainname
=
2944 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2945 bgp
->peer
= list_new();
2946 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2947 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2949 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2951 bgp
->group
= list_new();
2952 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2954 FOREACH_AFI_SAFI (afi
, safi
) {
2955 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2956 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2957 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2959 /* Enable maximum-paths */
2960 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2962 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2964 /* Initialize graceful restart info */
2965 bgp
->gr_info
[afi
][safi
].eor_required
= 0;
2966 bgp
->gr_info
[afi
][safi
].eor_received
= 0;
2967 bgp
->gr_info
[afi
][safi
].t_select_deferral
= NULL
;
2968 bgp
->gr_info
[afi
][safi
].t_route_select
= NULL
;
2969 bgp
->gr_info
[afi
][safi
].route_list
= list_new();
2972 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2973 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2974 bgp
->default_subgroup_pkt_queue_max
=
2975 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2976 bgp_timers_unset(bgp
);
2977 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2978 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2979 bgp
->select_defer_time
= BGP_DEFAULT_SELECT_DEFERRAL_TIME
;
2980 bgp
->rib_stale_time
= BGP_DEFAULT_RIB_STALE_TIME
;
2981 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2982 bgp
->dynamic_neighbors_count
= 0;
2983 bgp
->lb_ref_bw
= BGP_LINK_BW_REF_BW
;
2984 bgp
->lb_handling
= BGP_LINK_BW_ECMP
;
2985 bgp
->reject_as_sets
= false;
2986 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2990 #ifdef ENABLE_BGP_VNC
2991 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2992 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2994 assert(bgp
->rfapi_cfg
);
2996 #endif /* ENABLE_BGP_VNC */
2998 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2999 bgp
->vpn_policy
[afi
].bgp
= bgp
;
3000 bgp
->vpn_policy
[afi
].afi
= afi
;
3001 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
3002 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
3005 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
3006 bgp
->vpn_policy
[afi
].import_vrf
->del
=
3007 bgp_vrf_string_name_delete
;
3008 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
3009 bgp
->vpn_policy
[afi
].export_vrf
->del
=
3010 bgp_vrf_string_name_delete
;
3013 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
3015 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3016 bgp
->restart_time
, &bgp
->t_startup
);
3018 /* printable name we can use in debug messages */
3019 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3020 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3030 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3032 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3033 snprintf(bgp
->name_pretty
, len
, "%s %s",
3034 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3040 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3041 memory_order_relaxed
);
3042 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3043 memory_order_relaxed
);
3044 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3048 update_bgp_group_init(bgp
);
3050 /* assign a unique rd id for auto derivation of vrf's RD */
3051 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3053 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3054 sizeof(struct bgp_evpn_info
));
3059 /*initilize global GR FSM */
3060 bgp_global_gr_init(bgp
);
3064 /* Return the "default VRF" instance of BGP. */
3065 struct bgp
*bgp_get_default(void)
3068 struct listnode
*node
, *nnode
;
3070 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3071 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3076 /* Lookup BGP entry. */
3077 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3080 struct listnode
*node
, *nnode
;
3082 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3084 && ((bgp
->name
== NULL
&& name
== NULL
)
3085 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3090 /* Lookup BGP structure by view name. */
3091 struct bgp
*bgp_lookup_by_name(const char *name
)
3094 struct listnode
*node
, *nnode
;
3096 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3097 if ((bgp
->name
== NULL
&& name
== NULL
)
3098 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3103 /* Lookup BGP instance based on VRF id. */
3104 /* Note: Only to be used for incoming messages from Zebra. */
3105 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3109 /* Lookup VRF (in tree) and follow link. */
3110 vrf
= vrf_lookup_by_id(vrf_id
);
3113 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3116 /* Sets the BGP instance where EVPN is enabled */
3117 void bgp_set_evpn(struct bgp
*bgp
)
3119 if (bm
->bgp_evpn
== bgp
)
3122 /* First, release the reference count we hold on the instance */
3124 bgp_unlock(bm
->bgp_evpn
);
3128 /* Increase the reference count on this new VRF */
3130 bgp_lock(bm
->bgp_evpn
);
3133 /* Returns the BGP instance where EVPN is enabled, if any */
3134 struct bgp
*bgp_get_evpn(void)
3136 return bm
->bgp_evpn
;
3139 /* handle socket creation or deletion, if necessary
3140 * this is called for all new BGP instances
3142 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3147 /* Create BGP server socket, if listen mode not disabled */
3148 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3150 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3152 * suppress vrf socket
3155 bgp_close_vrf_socket(bgp
);
3159 return BGP_ERR_INVALID_VALUE
;
3161 * if vrf_id did not change
3163 if (vrf
->vrf_id
== old_vrf_id
)
3165 if (old_vrf_id
!= VRF_UNKNOWN
) {
3166 /* look for old socket. close it. */
3167 bgp_close_vrf_socket(bgp
);
3169 /* if backend is not yet identified ( VRF_UNKNOWN) then
3170 * creation will be done later
3172 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3174 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3176 return BGP_ERR_INVALID_VALUE
;
3179 return bgp_check_main_socket(create
, bgp
);
3182 /* Called from VTY commands. */
3183 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3184 enum bgp_instance_type inst_type
)
3187 struct vrf
*vrf
= NULL
;
3189 /* Multiple instance check. */
3191 bgp
= bgp_lookup_by_name(name
);
3193 bgp
= bgp_get_default();
3195 /* Already exists. */
3197 if (bgp
->as
!= *as
) {
3199 return BGP_ERR_INSTANCE_MISMATCH
;
3201 if (bgp
->inst_type
!= inst_type
)
3202 return BGP_ERR_INSTANCE_MISMATCH
;
3207 bgp
= bgp_create(as
, name
, inst_type
);
3208 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3209 bgp
->vrf_id
= vrf_generate_id();
3210 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3211 bgp_address_init(bgp
);
3212 bgp_tip_hash_init(bgp
);
3216 bgp
->t_rmap_def_originate_eval
= NULL
;
3218 /* If Default instance or VRF, link to the VRF structure, if present. */
3219 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3220 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3221 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3223 bgp_vrf_link(bgp
, vrf
);
3225 /* BGP server socket already processed if BGP instance
3226 * already part of the list
3228 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3229 listnode_add(bm
->bgp
, bgp
);
3231 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3232 if (BGP_DEBUG(zebra
, ZEBRA
))
3233 zlog_debug("%s: Registering BGP instance %s to zebra",
3235 bgp_zebra_instance_register(bgp
);
3242 * Make BGP instance "up". Applies only to VRFs (non-default) and
3243 * implies the VRF has been learnt from Zebra.
3245 void bgp_instance_up(struct bgp
*bgp
)
3248 struct listnode
*node
, *next
;
3250 /* Register with zebra. */
3251 bgp_zebra_instance_register(bgp
);
3253 /* Kick off any peers that may have been configured. */
3254 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3255 if (!BGP_PEER_START_SUPPRESSED(peer
))
3256 BGP_EVENT_ADD(peer
, BGP_Start
);
3259 /* Process any networks that have been configured. */
3260 bgp_static_add(bgp
);
3264 * Make BGP instance "down". Applies only to VRFs (non-default) and
3265 * implies the VRF has been deleted by Zebra.
3267 void bgp_instance_down(struct bgp
*bgp
)
3270 struct listnode
*node
;
3271 struct listnode
*next
;
3274 if (bgp
->t_rmap_def_originate_eval
) {
3275 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3276 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3280 /* Bring down peers, so corresponding routes are purged. */
3281 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3282 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3283 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3284 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3286 bgp_session_reset(peer
);
3289 /* Purge network and redistributed routes. */
3290 bgp_purge_static_redist_routes(bgp
);
3292 /* Cleanup registered nexthops (flags) */
3293 bgp_cleanup_nexthops(bgp
);
3296 /* Delete BGP instance. */
3297 int bgp_delete(struct bgp
*bgp
)
3300 struct peer_group
*group
;
3301 struct listnode
*node
, *next
;
3306 struct graceful_restart_info
*gr_info
;
3310 hook_call(bgp_inst_delete
, bgp
);
3312 THREAD_OFF(bgp
->t_startup
);
3313 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3314 THREAD_OFF(bgp
->t_update_delay
);
3315 THREAD_OFF(bgp
->t_establish_wait
);
3317 /* Set flag indicating bgp instance delete in progress */
3318 SET_FLAG(bgp
->flags
, BGP_FLAG_DELETE_IN_PROGRESS
);
3320 /* Delete the graceful restart info */
3321 FOREACH_AFI_SAFI (afi
, safi
) {
3322 gr_info
= &bgp
->gr_info
[afi
][safi
];
3326 BGP_TIMER_OFF(gr_info
->t_select_deferral
);
3327 BGP_TIMER_OFF(gr_info
->t_route_select
);
3328 if (gr_info
->route_list
)
3329 list_delete(&gr_info
->route_list
);
3332 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3333 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3334 zlog_debug("Deleting Default VRF");
3336 zlog_debug("Deleting %s %s",
3337 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3343 /* unmap from RT list */
3344 bgp_evpn_vrf_delete(bgp
);
3346 /* unmap bgp vrf label */
3347 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3348 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3351 if (bgp
->t_rmap_def_originate_eval
) {
3352 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3353 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3357 /* Inform peers we're going down. */
3358 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3359 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3360 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3361 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3364 /* Delete static routes (networks). */
3365 bgp_static_delete(bgp
);
3367 /* Unset redistribution. */
3368 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3369 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3370 if (i
!= ZEBRA_ROUTE_BGP
)
3371 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3373 /* Free peers and peer-groups. */
3374 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3375 peer_group_delete(group
);
3377 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3380 if (bgp
->peer_self
) {
3381 peer_delete(bgp
->peer_self
);
3382 bgp
->peer_self
= NULL
;
3385 update_bgp_group_free(bgp
);
3387 /* TODO - Other memory may need to be freed - e.g., NHT */
3389 #ifdef ENABLE_BGP_VNC
3392 bgp_cleanup_routes(bgp
);
3394 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3395 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3398 &bgp
->vpn_policy
[afi
]
3399 .import_redirect_rtlist
);
3400 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3403 /* Deregister from Zebra, if needed */
3404 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3405 if (BGP_DEBUG(zebra
, ZEBRA
))
3407 "%s: deregistering this bgp %s instance from zebra",
3408 __func__
, bgp
->name
);
3409 bgp_zebra_instance_deregister(bgp
);
3412 /* Remove visibility via the master list - there may however still be
3413 * routes to be processed still referencing the struct bgp.
3415 listnode_delete(bm
->bgp
, bgp
);
3417 /* Free interfaces in this instance. */
3420 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3421 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3423 bgp_vrf_unlink(bgp
, vrf
);
3425 /* Update EVPN VRF pointer */
3426 if (bm
->bgp_evpn
== bgp
) {
3427 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3430 bgp_set_evpn(bgp_get_default());
3433 thread_master_free_unused(bm
->master
);
3434 bgp_unlock(bgp
); /* initial reference */
3439 void bgp_free(struct bgp
*bgp
)
3443 struct bgp_table
*table
;
3444 struct bgp_dest
*dest
;
3445 struct bgp_rmap
*rmap
;
3449 list_delete(&bgp
->group
);
3450 list_delete(&bgp
->peer
);
3452 if (bgp
->peerhash
) {
3453 hash_free(bgp
->peerhash
);
3454 bgp
->peerhash
= NULL
;
3457 FOREACH_AFI_SAFI (afi
, safi
) {
3458 /* Special handling for 2-level routing tables. */
3459 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3460 || safi
== SAFI_EVPN
) {
3461 for (dest
= bgp_table_top(bgp
->rib
[afi
][safi
]); dest
;
3462 dest
= bgp_route_next(dest
)) {
3463 table
= bgp_dest_get_bgp_table_info(dest
);
3464 bgp_table_finish(&table
);
3467 if (bgp
->route
[afi
][safi
])
3468 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3469 if (bgp
->aggregate
[afi
][safi
])
3470 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3471 if (bgp
->rib
[afi
][safi
])
3472 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3473 rmap
= &bgp
->table_map
[afi
][safi
];
3474 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3477 bgp_scan_finish(bgp
);
3478 bgp_address_destroy(bgp
);
3479 bgp_tip_hash_destroy(bgp
);
3481 /* release the auto RD id */
3482 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3484 bgp_evpn_cleanup(bgp
);
3485 bgp_pbr_cleanup(bgp
);
3486 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3488 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3489 vpn_policy_direction_t dir
;
3491 if (bgp
->vpn_policy
[afi
].import_vrf
)
3492 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3493 if (bgp
->vpn_policy
[afi
].export_vrf
)
3494 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3496 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3497 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3498 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3499 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3500 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3501 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3504 XFREE(MTYPE_BGP
, bgp
->name
);
3505 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3507 XFREE(MTYPE_BGP
, bgp
);
3510 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3513 struct listnode
*node
, *nnode
;
3519 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3520 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3521 && !CHECK_FLAG(peer
->sflags
,
3522 PEER_STATUS_ACCEPT_PEER
))
3524 } else if (bm
->bgp
!= NULL
) {
3525 struct listnode
*bgpnode
, *nbgpnode
;
3527 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3528 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3530 && !strcmp(peer
->conf_if
, conf_if
)
3531 && !CHECK_FLAG(peer
->sflags
,
3532 PEER_STATUS_ACCEPT_PEER
))
3538 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3541 struct listnode
*node
, *nnode
;
3547 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3548 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3549 && !CHECK_FLAG(peer
->sflags
,
3550 PEER_STATUS_ACCEPT_PEER
))
3552 } else if (bm
->bgp
!= NULL
) {
3553 struct listnode
*bgpnode
, *nbgpnode
;
3555 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3556 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3558 && !strcmp(peer
->hostname
, hostname
)
3559 && !CHECK_FLAG(peer
->sflags
,
3560 PEER_STATUS_ACCEPT_PEER
))
3566 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3568 struct peer
*peer
= NULL
;
3569 struct peer tmp_peer
;
3571 memset(&tmp_peer
, 0, sizeof(struct peer
));
3574 * We do not want to find the doppelganger peer so search for the peer
3576 * the hash that has PEER_FLAG_CONFIG_NODE
3578 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3583 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3584 } else if (bm
->bgp
!= NULL
) {
3585 struct listnode
*bgpnode
, *nbgpnode
;
3587 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3588 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3597 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3598 union sockunion
*su
,
3599 struct peer_group
*group
)
3605 /* Create peer first; we've already checked group config is valid. */
3606 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3607 group
->conf
->as_type
, 0, 0, group
);
3612 peer
= peer_lock(peer
);
3613 listnode_add(group
->peer
, peer
);
3615 peer_group2peer_config_copy(group
, peer
);
3618 * Bind peer for all AFs configured for the group. We don't call
3619 * peer_group_bind as that is sub-optimal and does some stuff we don't
3622 FOREACH_AFI_SAFI (afi
, safi
) {
3623 if (!group
->conf
->afc
[afi
][safi
])
3625 peer
->afc
[afi
][safi
] = 1;
3627 if (!peer_af_find(peer
, afi
, safi
))
3628 peer_af_create(peer
, afi
, safi
);
3630 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3633 /* Mark as dynamic, but also as a "config node" for other things to
3635 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3636 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3642 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3643 struct prefix
*prefix
)
3645 struct listnode
*node
, *nnode
;
3646 struct prefix
*range
;
3649 afi
= family2afi(prefix
->family
);
3651 if (group
->listen_range
[afi
])
3652 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3654 if (prefix_match(range
, prefix
))
3661 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3662 struct prefix
**listen_range
)
3664 struct prefix
*range
= NULL
;
3665 struct peer_group
*group
= NULL
;
3666 struct listnode
*node
, *nnode
;
3668 *listen_range
= NULL
;
3670 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3671 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3674 } else if (bm
->bgp
!= NULL
) {
3675 struct listnode
*bgpnode
, *nbgpnode
;
3677 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3678 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3679 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3685 *listen_range
= range
;
3686 return (group
&& range
) ? group
: NULL
;
3689 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3691 struct peer_group
*group
;
3694 struct prefix prefix
;
3695 struct prefix
*listen_range
;
3697 char buf
[PREFIX2STR_BUFFER
];
3698 char buf1
[PREFIX2STR_BUFFER
];
3700 sockunion2hostprefix(su
, &prefix
);
3702 /* See if incoming connection matches a configured listen range. */
3703 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3714 prefix2str(&prefix
, buf
, sizeof(buf
));
3715 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3717 if (bgp_debug_neighbor_events(NULL
))
3719 "Dynamic Neighbor %s matches group %s listen range %s",
3720 buf
, group
->name
, buf1
);
3722 /* Are we within the listen limit? */
3723 dncount
= gbgp
->dynamic_neighbors_count
;
3725 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3726 if (bgp_debug_neighbor_events(NULL
))
3727 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3728 inet_sutop(su
, buf
),
3729 gbgp
->dynamic_neighbors_limit
);
3733 /* Ensure group is not disabled. */
3734 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3735 if (bgp_debug_neighbor_events(NULL
))
3737 "Dynamic Neighbor %s rejected - group %s disabled",
3742 /* Check that at least one AF is activated for the group. */
3743 if (!peer_group_af_configured(group
)) {
3744 if (bgp_debug_neighbor_events(NULL
))
3746 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3751 /* Create dynamic peer and bind to associated group. */
3752 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3755 gbgp
->dynamic_neighbors_count
= ++dncount
;
3757 if (bgp_debug_neighbor_events(peer
))
3758 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3759 peer
->host
, group
->name
, dncount
);
3764 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3767 if (peer
->group
->bgp
) {
3768 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3770 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3772 if (bgp_debug_neighbor_events(peer
))
3773 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3774 peer
->group
->name
, dncount
);
3777 /* If peer is configured at least one address family return 1. */
3778 bool peer_active(struct peer
*peer
)
3780 if (BGP_PEER_SU_UNSPEC(peer
))
3782 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3783 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3784 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3785 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3786 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3787 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3788 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3789 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3790 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3791 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3792 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3797 /* If peer is negotiated at least one address family return 1. */
3798 bool peer_active_nego(struct peer
*peer
)
3800 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3801 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3802 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3803 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3804 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3805 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3806 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3807 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3808 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3809 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3810 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3811 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3812 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3817 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3818 enum peer_change_type type
)
3820 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3823 if (peer
->status
!= Established
)
3826 if (type
== peer_change_reset
) {
3827 /* If we're resetting session, we've to delete both peer struct
3829 if ((peer
->doppelganger
)
3830 && (peer
->doppelganger
->status
!= Deleted
)
3831 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3832 PEER_FLAG_CONFIG_NODE
)))
3833 peer_delete(peer
->doppelganger
);
3835 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3836 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3837 } else if (type
== peer_change_reset_in
) {
3838 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3839 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3840 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3842 if ((peer
->doppelganger
)
3843 && (peer
->doppelganger
->status
!= Deleted
)
3844 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3845 PEER_FLAG_CONFIG_NODE
)))
3846 peer_delete(peer
->doppelganger
);
3848 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3849 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3851 } else if (type
== peer_change_reset_out
) {
3852 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3853 bgp_announce_route(peer
, afi
, safi
);
3857 struct peer_flag_action
{
3861 /* This flag can be set for peer-group member. */
3862 uint8_t not_for_member
;
3864 /* Action when the flag is changed. */
3865 enum peer_change_type type
;
3868 static const struct peer_flag_action peer_flag_action_list
[] = {
3869 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3870 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3871 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3872 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3873 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3874 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3875 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3876 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3877 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3878 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3879 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3880 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3881 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3882 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3883 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3884 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3885 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3886 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3889 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3890 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3891 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3892 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3893 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3894 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3895 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3896 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3897 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3898 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3899 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3900 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3901 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3902 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3903 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3904 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3905 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3906 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3907 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3908 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3909 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3910 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3911 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3912 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3913 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3914 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3917 /* Proper action set. */
3918 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3919 int size
, struct peer_flag_action
*action
,
3926 const struct peer_flag_action
*match
= NULL
;
3928 /* Check peer's frag action. */
3929 for (i
= 0; i
< size
; i
++) {
3930 match
= &action_list
[i
];
3932 if (match
->flag
== 0)
3935 if (match
->flag
& flag
) {
3938 if (match
->type
== peer_change_reset_in
)
3940 if (match
->type
== peer_change_reset_out
)
3942 if (match
->type
== peer_change_reset
) {
3946 if (match
->not_for_member
)
3947 action
->not_for_member
= 1;
3951 /* Set peer clear type. */
3952 if (reset_in
&& reset_out
)
3953 action
->type
= peer_change_reset
;
3955 action
->type
= peer_change_reset_in
;
3957 action
->type
= peer_change_reset_out
;
3959 action
->type
= peer_change_none
;
3964 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3966 if (flag
== PEER_FLAG_SHUTDOWN
) {
3967 if (CHECK_FLAG(peer
->flags
, flag
)) {
3968 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3969 peer_nsf_stop(peer
);
3971 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3972 if (peer
->t_pmax_restart
) {
3973 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3974 if (bgp_debug_neighbor_events(peer
))
3976 "%s Maximum-prefix restart timer canceled",
3980 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3981 peer_nsf_stop(peer
);
3983 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3984 char *msg
= peer
->tx_shutdown_message
;
3987 if (!msg
&& peer_group_active(peer
))
3988 msg
= peer
->group
->conf
3989 ->tx_shutdown_message
;
3990 msglen
= msg
? strlen(msg
) : 0;
3995 uint8_t msgbuf
[129];
3998 memcpy(msgbuf
+ 1, msg
, msglen
);
4000 bgp_notify_send_with_data(
4001 peer
, BGP_NOTIFY_CEASE
,
4002 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
4003 msgbuf
, msglen
+ 1);
4006 peer
, BGP_NOTIFY_CEASE
,
4007 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
4009 bgp_session_reset(peer
);
4011 peer
->v_start
= BGP_INIT_START_TIMER
;
4012 BGP_EVENT_ADD(peer
, BGP_Stop
);
4014 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4015 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
4016 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4017 else if (flag
== PEER_FLAG_PASSIVE
)
4018 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
4019 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
4020 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
4022 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4023 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4025 bgp_session_reset(peer
);
4028 /* Change specified peer flag. */
4029 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
4033 bool invert
, member_invert
;
4034 struct peer
*member
;
4035 struct listnode
*node
, *nnode
;
4036 struct peer_flag_action action
;
4038 memset(&action
, 0, sizeof(struct peer_flag_action
));
4039 size
= sizeof(peer_flag_action_list
) / sizeof(struct peer_flag_action
);
4041 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4042 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4045 /* Abort if no flag action exists. */
4047 return BGP_ERR_INVALID_FLAG
;
4049 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4050 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4051 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4052 return BGP_ERR_PEER_FLAG_CONFLICT
;
4054 /* Handle flag updates where desired state matches current state. */
4055 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4056 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4057 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4061 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4062 COND_FLAG(peer
->flags_override
, flag
, invert
);
4067 /* Inherit from peer-group or set/unset flags accordingly. */
4068 if (peer_group_active(peer
) && set
== invert
)
4069 peer_flag_inherit(peer
, flag
);
4071 COND_FLAG(peer
->flags
, flag
, set
);
4073 /* Check if handling a regular peer. */
4074 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4075 /* Update flag override state accordingly. */
4076 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4079 * For the extended next-hop encoding flag we need to turn RAs
4080 * on if flag is being set, but only turn RAs off if the flag
4081 * is being unset on this peer and if this peer is a member of a
4082 * peer-group, the peer-group also doesn't have the flag set.
4084 if (flag
== PEER_FLAG_CAPABILITY_ENHE
) {
4086 bgp_zebra_initiate_radv(peer
->bgp
, peer
);
4087 } else if (peer_group_active(peer
)) {
4088 if (!CHECK_FLAG(peer
->group
->conf
->flags
, flag
))
4089 bgp_zebra_terminate_radv(peer
->bgp
,
4092 bgp_zebra_terminate_radv(peer
->bgp
, peer
);
4095 /* Execute flag action on peer. */
4096 if (action
.type
== peer_change_reset
)
4097 peer_flag_modify_action(peer
, flag
);
4099 /* Skip peer-group mechanics for regular peers. */
4104 * Update peer-group members, unless they are explicitely overriding
4105 * peer-group configuration.
4107 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4108 /* Skip peers with overridden configuration. */
4109 if (CHECK_FLAG(member
->flags_override
, flag
))
4112 /* Check if only member without group is inverted. */
4114 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4116 /* Skip peers with equivalent configuration. */
4117 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4120 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4123 /* Update flag on peer-group member. */
4124 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4126 if (flag
== PEER_FLAG_CAPABILITY_ENHE
)
4127 set
? bgp_zebra_initiate_radv(member
->bgp
, member
)
4128 : bgp_zebra_terminate_radv(member
->bgp
, member
);
4130 /* Execute flag action on peer-group member. */
4131 if (action
.type
== peer_change_reset
)
4132 peer_flag_modify_action(member
, flag
);
4138 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4140 return peer_flag_modify(peer
, flag
, 1);
4143 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4145 return peer_flag_modify(peer
, flag
, 0);
4148 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4149 uint32_t flag
, bool set
)
4153 bool invert
, member_invert
;
4154 struct peer
*member
;
4155 struct listnode
*node
, *nnode
;
4156 struct peer_flag_action action
;
4157 bgp_peer_sort_t ptype
;
4159 memset(&action
, 0, sizeof(struct peer_flag_action
));
4160 size
= sizeof(peer_af_flag_action_list
)
4161 / sizeof(struct peer_flag_action
);
4163 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4164 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4167 /* Abort if flag action exists. */
4169 return BGP_ERR_INVALID_FLAG
;
4171 ptype
= peer_sort(peer
);
4172 /* Special check for reflector client. */
4173 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
&& ptype
!= BGP_PEER_IBGP
)
4174 return BGP_ERR_NOT_INTERNAL_PEER
;
4176 /* Special check for remove-private-AS. */
4177 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
&& ptype
== BGP_PEER_IBGP
)
4178 return BGP_ERR_REMOVE_PRIVATE_AS
;
4180 /* as-override is not allowed for IBGP peers */
4181 if (flag
& PEER_FLAG_AS_OVERRIDE
&& ptype
== BGP_PEER_IBGP
)
4182 return BGP_ERR_AS_OVERRIDE
;
4184 /* Handle flag updates where desired state matches current state. */
4185 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4186 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4187 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4192 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4193 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4200 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4201 * if we are setting/unsetting flags which conflict with this flag
4202 * handle accordingly
4204 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4208 * if we are setting NEXTHOP_SELF, we need to unset the
4209 * NEXTHOP_UNCHANGED flag
4211 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4212 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4213 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4214 PEER_FLAG_NEXTHOP_UNCHANGED
);
4218 * if we are unsetting NEXTHOP_SELF, we need to set the
4219 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4221 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4222 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4223 SET_FLAG(peer
->af_flags
[afi
][safi
],
4224 PEER_FLAG_NEXTHOP_UNCHANGED
);
4229 * If the peer is a route server client let's not
4230 * muck with the nexthop on the way out the door
4232 if (flag
& PEER_FLAG_RSERVER_CLIENT
) {
4234 SET_FLAG(peer
->af_flags
[afi
][safi
],
4235 PEER_FLAG_NEXTHOP_UNCHANGED
);
4237 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4238 PEER_FLAG_NEXTHOP_UNCHANGED
);
4241 /* Inherit from peer-group or set/unset flags accordingly. */
4242 if (peer_group_active(peer
) && set
== invert
)
4243 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4245 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4247 /* Execute action when peer is established. */
4248 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4249 && peer
->status
== Established
) {
4250 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4251 bgp_clear_adj_in(peer
, afi
, safi
);
4253 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4254 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4255 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4256 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4257 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4258 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4259 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4260 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4262 peer_change_action(peer
, afi
, safi
, action
.type
);
4266 /* Check if handling a regular peer. */
4267 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4268 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4272 * Update peer-group members, unless they are explicitely
4273 * overriding peer-group configuration.
4275 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4277 /* Skip peers with overridden configuration. */
4278 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4282 /* Check if only member without group is inverted. */
4284 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4288 /* Skip peers with equivalent configuration. */
4289 if (set
!= member_invert
4290 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4293 if (set
== member_invert
4294 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4297 /* Update flag on peer-group member. */
4298 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4299 set
!= member_invert
);
4301 /* Execute flag action on peer-group member. */
4302 if (member
->status
== Established
) {
4303 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4304 bgp_clear_adj_in(member
, afi
, safi
);
4306 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4307 member
->last_reset
=
4308 PEER_DOWN_RR_CLIENT_CHANGE
;
4310 == PEER_FLAG_RSERVER_CLIENT
)
4311 member
->last_reset
=
4312 PEER_DOWN_RS_CLIENT_CHANGE
;
4314 == PEER_FLAG_ORF_PREFIX_SM
)
4315 member
->last_reset
=
4316 PEER_DOWN_CAPABILITY_CHANGE
;
4318 == PEER_FLAG_ORF_PREFIX_RM
)
4319 member
->last_reset
=
4320 PEER_DOWN_CAPABILITY_CHANGE
;
4322 peer_change_action(member
, afi
, safi
,
4332 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4334 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4337 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4339 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4343 void peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4345 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4346 peer
->tx_shutdown_message
=
4347 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4350 void peer_tx_shutdown_message_unset(struct peer
*peer
)
4352 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4356 /* EBGP multihop configuration. */
4357 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4359 struct peer_group
*group
;
4360 struct listnode
*node
, *nnode
;
4363 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4366 /* see comment in peer_ttl_security_hops_set() */
4367 if (ttl
!= MAXTTL
) {
4368 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4369 group
= peer
->group
;
4370 if (group
->conf
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4371 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4373 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4375 if (peer1
->sort
== BGP_PEER_IBGP
)
4378 if (peer1
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4379 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4382 if (peer
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
)
4383 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4389 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4390 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4391 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4392 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4393 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4395 bgp_session_reset(peer
);
4398 group
= peer
->group
;
4399 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4400 if (peer
->sort
== BGP_PEER_IBGP
)
4403 peer
->ttl
= group
->conf
->ttl
;
4405 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4406 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4407 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4409 bgp_session_reset(peer
);
4415 int peer_ebgp_multihop_unset(struct peer
*peer
)
4417 struct peer_group
*group
;
4418 struct listnode
*node
, *nnode
;
4420 if (peer
->sort
== BGP_PEER_IBGP
)
4423 if (peer
->gtsm_hops
!= BGP_GTSM_HOPS_DISABLED
&& peer
->ttl
!= MAXTTL
)
4424 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4426 if (peer_group_active(peer
))
4427 peer
->ttl
= peer
->group
->conf
->ttl
;
4429 peer
->ttl
= BGP_DEFAULT_TTL
;
4431 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4432 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4433 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4434 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4436 bgp_session_reset(peer
);
4438 group
= peer
->group
;
4439 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4440 if (peer
->sort
== BGP_PEER_IBGP
)
4443 peer
->ttl
= BGP_DEFAULT_TTL
;
4445 if (peer
->fd
>= 0) {
4446 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4448 peer
, BGP_NOTIFY_CEASE
,
4449 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4451 bgp_session_reset(peer
);
4458 /* Neighbor description. */
4459 void peer_description_set(struct peer
*peer
, const char *desc
)
4461 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4463 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4466 void peer_description_unset(struct peer
*peer
)
4468 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4471 /* Neighbor update-source. */
4472 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4474 struct peer
*member
;
4475 struct listnode
*node
, *nnode
;
4477 /* Set flag and configuration on peer. */
4478 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4479 if (peer
->update_if
) {
4480 if (strcmp(peer
->update_if
, ifname
) == 0)
4482 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4484 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4485 sockunion_free(peer
->update_source
);
4486 peer
->update_source
= NULL
;
4488 /* Check if handling a regular peer. */
4489 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4490 /* Send notification or reset peer depending on state. */
4491 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4492 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4493 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4494 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4496 bgp_session_reset(peer
);
4498 /* Skip peer-group mechanics for regular peers. */
4503 * Set flag and configuration on all peer-group members, unless they are
4504 * explicitely overriding peer-group configuration.
4506 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4507 /* Skip peers with overridden configuration. */
4508 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4511 /* Skip peers with the same configuration. */
4512 if (member
->update_if
) {
4513 if (strcmp(member
->update_if
, ifname
) == 0)
4515 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4518 /* Set flag and configuration on peer-group member. */
4519 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4520 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4521 sockunion_free(member
->update_source
);
4522 member
->update_source
= NULL
;
4524 /* Send notification or reset peer depending on state. */
4525 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4526 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4527 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4528 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4530 bgp_session_reset(member
);
4536 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4538 struct peer
*member
;
4539 struct listnode
*node
, *nnode
;
4541 /* Set flag and configuration on peer. */
4542 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4543 if (peer
->update_source
) {
4544 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4546 sockunion_free(peer
->update_source
);
4548 peer
->update_source
= sockunion_dup(su
);
4549 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4551 /* Check if handling a regular peer. */
4552 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4553 /* Send notification or reset peer depending on state. */
4554 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4555 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4556 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4557 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4559 bgp_session_reset(peer
);
4561 /* Skip peer-group mechanics for regular peers. */
4566 * Set flag and configuration on all peer-group members, unless they are
4567 * explicitely overriding peer-group configuration.
4569 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4570 /* Skip peers with overridden configuration. */
4571 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4574 /* Skip peers with the same configuration. */
4575 if (member
->update_source
) {
4576 if (sockunion_cmp(member
->update_source
, su
) == 0)
4578 sockunion_free(member
->update_source
);
4581 /* Set flag and configuration on peer-group member. */
4582 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4583 member
->update_source
= sockunion_dup(su
);
4584 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4586 /* Send notification or reset peer depending on state. */
4587 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4588 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4589 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4590 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4592 bgp_session_reset(member
);
4598 int peer_update_source_unset(struct peer
*peer
)
4600 struct peer
*member
;
4601 struct listnode
*node
, *nnode
;
4603 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4606 /* Inherit configuration from peer-group if peer is member. */
4607 if (peer_group_active(peer
)) {
4608 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4609 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4610 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4611 MTYPE_PEER_UPDATE_SOURCE
);
4613 /* Otherwise remove flag and configuration from peer. */
4614 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4615 sockunion_free(peer
->update_source
);
4616 peer
->update_source
= NULL
;
4617 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4620 /* Check if handling a regular peer. */
4621 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4622 /* Send notification or reset peer depending on state. */
4623 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4624 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4625 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4626 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4628 bgp_session_reset(peer
);
4630 /* Skip peer-group mechanics for regular peers. */
4635 * Set flag and configuration on all peer-group members, unless they are
4636 * explicitely overriding peer-group configuration.
4638 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4639 /* Skip peers with overridden configuration. */
4640 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4643 /* Skip peers with the same configuration. */
4644 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4645 && !member
->update_source
&& !member
->update_if
)
4648 /* Remove flag and configuration on peer-group member. */
4649 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4650 sockunion_free(member
->update_source
);
4651 member
->update_source
= NULL
;
4652 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4654 /* Send notification or reset peer depending on state. */
4655 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4656 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4657 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4658 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4660 bgp_session_reset(member
);
4666 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4667 const char *rmap
, struct route_map
*route_map
)
4669 struct peer
*member
;
4670 struct listnode
*node
, *nnode
;
4672 /* Set flag and configuration on peer. */
4673 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4675 if (!peer
->default_rmap
[afi
][safi
].name
4676 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4677 if (peer
->default_rmap
[afi
][safi
].name
)
4678 XFREE(MTYPE_ROUTE_MAP_NAME
,
4679 peer
->default_rmap
[afi
][safi
].name
);
4681 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4682 peer
->default_rmap
[afi
][safi
].name
=
4683 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4684 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4685 route_map_counter_increment(route_map
);
4688 if (peer
->default_rmap
[afi
][safi
].name
)
4689 XFREE(MTYPE_ROUTE_MAP_NAME
,
4690 peer
->default_rmap
[afi
][safi
].name
);
4692 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4693 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4694 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4697 /* Check if handling a regular peer. */
4698 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4699 /* Update peer route announcements. */
4700 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4701 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4702 bgp_default_originate(peer
, afi
, safi
, 0);
4703 bgp_announce_route(peer
, afi
, safi
);
4706 /* Skip peer-group mechanics for regular peers. */
4711 * Set flag and configuration on all peer-group members, unless they are
4712 * explicitely overriding peer-group configuration.
4714 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4715 /* Skip peers with overridden configuration. */
4716 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4717 PEER_FLAG_DEFAULT_ORIGINATE
))
4720 /* Set flag and configuration on peer-group member. */
4721 SET_FLAG(member
->af_flags
[afi
][safi
],
4722 PEER_FLAG_DEFAULT_ORIGINATE
);
4724 if (member
->default_rmap
[afi
][safi
].name
)
4725 XFREE(MTYPE_ROUTE_MAP_NAME
,
4726 member
->default_rmap
[afi
][safi
].name
);
4727 route_map_counter_decrement(
4728 member
->default_rmap
[afi
][safi
].map
);
4729 member
->default_rmap
[afi
][safi
].name
=
4730 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4731 member
->default_rmap
[afi
][safi
].map
= route_map
;
4732 route_map_counter_increment(route_map
);
4735 /* Update peer route announcements. */
4736 if (member
->status
== Established
4737 && member
->afc_nego
[afi
][safi
]) {
4738 update_group_adjust_peer(
4739 peer_af_find(member
, afi
, safi
));
4740 bgp_default_originate(member
, afi
, safi
, 0);
4741 bgp_announce_route(member
, afi
, safi
);
4748 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4750 struct peer
*member
;
4751 struct listnode
*node
, *nnode
;
4753 /* Inherit configuration from peer-group if peer is member. */
4754 if (peer_group_active(peer
)) {
4755 peer_af_flag_inherit(peer
, afi
, safi
,
4756 PEER_FLAG_DEFAULT_ORIGINATE
);
4757 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4758 default_rmap
[afi
][safi
].name
,
4759 MTYPE_ROUTE_MAP_NAME
);
4760 PEER_ATTR_INHERIT(peer
, peer
->group
,
4761 default_rmap
[afi
][safi
].map
);
4763 /* Otherwise remove flag and configuration from peer. */
4764 peer_af_flag_unset(peer
, afi
, safi
,
4765 PEER_FLAG_DEFAULT_ORIGINATE
);
4766 if (peer
->default_rmap
[afi
][safi
].name
)
4767 XFREE(MTYPE_ROUTE_MAP_NAME
,
4768 peer
->default_rmap
[afi
][safi
].name
);
4769 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4770 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4771 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4774 /* Check if handling a regular peer. */
4775 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4776 /* Update peer route announcements. */
4777 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4778 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4779 bgp_default_originate(peer
, afi
, safi
, 1);
4780 bgp_announce_route(peer
, afi
, safi
);
4783 /* Skip peer-group mechanics for regular peers. */
4788 * Remove flag and configuration from all peer-group members, unless
4789 * they are explicitely overriding peer-group configuration.
4791 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4792 /* Skip peers with overridden configuration. */
4793 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4794 PEER_FLAG_DEFAULT_ORIGINATE
))
4797 /* Remove flag and configuration on peer-group member. */
4798 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4799 PEER_FLAG_DEFAULT_ORIGINATE
);
4800 if (peer
->default_rmap
[afi
][safi
].name
)
4801 XFREE(MTYPE_ROUTE_MAP_NAME
,
4802 peer
->default_rmap
[afi
][safi
].name
);
4803 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4804 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4805 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4807 /* Update peer route announcements. */
4808 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4809 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4810 bgp_default_originate(peer
, afi
, safi
, 1);
4811 bgp_announce_route(peer
, afi
, safi
);
4818 void peer_port_set(struct peer
*peer
, uint16_t port
)
4823 void peer_port_unset(struct peer
*peer
)
4825 peer
->port
= BGP_PORT_DEFAULT
;
4829 * Helper function that is called after the name of the policy
4830 * being used by a peer has changed (AF specific). Automatically
4831 * initiates inbound or outbound processing as needed.
4833 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4837 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4838 if (peer
->status
== Established
)
4839 bgp_announce_route(peer
, afi
, safi
);
4841 if (peer
->status
!= Established
)
4844 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4845 PEER_FLAG_SOFT_RECONFIG
))
4846 bgp_soft_reconfig_in(peer
, afi
, safi
);
4847 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4848 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4849 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4854 /* neighbor weight. */
4855 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4857 struct peer
*member
;
4858 struct listnode
*node
, *nnode
;
4860 /* Set flag and configuration on peer. */
4861 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4862 if (peer
->weight
[afi
][safi
] != weight
) {
4863 peer
->weight
[afi
][safi
] = weight
;
4864 peer_on_policy_change(peer
, afi
, safi
, 0);
4867 /* Skip peer-group mechanics for regular peers. */
4868 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4872 * Set flag and configuration on all peer-group members, unless they are
4873 * explicitely overriding peer-group configuration.
4875 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4876 /* Skip peers with overridden configuration. */
4877 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4881 /* Set flag and configuration on peer-group member. */
4882 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4883 if (member
->weight
[afi
][safi
] != weight
) {
4884 member
->weight
[afi
][safi
] = weight
;
4885 peer_on_policy_change(member
, afi
, safi
, 0);
4892 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4894 struct peer
*member
;
4895 struct listnode
*node
, *nnode
;
4897 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4900 /* Inherit configuration from peer-group if peer is member. */
4901 if (peer_group_active(peer
)) {
4902 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4903 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4905 peer_on_policy_change(peer
, afi
, safi
, 0);
4909 /* Remove flag and configuration from peer. */
4910 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4911 peer
->weight
[afi
][safi
] = 0;
4912 peer_on_policy_change(peer
, afi
, safi
, 0);
4914 /* Skip peer-group mechanics for regular peers. */
4915 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4919 * Remove flag and configuration from all peer-group members, unless
4920 * they are explicitely overriding peer-group configuration.
4922 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4923 /* Skip peers with overridden configuration. */
4924 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4928 /* Skip peers where flag is already disabled. */
4929 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4932 /* Remove flag and configuration on peer-group member. */
4933 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4934 member
->weight
[afi
][safi
] = 0;
4935 peer_on_policy_change(member
, afi
, safi
, 0);
4941 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4943 struct peer
*member
;
4944 struct listnode
*node
, *nnode
;
4946 if (keepalive
> 65535)
4947 return BGP_ERR_INVALID_VALUE
;
4949 if (holdtime
> 65535)
4950 return BGP_ERR_INVALID_VALUE
;
4952 if (holdtime
< 3 && holdtime
!= 0)
4953 return BGP_ERR_INVALID_VALUE
;
4955 /* Set flag and configuration on peer. */
4956 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4957 peer
->holdtime
= holdtime
;
4958 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4960 /* Skip peer-group mechanics for regular peers. */
4961 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4965 * Set flag and configuration on all peer-group members, unless they are
4966 * explicitely overriding peer-group configuration.
4968 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4969 /* Skip peers with overridden configuration. */
4970 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4973 /* Set flag and configuration on peer-group member. */
4974 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4975 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4976 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4982 int peer_timers_unset(struct peer
*peer
)
4984 struct peer
*member
;
4985 struct listnode
*node
, *nnode
;
4987 /* Inherit configuration from peer-group if peer is member. */
4988 if (peer_group_active(peer
)) {
4989 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4990 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4991 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4993 /* Otherwise remove flag and configuration from peer. */
4994 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4996 peer
->keepalive
= 0;
4999 /* Skip peer-group mechanics for regular peers. */
5000 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5004 * Remove flag and configuration from all peer-group members, unless
5005 * they are explicitely overriding peer-group configuration.
5007 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5008 /* Skip peers with overridden configuration. */
5009 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
5012 /* Remove flag and configuration on peer-group member. */
5013 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
5014 member
->holdtime
= 0;
5015 member
->keepalive
= 0;
5021 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
5023 struct peer
*member
;
5024 struct listnode
*node
, *nnode
;
5026 if (connect
> 65535)
5027 return BGP_ERR_INVALID_VALUE
;
5029 /* Set flag and configuration on peer. */
5030 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
5031 peer
->connect
= connect
;
5032 peer
->v_connect
= connect
;
5034 /* Skip peer-group mechanics for regular peers. */
5035 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5039 * Set flag and configuration on all peer-group members, unless they are
5040 * explicitely overriding peer-group configuration.
5042 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5043 /* Skip peers with overridden configuration. */
5044 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5047 /* Set flag and configuration on peer-group member. */
5048 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5049 member
->connect
= connect
;
5050 member
->v_connect
= connect
;
5056 int peer_timers_connect_unset(struct peer
*peer
)
5058 struct peer
*member
;
5059 struct listnode
*node
, *nnode
;
5061 /* Inherit configuration from peer-group if peer is member. */
5062 if (peer_group_active(peer
)) {
5063 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5064 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5066 /* Otherwise remove flag and configuration from peer. */
5067 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5071 /* Set timer with fallback to default value. */
5073 peer
->v_connect
= peer
->connect
;
5075 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
5077 /* Skip peer-group mechanics for regular peers. */
5078 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5082 * Remove flag and configuration from all peer-group members, unless
5083 * they are explicitely overriding peer-group configuration.
5085 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5086 /* Skip peers with overridden configuration. */
5087 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5090 /* Remove flag and configuration on peer-group member. */
5091 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5092 member
->connect
= 0;
5093 member
->v_connect
= peer
->bgp
->default_connect_retry
;
5099 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5101 struct peer
*member
;
5102 struct listnode
*node
, *nnode
;
5105 return BGP_ERR_INVALID_VALUE
;
5107 /* Set flag and configuration on peer. */
5108 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5109 peer
->routeadv
= routeadv
;
5110 peer
->v_routeadv
= routeadv
;
5112 /* Check if handling a regular peer. */
5113 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5114 /* Update peer route announcements. */
5115 update_group_adjust_peer_afs(peer
);
5116 if (peer
->status
== Established
)
5117 bgp_announce_route_all(peer
);
5119 /* Skip peer-group mechanics for regular peers. */
5124 * Set flag and configuration on all peer-group members, unless they are
5125 * explicitely overriding peer-group configuration.
5127 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5128 /* Skip peers with overridden configuration. */
5129 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5132 /* Set flag and configuration on peer-group member. */
5133 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5134 member
->routeadv
= routeadv
;
5135 member
->v_routeadv
= routeadv
;
5137 /* Update peer route announcements. */
5138 update_group_adjust_peer_afs(member
);
5139 if (member
->status
== Established
)
5140 bgp_announce_route_all(member
);
5146 int peer_advertise_interval_unset(struct peer
*peer
)
5148 struct peer
*member
;
5149 struct listnode
*node
, *nnode
;
5151 /* Inherit configuration from peer-group if peer is member. */
5152 if (peer_group_active(peer
)) {
5153 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5154 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5156 /* Otherwise remove flag and configuration from peer. */
5157 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5161 /* Set timer with fallback to default value. */
5163 peer
->v_routeadv
= peer
->routeadv
;
5165 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5166 ? BGP_DEFAULT_IBGP_ROUTEADV
5167 : BGP_DEFAULT_EBGP_ROUTEADV
;
5169 /* Check if handling a regular peer. */
5170 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5171 /* Update peer route announcements. */
5172 update_group_adjust_peer_afs(peer
);
5173 if (peer
->status
== Established
)
5174 bgp_announce_route_all(peer
);
5176 /* Skip peer-group mechanics for regular peers. */
5181 * Remove flag and configuration from all peer-group members, unless
5182 * they are explicitely overriding peer-group configuration.
5184 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5185 /* Skip peers with overridden configuration. */
5186 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5189 /* Remove flag and configuration on peer-group member. */
5190 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5191 member
->routeadv
= 0;
5192 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5193 ? BGP_DEFAULT_IBGP_ROUTEADV
5194 : BGP_DEFAULT_EBGP_ROUTEADV
;
5196 /* Update peer route announcements. */
5197 update_group_adjust_peer_afs(member
);
5198 if (member
->status
== Established
)
5199 bgp_announce_route_all(member
);
5205 /* neighbor interface */
5206 void peer_interface_set(struct peer
*peer
, const char *str
)
5208 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5209 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5212 void peer_interface_unset(struct peer
*peer
)
5214 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5218 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5219 int allow_num
, int origin
)
5221 struct peer
*member
;
5222 struct listnode
*node
, *nnode
;
5224 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5225 return BGP_ERR_INVALID_VALUE
;
5227 /* Set flag and configuration on peer. */
5228 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5230 if (peer
->allowas_in
[afi
][safi
] != 0
5231 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5232 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5233 peer_af_flag_set(peer
, afi
, safi
,
5234 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5235 peer
->allowas_in
[afi
][safi
] = 0;
5236 peer_on_policy_change(peer
, afi
, safi
, 0);
5239 if (peer
->allowas_in
[afi
][safi
] != allow_num
5240 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5241 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5243 peer_af_flag_unset(peer
, afi
, safi
,
5244 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5245 peer
->allowas_in
[afi
][safi
] = allow_num
;
5246 peer_on_policy_change(peer
, afi
, safi
, 0);
5250 /* Skip peer-group mechanics for regular peers. */
5251 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5255 * Set flag and configuration on all peer-group members, unless
5256 * they are explicitely overriding peer-group configuration.
5258 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5259 /* Skip peers with overridden configuration. */
5260 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5261 PEER_FLAG_ALLOWAS_IN
))
5264 /* Set flag and configuration on peer-group member. */
5265 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5267 if (member
->allowas_in
[afi
][safi
] != 0
5268 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5269 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5270 SET_FLAG(member
->af_flags
[afi
][safi
],
5271 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5272 member
->allowas_in
[afi
][safi
] = 0;
5273 peer_on_policy_change(peer
, afi
, safi
, 0);
5276 if (member
->allowas_in
[afi
][safi
] != allow_num
5277 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5278 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5279 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5280 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5281 member
->allowas_in
[afi
][safi
] = allow_num
;
5282 peer_on_policy_change(peer
, afi
, safi
, 0);
5290 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5292 struct peer
*member
;
5293 struct listnode
*node
, *nnode
;
5295 /* Skip peer if flag is already disabled. */
5296 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5299 /* Inherit configuration from peer-group if peer is member. */
5300 if (peer_group_active(peer
)) {
5301 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5302 peer_af_flag_inherit(peer
, afi
, safi
,
5303 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5304 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5305 peer_on_policy_change(peer
, afi
, safi
, 0);
5310 /* Remove flag and configuration from peer. */
5311 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5312 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5313 peer
->allowas_in
[afi
][safi
] = 0;
5314 peer_on_policy_change(peer
, afi
, safi
, 0);
5316 /* Skip peer-group mechanics if handling a regular peer. */
5317 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5321 * Remove flags and configuration from all peer-group members, unless
5322 * they are explicitely overriding peer-group configuration.
5324 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5325 /* Skip peers with overridden configuration. */
5326 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5327 PEER_FLAG_ALLOWAS_IN
))
5330 /* Skip peers where flag is already disabled. */
5331 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5332 PEER_FLAG_ALLOWAS_IN
))
5335 /* Remove flags and configuration on peer-group member. */
5336 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5337 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5338 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5339 member
->allowas_in
[afi
][safi
] = 0;
5340 peer_on_policy_change(member
, afi
, safi
, 0);
5346 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5349 bool old_no_prepend
, old_replace_as
;
5350 struct bgp
*bgp
= peer
->bgp
;
5351 struct peer
*member
;
5352 struct listnode
*node
, *nnode
;
5353 bgp_peer_sort_t ptype
= peer_sort(peer
);
5355 if (ptype
!= BGP_PEER_EBGP
&& ptype
!= BGP_PEER_INTERNAL
)
5356 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5359 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5362 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5364 /* Save previous flag states. */
5366 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5368 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5370 /* Set flag and configuration on peer. */
5371 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5372 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5373 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5375 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5376 && old_replace_as
== replace_as
)
5378 peer
->change_local_as
= as
;
5380 /* Check if handling a regular peer. */
5381 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5382 /* Send notification or reset peer depending on state. */
5383 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5384 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5385 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5386 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5388 bgp_session_reset(peer
);
5390 /* Skip peer-group mechanics for regular peers. */
5395 * Set flag and configuration on all peer-group members, unless they are
5396 * explicitely overriding peer-group configuration.
5398 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5399 /* Skip peers with overridden configuration. */
5400 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5403 /* Skip peers with the same configuration. */
5404 old_no_prepend
= CHECK_FLAG(member
->flags
,
5405 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5406 old_replace_as
= CHECK_FLAG(member
->flags
,
5407 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5408 if (member
->change_local_as
== as
5409 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5410 && old_no_prepend
== no_prepend
5411 && old_replace_as
== replace_as
)
5414 /* Set flag and configuration on peer-group member. */
5415 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5416 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5418 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5420 member
->change_local_as
= as
;
5422 /* Send notification or stop peer depending on state. */
5423 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5424 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5425 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5426 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5428 BGP_EVENT_ADD(member
, BGP_Stop
);
5434 int peer_local_as_unset(struct peer
*peer
)
5436 struct peer
*member
;
5437 struct listnode
*node
, *nnode
;
5439 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5442 /* Inherit configuration from peer-group if peer is member. */
5443 if (peer_group_active(peer
)) {
5444 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5445 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5446 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5447 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5449 /* Otherwise remove flag and configuration from peer. */
5450 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5451 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5452 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5453 peer
->change_local_as
= 0;
5456 /* Check if handling a regular peer. */
5457 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5458 /* Send notification or stop peer depending on state. */
5459 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5460 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5461 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5462 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5464 BGP_EVENT_ADD(peer
, BGP_Stop
);
5466 /* Skip peer-group mechanics for regular peers. */
5471 * Remove flag and configuration from all peer-group members, unless
5472 * they are explicitely overriding peer-group configuration.
5474 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5475 /* Skip peers with overridden configuration. */
5476 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5479 /* Remove flag and configuration on peer-group member. */
5480 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5481 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5482 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5483 member
->change_local_as
= 0;
5485 /* Send notification or stop peer depending on state. */
5486 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5487 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5488 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5489 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5491 bgp_session_reset(member
);
5497 /* Set password for authenticating with the peer. */
5498 int peer_password_set(struct peer
*peer
, const char *password
)
5500 struct peer
*member
;
5501 struct listnode
*node
, *nnode
;
5502 int len
= password
? strlen(password
) : 0;
5503 int ret
= BGP_SUCCESS
;
5505 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5506 return BGP_ERR_INVALID_VALUE
;
5508 /* Set flag and configuration on peer. */
5509 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5510 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5512 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5513 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5515 /* Check if handling a regular peer. */
5516 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5517 /* Send notification or reset peer depending on state. */
5518 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5519 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5520 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5522 bgp_session_reset(peer
);
5525 * Attempt to install password on socket and skip peer-group
5528 if (BGP_PEER_SU_UNSPEC(peer
))
5530 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5531 : BGP_ERR_TCPSIG_FAILED
;
5535 * Set flag and configuration on all peer-group members, unless they are
5536 * explicitely overriding peer-group configuration.
5538 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5539 /* Skip peers with overridden configuration. */
5540 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5543 /* Skip peers with the same password. */
5544 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5547 /* Set flag and configuration on peer-group member. */
5548 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5549 if (member
->password
)
5550 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5551 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5553 /* Send notification or reset peer depending on state. */
5554 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5555 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5556 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5558 bgp_session_reset(member
);
5560 /* Attempt to install password on socket. */
5561 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5562 ret
= BGP_ERR_TCPSIG_FAILED
;
5565 /* Set flag and configuration on all peer-group listen ranges */
5566 struct listnode
*ln
;
5569 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5570 bgp_md5_set_prefix(lr
, password
);
5571 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5572 bgp_md5_set_prefix(lr
, password
);
5577 int peer_password_unset(struct peer
*peer
)
5579 struct peer
*member
;
5580 struct listnode
*node
, *nnode
;
5582 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5585 /* Inherit configuration from peer-group if peer is member. */
5586 if (peer_group_active(peer
)) {
5587 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5588 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5589 MTYPE_PEER_PASSWORD
);
5591 /* Otherwise remove flag and configuration from peer. */
5592 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5593 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5596 /* Check if handling a regular peer. */
5597 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5598 /* Send notification or reset peer depending on state. */
5599 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5600 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5601 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5603 bgp_session_reset(peer
);
5605 /* Attempt to uninstall password on socket. */
5606 if (!BGP_PEER_SU_UNSPEC(peer
))
5607 bgp_md5_unset(peer
);
5609 /* Skip peer-group mechanics for regular peers. */
5614 * Remove flag and configuration from all peer-group members, unless
5615 * they are explicitely overriding peer-group configuration.
5617 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5618 /* Skip peers with overridden configuration. */
5619 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5622 /* Remove flag and configuration on peer-group member. */
5623 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5624 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5626 /* Send notification or reset peer depending on state. */
5627 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5628 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5629 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5631 bgp_session_reset(member
);
5633 /* Attempt to uninstall password on socket. */
5634 if (!BGP_PEER_SU_UNSPEC(member
))
5635 bgp_md5_unset(member
);
5638 /* Set flag and configuration on all peer-group listen ranges */
5639 struct listnode
*ln
;
5642 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5643 bgp_md5_unset_prefix(lr
);
5644 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5645 bgp_md5_unset_prefix(lr
);
5651 /* Set distribute list to the peer. */
5652 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5655 struct peer
*member
;
5656 struct bgp_filter
*filter
;
5657 struct listnode
*node
, *nnode
;
5659 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5660 return BGP_ERR_INVALID_VALUE
;
5662 /* Set configuration on peer. */
5663 filter
= &peer
->filter
[afi
][safi
];
5664 if (filter
->plist
[direct
].name
)
5665 return BGP_ERR_PEER_FILTER_CONFLICT
;
5666 if (filter
->dlist
[direct
].name
)
5667 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5668 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5669 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5671 /* Check if handling a regular peer. */
5672 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5673 /* Set override-flag and process peer route updates. */
5674 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5675 PEER_FT_DISTRIBUTE_LIST
);
5676 peer_on_policy_change(peer
, afi
, safi
,
5677 (direct
== FILTER_OUT
) ? 1 : 0);
5679 /* Skip peer-group mechanics for regular peers. */
5684 * Set configuration on all peer-group members, un less they are
5685 * explicitely overriding peer-group configuration.
5687 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5688 /* Skip peers with overridden configuration. */
5689 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5690 PEER_FT_DISTRIBUTE_LIST
))
5693 /* Set configuration on peer-group member. */
5694 filter
= &member
->filter
[afi
][safi
];
5695 if (filter
->dlist
[direct
].name
)
5696 XFREE(MTYPE_BGP_FILTER_NAME
,
5697 filter
->dlist
[direct
].name
);
5698 filter
->dlist
[direct
].name
=
5699 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5700 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5702 /* Process peer route updates. */
5703 peer_on_policy_change(member
, afi
, safi
,
5704 (direct
== FILTER_OUT
) ? 1 : 0);
5710 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5712 struct peer
*member
;
5713 struct bgp_filter
*filter
;
5714 struct listnode
*node
, *nnode
;
5716 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5717 return BGP_ERR_INVALID_VALUE
;
5719 /* Unset override-flag unconditionally. */
5720 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5721 PEER_FT_DISTRIBUTE_LIST
);
5723 /* Inherit configuration from peer-group if peer is member. */
5724 if (peer_group_active(peer
)) {
5725 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5726 filter
[afi
][safi
].dlist
[direct
].name
,
5727 MTYPE_BGP_FILTER_NAME
);
5728 PEER_ATTR_INHERIT(peer
, peer
->group
,
5729 filter
[afi
][safi
].dlist
[direct
].alist
);
5731 /* Otherwise remove configuration from peer. */
5732 filter
= &peer
->filter
[afi
][safi
];
5733 if (filter
->dlist
[direct
].name
)
5734 XFREE(MTYPE_BGP_FILTER_NAME
,
5735 filter
->dlist
[direct
].name
);
5736 filter
->dlist
[direct
].name
= NULL
;
5737 filter
->dlist
[direct
].alist
= NULL
;
5740 /* Check if handling a regular peer. */
5741 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5742 /* Process peer route updates. */
5743 peer_on_policy_change(peer
, afi
, safi
,
5744 (direct
== FILTER_OUT
) ? 1 : 0);
5746 /* Skip peer-group mechanics for regular peers. */
5751 * Remove configuration on all peer-group members, unless they are
5752 * explicitely overriding peer-group configuration.
5754 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5755 /* Skip peers with overridden configuration. */
5756 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5757 PEER_FT_DISTRIBUTE_LIST
))
5760 /* Remove configuration on peer-group member. */
5761 filter
= &member
->filter
[afi
][safi
];
5762 if (filter
->dlist
[direct
].name
)
5763 XFREE(MTYPE_BGP_FILTER_NAME
,
5764 filter
->dlist
[direct
].name
);
5765 filter
->dlist
[direct
].name
= NULL
;
5766 filter
->dlist
[direct
].alist
= NULL
;
5768 /* Process peer route updates. */
5769 peer_on_policy_change(member
, afi
, safi
,
5770 (direct
== FILTER_OUT
) ? 1 : 0);
5776 /* Update distribute list. */
5777 static void peer_distribute_update(struct access_list
*access
)
5782 struct listnode
*mnode
, *mnnode
;
5783 struct listnode
*node
, *nnode
;
5786 struct peer_group
*group
;
5787 struct bgp_filter
*filter
;
5789 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5791 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5792 access
->name
, 0, 0);
5793 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5794 FOREACH_AFI_SAFI (afi
, safi
) {
5795 filter
= &peer
->filter
[afi
][safi
];
5797 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5799 if (filter
->dlist
[direct
].name
)
5800 filter
->dlist
[direct
]
5801 .alist
= access_list_lookup(
5803 filter
->dlist
[direct
]
5806 filter
->dlist
[direct
].alist
=
5811 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5812 FOREACH_AFI_SAFI (afi
, safi
) {
5813 filter
= &group
->conf
->filter
[afi
][safi
];
5815 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5817 if (filter
->dlist
[direct
].name
)
5818 filter
->dlist
[direct
]
5819 .alist
= access_list_lookup(
5821 filter
->dlist
[direct
]
5824 filter
->dlist
[direct
].alist
=
5829 #ifdef ENABLE_BGP_VNC
5830 vnc_prefix_list_update(bgp
);
5835 /* Set prefix list to the peer. */
5836 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5839 struct peer
*member
;
5840 struct bgp_filter
*filter
;
5841 struct listnode
*node
, *nnode
;
5843 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5844 return BGP_ERR_INVALID_VALUE
;
5846 /* Set configuration on peer. */
5847 filter
= &peer
->filter
[afi
][safi
];
5848 if (filter
->dlist
[direct
].name
)
5849 return BGP_ERR_PEER_FILTER_CONFLICT
;
5850 if (filter
->plist
[direct
].name
)
5851 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5852 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5853 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5855 /* Check if handling a regular peer. */
5856 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5857 /* Set override-flag and process peer route updates. */
5858 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5859 PEER_FT_PREFIX_LIST
);
5860 peer_on_policy_change(peer
, afi
, safi
,
5861 (direct
== FILTER_OUT
) ? 1 : 0);
5863 /* Skip peer-group mechanics for regular peers. */
5868 * Set configuration on all peer-group members, unless they are
5869 * explicitely overriding peer-group configuration.
5871 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5872 /* Skip peers with overridden configuration. */
5873 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5874 PEER_FT_PREFIX_LIST
))
5877 /* Set configuration on peer-group member. */
5878 filter
= &member
->filter
[afi
][safi
];
5879 if (filter
->plist
[direct
].name
)
5880 XFREE(MTYPE_BGP_FILTER_NAME
,
5881 filter
->plist
[direct
].name
);
5882 filter
->plist
[direct
].name
=
5883 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5884 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5886 /* Process peer route updates. */
5887 peer_on_policy_change(member
, afi
, safi
,
5888 (direct
== FILTER_OUT
) ? 1 : 0);
5894 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5897 struct peer
*member
;
5898 struct bgp_filter
*filter
;
5899 struct listnode
*node
, *nnode
;
5901 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5902 return BGP_ERR_INVALID_VALUE
;
5904 /* Unset override-flag unconditionally. */
5905 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5906 PEER_FT_PREFIX_LIST
);
5908 /* Inherit configuration from peer-group if peer is member. */
5909 if (peer_group_active(peer
)) {
5910 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5911 filter
[afi
][safi
].plist
[direct
].name
,
5912 MTYPE_BGP_FILTER_NAME
);
5913 PEER_ATTR_INHERIT(peer
, peer
->group
,
5914 filter
[afi
][safi
].plist
[direct
].plist
);
5916 /* Otherwise remove configuration from peer. */
5917 filter
= &peer
->filter
[afi
][safi
];
5918 if (filter
->plist
[direct
].name
)
5919 XFREE(MTYPE_BGP_FILTER_NAME
,
5920 filter
->plist
[direct
].name
);
5921 filter
->plist
[direct
].name
= NULL
;
5922 filter
->plist
[direct
].plist
= NULL
;
5925 /* Check if handling a regular peer. */
5926 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5927 /* Process peer route updates. */
5928 peer_on_policy_change(peer
, afi
, safi
,
5929 (direct
== FILTER_OUT
) ? 1 : 0);
5931 /* Skip peer-group mechanics for regular peers. */
5936 * Remove configuration on all peer-group members, unless they are
5937 * explicitely overriding peer-group configuration.
5939 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5940 /* Skip peers with overridden configuration. */
5941 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5942 PEER_FT_PREFIX_LIST
))
5945 /* Remove configuration on peer-group member. */
5946 filter
= &member
->filter
[afi
][safi
];
5947 if (filter
->plist
[direct
].name
)
5948 XFREE(MTYPE_BGP_FILTER_NAME
,
5949 filter
->plist
[direct
].name
);
5950 filter
->plist
[direct
].name
= NULL
;
5951 filter
->plist
[direct
].plist
= NULL
;
5953 /* Process peer route updates. */
5954 peer_on_policy_change(member
, afi
, safi
,
5955 (direct
== FILTER_OUT
) ? 1 : 0);
5961 /* Update prefix-list list. */
5962 static void peer_prefix_list_update(struct prefix_list
*plist
)
5964 struct listnode
*mnode
, *mnnode
;
5965 struct listnode
*node
, *nnode
;
5968 struct peer_group
*group
;
5969 struct bgp_filter
*filter
;
5974 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5977 * Update the prefix-list on update groups.
5979 update_group_policy_update(
5980 bgp
, BGP_POLICY_PREFIX_LIST
,
5981 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5983 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5984 FOREACH_AFI_SAFI (afi
, safi
) {
5985 filter
= &peer
->filter
[afi
][safi
];
5987 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5989 if (filter
->plist
[direct
].name
)
5990 filter
->plist
[direct
]
5991 .plist
= prefix_list_lookup(
5993 filter
->plist
[direct
]
5996 filter
->plist
[direct
].plist
=
6001 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6002 FOREACH_AFI_SAFI (afi
, safi
) {
6003 filter
= &group
->conf
->filter
[afi
][safi
];
6005 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6007 if (filter
->plist
[direct
].name
)
6008 filter
->plist
[direct
]
6009 .plist
= prefix_list_lookup(
6011 filter
->plist
[direct
]
6014 filter
->plist
[direct
].plist
=
6022 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6025 struct peer
*member
;
6026 struct bgp_filter
*filter
;
6027 struct listnode
*node
, *nnode
;
6029 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6030 return BGP_ERR_INVALID_VALUE
;
6032 /* Set configuration on peer. */
6033 filter
= &peer
->filter
[afi
][safi
];
6034 if (filter
->aslist
[direct
].name
)
6035 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
6036 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6037 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6039 /* Check if handling a regular peer. */
6040 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6041 /* Set override-flag and process peer route updates. */
6042 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6043 PEER_FT_FILTER_LIST
);
6044 peer_on_policy_change(peer
, afi
, safi
,
6045 (direct
== FILTER_OUT
) ? 1 : 0);
6047 /* Skip peer-group mechanics for regular peers. */
6052 * Set configuration on all peer-group members, unless they are
6053 * explicitely overriding peer-group configuration.
6055 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6056 /* Skip peers with overridden configuration. */
6057 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6058 PEER_FT_FILTER_LIST
))
6061 /* Set configuration on peer-group member. */
6062 filter
= &member
->filter
[afi
][safi
];
6063 if (filter
->aslist
[direct
].name
)
6064 XFREE(MTYPE_BGP_FILTER_NAME
,
6065 filter
->aslist
[direct
].name
);
6066 filter
->aslist
[direct
].name
=
6067 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6068 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6070 /* Process peer route updates. */
6071 peer_on_policy_change(member
, afi
, safi
,
6072 (direct
== FILTER_OUT
) ? 1 : 0);
6078 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6080 struct peer
*member
;
6081 struct bgp_filter
*filter
;
6082 struct listnode
*node
, *nnode
;
6084 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6085 return BGP_ERR_INVALID_VALUE
;
6087 /* Unset override-flag unconditionally. */
6088 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6089 PEER_FT_FILTER_LIST
);
6091 /* Inherit configuration from peer-group if peer is member. */
6092 if (peer_group_active(peer
)) {
6093 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6094 filter
[afi
][safi
].aslist
[direct
].name
,
6095 MTYPE_BGP_FILTER_NAME
);
6096 PEER_ATTR_INHERIT(peer
, peer
->group
,
6097 filter
[afi
][safi
].aslist
[direct
].aslist
);
6099 /* Otherwise remove configuration from peer. */
6100 filter
= &peer
->filter
[afi
][safi
];
6101 if (filter
->aslist
[direct
].name
)
6102 XFREE(MTYPE_BGP_FILTER_NAME
,
6103 filter
->aslist
[direct
].name
);
6104 filter
->aslist
[direct
].name
= NULL
;
6105 filter
->aslist
[direct
].aslist
= NULL
;
6108 /* Check if handling a regular peer. */
6109 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6110 /* Process peer route updates. */
6111 peer_on_policy_change(peer
, afi
, safi
,
6112 (direct
== FILTER_OUT
) ? 1 : 0);
6114 /* Skip peer-group mechanics for regular peers. */
6119 * Remove configuration on all peer-group members, unless they are
6120 * explicitely overriding peer-group configuration.
6122 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6123 /* Skip peers with overridden configuration. */
6124 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6125 PEER_FT_FILTER_LIST
))
6128 /* Remove configuration on peer-group member. */
6129 filter
= &member
->filter
[afi
][safi
];
6130 if (filter
->aslist
[direct
].name
)
6131 XFREE(MTYPE_BGP_FILTER_NAME
,
6132 filter
->aslist
[direct
].name
);
6133 filter
->aslist
[direct
].name
= NULL
;
6134 filter
->aslist
[direct
].aslist
= NULL
;
6136 /* Process peer route updates. */
6137 peer_on_policy_change(member
, afi
, safi
,
6138 (direct
== FILTER_OUT
) ? 1 : 0);
6144 static void peer_aslist_update(const char *aslist_name
)
6149 struct listnode
*mnode
, *mnnode
;
6150 struct listnode
*node
, *nnode
;
6153 struct peer_group
*group
;
6154 struct bgp_filter
*filter
;
6156 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6157 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6160 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6161 FOREACH_AFI_SAFI (afi
, safi
) {
6162 filter
= &peer
->filter
[afi
][safi
];
6164 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6166 if (filter
->aslist
[direct
].name
)
6167 filter
->aslist
[direct
]
6168 .aslist
= as_list_lookup(
6169 filter
->aslist
[direct
]
6172 filter
->aslist
[direct
].aslist
=
6177 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6178 FOREACH_AFI_SAFI (afi
, safi
) {
6179 filter
= &group
->conf
->filter
[afi
][safi
];
6181 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6183 if (filter
->aslist
[direct
].name
)
6184 filter
->aslist
[direct
]
6185 .aslist
= as_list_lookup(
6186 filter
->aslist
[direct
]
6189 filter
->aslist
[direct
].aslist
=
6197 static void peer_aslist_add(char *aslist_name
)
6199 peer_aslist_update(aslist_name
);
6200 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_ADDED
);
6203 static void peer_aslist_del(const char *aslist_name
)
6205 peer_aslist_update(aslist_name
);
6206 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6210 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6211 const char *name
, struct route_map
*route_map
)
6213 struct peer
*member
;
6214 struct bgp_filter
*filter
;
6215 struct listnode
*node
, *nnode
;
6217 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6218 return BGP_ERR_INVALID_VALUE
;
6220 /* Set configuration on peer. */
6221 filter
= &peer
->filter
[afi
][safi
];
6222 if (filter
->map
[direct
].name
) {
6223 /* If the neighbor is configured with the same route-map
6224 * again then, ignore the duplicate configuration.
6226 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6229 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6231 route_map_counter_decrement(filter
->map
[direct
].map
);
6232 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6233 filter
->map
[direct
].map
= route_map
;
6234 route_map_counter_increment(route_map
);
6236 /* Check if handling a regular peer. */
6237 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6238 /* Set override-flag and process peer route updates. */
6239 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6241 peer_on_policy_change(peer
, afi
, safi
,
6242 (direct
== RMAP_OUT
) ? 1 : 0);
6244 /* Skip peer-group mechanics for regular peers. */
6249 * Set configuration on all peer-group members, unless they are
6250 * explicitely overriding peer-group configuration.
6252 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6253 /* Skip peers with overridden configuration. */
6254 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6258 /* Set configuration on peer-group member. */
6259 filter
= &member
->filter
[afi
][safi
];
6260 if (filter
->map
[direct
].name
)
6261 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6262 route_map_counter_decrement(filter
->map
[direct
].map
);
6263 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6264 filter
->map
[direct
].map
= route_map
;
6265 route_map_counter_increment(route_map
);
6267 /* Process peer route updates. */
6268 peer_on_policy_change(member
, afi
, safi
,
6269 (direct
== RMAP_OUT
) ? 1 : 0);
6274 /* Unset route-map from the peer. */
6275 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6277 struct peer
*member
;
6278 struct bgp_filter
*filter
;
6279 struct listnode
*node
, *nnode
;
6281 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6282 return BGP_ERR_INVALID_VALUE
;
6284 /* Unset override-flag unconditionally. */
6285 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6287 /* Inherit configuration from peer-group if peer is member. */
6288 if (peer_group_active(peer
)) {
6289 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6290 filter
[afi
][safi
].map
[direct
].name
,
6291 MTYPE_BGP_FILTER_NAME
);
6292 PEER_ATTR_INHERIT(peer
, peer
->group
,
6293 filter
[afi
][safi
].map
[direct
].map
);
6295 /* Otherwise remove configuration from peer. */
6296 filter
= &peer
->filter
[afi
][safi
];
6297 if (filter
->map
[direct
].name
)
6298 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6299 route_map_counter_decrement(filter
->map
[direct
].map
);
6300 filter
->map
[direct
].name
= NULL
;
6301 filter
->map
[direct
].map
= NULL
;
6304 /* Check if handling a regular peer. */
6305 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6306 /* Process peer route updates. */
6307 peer_on_policy_change(peer
, afi
, safi
,
6308 (direct
== RMAP_OUT
) ? 1 : 0);
6310 /* Skip peer-group mechanics for regular peers. */
6315 * Remove configuration on all peer-group members, unless they are
6316 * explicitely overriding peer-group configuration.
6318 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6319 /* Skip peers with overridden configuration. */
6320 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6324 /* Remove configuration on peer-group member. */
6325 filter
= &member
->filter
[afi
][safi
];
6326 if (filter
->map
[direct
].name
)
6327 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6328 route_map_counter_decrement(filter
->map
[direct
].map
);
6329 filter
->map
[direct
].name
= NULL
;
6330 filter
->map
[direct
].map
= NULL
;
6332 /* Process peer route updates. */
6333 peer_on_policy_change(member
, afi
, safi
,
6334 (direct
== RMAP_OUT
) ? 1 : 0);
6340 /* Set unsuppress-map to the peer. */
6341 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6342 const char *name
, struct route_map
*route_map
)
6344 struct peer
*member
;
6345 struct bgp_filter
*filter
;
6346 struct listnode
*node
, *nnode
;
6348 /* Set configuration on peer. */
6349 filter
= &peer
->filter
[afi
][safi
];
6350 if (filter
->usmap
.name
)
6351 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6352 route_map_counter_decrement(filter
->usmap
.map
);
6353 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6354 filter
->usmap
.map
= route_map
;
6355 route_map_counter_increment(route_map
);
6357 /* Check if handling a regular peer. */
6358 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6359 /* Set override-flag and process peer route updates. */
6360 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6361 PEER_FT_UNSUPPRESS_MAP
);
6362 peer_on_policy_change(peer
, afi
, safi
, 1);
6364 /* Skip peer-group mechanics for regular peers. */
6369 * Set configuration on all peer-group members, unless they are
6370 * explicitely overriding peer-group configuration.
6372 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6373 /* Skip peers with overridden configuration. */
6374 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6375 PEER_FT_UNSUPPRESS_MAP
))
6378 /* Set configuration on peer-group member. */
6379 filter
= &member
->filter
[afi
][safi
];
6380 if (filter
->usmap
.name
)
6381 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6382 route_map_counter_decrement(filter
->usmap
.map
);
6383 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6384 filter
->usmap
.map
= route_map
;
6385 route_map_counter_increment(route_map
);
6387 /* Process peer route updates. */
6388 peer_on_policy_change(member
, afi
, safi
, 1);
6394 /* Unset route-map from the peer. */
6395 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6397 struct peer
*member
;
6398 struct bgp_filter
*filter
;
6399 struct listnode
*node
, *nnode
;
6401 /* Unset override-flag unconditionally. */
6402 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6404 /* Inherit configuration from peer-group if peer is member. */
6405 if (peer_group_active(peer
)) {
6406 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6407 filter
[afi
][safi
].usmap
.name
,
6408 MTYPE_BGP_FILTER_NAME
);
6409 PEER_ATTR_INHERIT(peer
, peer
->group
,
6410 filter
[afi
][safi
].usmap
.map
);
6412 /* Otherwise remove configuration from peer. */
6413 filter
= &peer
->filter
[afi
][safi
];
6414 if (filter
->usmap
.name
)
6415 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6416 route_map_counter_decrement(filter
->usmap
.map
);
6417 filter
->usmap
.name
= NULL
;
6418 filter
->usmap
.map
= NULL
;
6421 /* Check if handling a regular peer. */
6422 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6423 /* Process peer route updates. */
6424 peer_on_policy_change(peer
, afi
, safi
, 1);
6426 /* Skip peer-group mechanics for regular peers. */
6431 * Remove configuration on all peer-group members, unless they are
6432 * explicitely overriding peer-group configuration.
6434 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6435 /* Skip peers with overridden configuration. */
6436 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6437 PEER_FT_UNSUPPRESS_MAP
))
6440 /* Remove configuration on peer-group member. */
6441 filter
= &member
->filter
[afi
][safi
];
6442 if (filter
->usmap
.name
)
6443 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6444 route_map_counter_decrement(filter
->usmap
.map
);
6445 filter
->usmap
.name
= NULL
;
6446 filter
->usmap
.map
= NULL
;
6448 /* Process peer route updates. */
6449 peer_on_policy_change(member
, afi
, safi
, 1);
6455 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6456 uint32_t max
, uint8_t threshold
, int warning
,
6459 struct peer
*member
;
6460 struct listnode
*node
, *nnode
;
6462 /* Set flags and configuration on peer. */
6463 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6465 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6467 peer_af_flag_unset(peer
, afi
, safi
,
6468 PEER_FLAG_MAX_PREFIX_WARNING
);
6470 peer
->pmax
[afi
][safi
] = max
;
6471 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6472 peer
->pmax_restart
[afi
][safi
] = restart
;
6474 /* Check if handling a regular peer. */
6475 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6476 /* Re-check if peer violates maximum-prefix. */
6477 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6478 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6480 /* Skip peer-group mechanics for regular peers. */
6485 * Set flags and configuration on all peer-group members, unless they
6486 * are explicitely overriding peer-group configuration.
6488 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6489 /* Skip peers with overridden configuration. */
6490 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6491 PEER_FLAG_MAX_PREFIX
))
6494 /* Set flag and configuration on peer-group member. */
6495 member
->pmax
[afi
][safi
] = max
;
6496 member
->pmax_threshold
[afi
][safi
] = threshold
;
6497 member
->pmax_restart
[afi
][safi
] = restart
;
6499 SET_FLAG(member
->af_flags
[afi
][safi
],
6500 PEER_FLAG_MAX_PREFIX_WARNING
);
6502 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6503 PEER_FLAG_MAX_PREFIX_WARNING
);
6505 /* Re-check if peer violates maximum-prefix. */
6506 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6507 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6513 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6515 /* Inherit configuration from peer-group if peer is member. */
6516 if (peer_group_active(peer
)) {
6517 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6518 peer_af_flag_inherit(peer
, afi
, safi
,
6519 PEER_FLAG_MAX_PREFIX_WARNING
);
6520 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6521 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6522 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6527 /* Remove flags and configuration from peer. */
6528 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6529 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6530 peer
->pmax
[afi
][safi
] = 0;
6531 peer
->pmax_threshold
[afi
][safi
] = 0;
6532 peer
->pmax_restart
[afi
][safi
] = 0;
6535 * Remove flags and configuration from all peer-group members, unless
6536 * they are explicitely overriding peer-group configuration.
6538 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6539 struct peer
*member
;
6540 struct listnode
*node
;
6542 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6543 /* Skip peers with overridden configuration. */
6544 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6545 PEER_FLAG_MAX_PREFIX
))
6548 /* Remove flag and configuration on peer-group member.
6550 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6551 PEER_FLAG_MAX_PREFIX
);
6552 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6553 PEER_FLAG_MAX_PREFIX_WARNING
);
6554 member
->pmax
[afi
][safi
] = 0;
6555 member
->pmax_threshold
[afi
][safi
] = 0;
6556 member
->pmax_restart
[afi
][safi
] = 0;
6563 int is_ebgp_multihop_configured(struct peer
*peer
)
6565 struct peer_group
*group
;
6566 struct listnode
*node
, *nnode
;
6569 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6570 group
= peer
->group
;
6571 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6572 && (group
->conf
->ttl
!= BGP_DEFAULT_TTL
))
6575 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6576 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6577 && (peer1
->ttl
!= BGP_DEFAULT_TTL
))
6581 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6582 && (peer
->ttl
!= BGP_DEFAULT_TTL
))
6588 /* Set # of hops between us and BGP peer. */
6589 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6591 struct peer_group
*group
;
6592 struct listnode
*node
, *nnode
;
6595 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6596 gtsm_hops
, peer
->host
);
6598 /* We cannot configure ttl-security hops when ebgp-multihop is already
6599 set. For non peer-groups, the check is simple. For peer-groups,
6601 slightly messy, because we need to check both the peer-group
6603 and all peer-group members for any trace of ebgp-multihop
6605 before actually applying the ttl-security rules. Cisco really made a
6606 mess of this configuration parameter, and OpenBGPD got it right.
6609 if ((peer
->gtsm_hops
== BGP_GTSM_HOPS_DISABLED
)
6610 && (peer
->sort
!= BGP_PEER_IBGP
)) {
6611 if (is_ebgp_multihop_configured(peer
))
6612 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6614 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6615 peer
->gtsm_hops
= gtsm_hops
;
6617 /* Calling ebgp multihop also resets the session.
6618 * On restart, NHT will get setup correctly as will the
6619 * min & max ttls on the socket. The return value is
6622 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6627 group
= peer
->group
;
6628 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6630 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6632 /* Calling ebgp multihop also resets the
6634 * On restart, NHT will get setup correctly as
6636 * min & max ttls on the socket. The return
6640 peer_ebgp_multihop_set(peer
, MAXTTL
);
6644 /* Post the first gtsm setup or if its ibgp, maxttl setting
6646 * necessary, just set the minttl.
6648 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6649 peer
->gtsm_hops
= gtsm_hops
;
6652 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6653 MAXTTL
+ 1 - gtsm_hops
);
6654 if ((peer
->status
< Established
) && peer
->doppelganger
6655 && (peer
->doppelganger
->fd
>= 0))
6656 sockopt_minttl(peer
->su
.sa
.sa_family
,
6657 peer
->doppelganger
->fd
,
6658 MAXTTL
+ 1 - gtsm_hops
);
6660 group
= peer
->group
;
6661 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6663 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6665 /* Change setting of existing peer
6666 * established then change value (may break
6668 * not established yet (teardown session and
6670 * no session then do nothing (will get
6671 * handled by next connection)
6675 != BGP_GTSM_HOPS_DISABLED
)
6677 peer
->su
.sa
.sa_family
, peer
->fd
,
6678 MAXTTL
+ 1 - peer
->gtsm_hops
);
6679 if ((peer
->status
< Established
)
6680 && peer
->doppelganger
6681 && (peer
->doppelganger
->fd
>= 0))
6682 sockopt_minttl(peer
->su
.sa
.sa_family
,
6683 peer
->doppelganger
->fd
,
6684 MAXTTL
+ 1 - gtsm_hops
);
6692 int peer_ttl_security_hops_unset(struct peer
*peer
)
6694 struct peer_group
*group
;
6695 struct listnode
*node
, *nnode
;
6698 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6701 /* if a peer-group member, then reset to peer-group default rather than
6703 if (peer_group_active(peer
))
6704 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6706 peer
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
6708 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6709 /* Invoking ebgp_multihop_set will set the TTL back to the
6711 * value as well as restting the NHT and such. The session is
6714 if (peer
->sort
== BGP_PEER_EBGP
)
6715 ret
= peer_ebgp_multihop_unset(peer
);
6718 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6721 if ((peer
->status
< Established
) && peer
->doppelganger
6722 && (peer
->doppelganger
->fd
>= 0))
6723 sockopt_minttl(peer
->su
.sa
.sa_family
,
6724 peer
->doppelganger
->fd
, 0);
6727 group
= peer
->group
;
6728 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6729 peer
->gtsm_hops
= BGP_GTSM_HOPS_DISABLED
;
6730 if (peer
->sort
== BGP_PEER_EBGP
)
6731 ret
= peer_ebgp_multihop_unset(peer
);
6734 sockopt_minttl(peer
->su
.sa
.sa_family
,
6737 if ((peer
->status
< Established
)
6738 && peer
->doppelganger
6739 && (peer
->doppelganger
->fd
>= 0))
6740 sockopt_minttl(peer
->su
.sa
.sa_family
,
6741 peer
->doppelganger
->fd
,
6751 * If peer clear is invoked in a loop for all peers on the BGP instance,
6752 * it may end up freeing the doppelganger, and if this was the next node
6753 * to the current node, we would end up accessing the freed next node.
6754 * Pass along additional parameter which can be updated if next node
6755 * is freed; only required when walking the peer list on BGP instance.
6757 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6759 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6760 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6761 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6762 if (peer
->t_pmax_restart
) {
6763 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6764 if (bgp_debug_neighbor_events(peer
))
6766 "%s Maximum-prefix restart timer canceled",
6769 BGP_EVENT_ADD(peer
, BGP_Start
);
6773 peer
->v_start
= BGP_INIT_START_TIMER
;
6774 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6775 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6776 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6778 bgp_session_reset_safe(peer
, nnode
);
6783 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6784 enum bgp_clear_type stype
)
6786 struct peer_af
*paf
;
6788 if (peer
->status
!= Established
)
6791 if (!peer
->afc
[afi
][safi
])
6792 return BGP_ERR_AF_UNCONFIGURED
;
6794 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6796 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6797 /* Clear the "neighbor x.x.x.x default-originate" flag */
6798 paf
= peer_af_find(peer
, afi
, safi
);
6799 if (paf
&& paf
->subgroup
6800 && CHECK_FLAG(paf
->subgroup
->sflags
,
6801 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6802 UNSET_FLAG(paf
->subgroup
->sflags
,
6803 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6805 bgp_announce_route(peer
, afi
, safi
);
6808 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6809 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6810 PEER_CAP_ORF_PREFIX_SM_ADV
)
6811 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6812 PEER_CAP_ORF_PREFIX_RM_RCV
)
6813 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6814 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6815 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6816 uint8_t prefix_type
;
6818 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6819 PEER_CAP_ORF_PREFIX_RM_RCV
))
6820 prefix_type
= ORF_TYPE_PREFIX
;
6822 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6824 if (filter
->plist
[FILTER_IN
].plist
) {
6825 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6826 PEER_STATUS_ORF_PREFIX_SEND
))
6827 bgp_route_refresh_send(
6828 peer
, afi
, safi
, prefix_type
,
6830 bgp_route_refresh_send(peer
, afi
, safi
,
6832 REFRESH_IMMEDIATE
, 0);
6834 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6835 PEER_STATUS_ORF_PREFIX_SEND
))
6836 bgp_route_refresh_send(
6837 peer
, afi
, safi
, prefix_type
,
6838 REFRESH_IMMEDIATE
, 1);
6840 bgp_route_refresh_send(peer
, afi
, safi
,
6847 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6848 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6849 /* If neighbor has soft reconfiguration inbound flag.
6850 Use Adj-RIB-In database. */
6851 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6852 PEER_FLAG_SOFT_RECONFIG
))
6853 bgp_soft_reconfig_in(peer
, afi
, safi
);
6855 /* If neighbor has route refresh capability, send route
6857 message to the peer. */
6858 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6859 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6860 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6863 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6869 /* Display peer uptime.*/
6870 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6873 time_t uptime1
, epoch_tbuf
;
6876 /* If there is no connection has been done before print `never'. */
6879 json_object_string_add(json
, "peerUptime", "never");
6880 json_object_int_add(json
, "peerUptimeMsec", 0);
6882 snprintf(buf
, len
, "never");
6886 /* Get current time. */
6887 uptime1
= bgp_clock();
6889 gmtime_r(&uptime1
, &tm
);
6891 if (uptime1
< ONE_DAY_SECOND
)
6892 snprintf(buf
, len
, "%02d:%02d:%02d", tm
.tm_hour
, tm
.tm_min
,
6894 else if (uptime1
< ONE_WEEK_SECOND
)
6895 snprintf(buf
, len
, "%dd%02dh%02dm", tm
.tm_yday
, tm
.tm_hour
,
6897 else if (uptime1
< ONE_YEAR_SECOND
)
6898 snprintf(buf
, len
, "%02dw%dd%02dh", tm
.tm_yday
/ 7,
6899 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7), tm
.tm_hour
);
6901 snprintf(buf
, len
, "%02dy%02dw%dd", tm
.tm_year
- 70,
6903 tm
.tm_yday
- ((tm
.tm_yday
/ 7) * 7));
6906 epoch_tbuf
= time(NULL
) - uptime1
;
6907 json_object_string_add(json
, "peerUptime", buf
);
6908 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6909 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6916 void bgp_master_init(struct thread_master
*master
, const int buffer_size
)
6920 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
6923 bm
->bgp
= list_new();
6924 bm
->listen_sockets
= list_new();
6925 bm
->port
= BGP_PORT_DEFAULT
;
6926 bm
->master
= master
;
6927 bm
->start_time
= bgp_clock();
6928 bm
->t_rmap_update
= NULL
;
6929 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
6930 bm
->terminating
= false;
6931 bm
->socket_buffer
= buffer_size
;
6933 bgp_process_queue_init();
6936 /* init the rd id space.
6937 assign 0th index in the bitfield,
6938 so that we start with id 1
6940 bf_init(bm
->rd_idspace
, UINT16_MAX
);
6941 bf_assign_zero_index(bm
->rd_idspace
);
6943 /* mpls label dynamic allocation pool */
6944 bgp_lp_init(bm
->master
, &bm
->labelpool
);
6946 QOBJ_REG(bm
, bgp_master
);
6950 * Free up connected routes and interfaces for a BGP instance. Invoked upon
6951 * instance delete (non-default only) or BGP exit.
6953 static void bgp_if_finish(struct bgp
*bgp
)
6956 struct interface
*ifp
;
6958 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
6960 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
6963 FOR_ALL_INTERFACES (vrf
, ifp
) {
6964 struct listnode
*c_node
, *c_nnode
;
6965 struct connected
*c
;
6967 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
6968 bgp_connected_delete(bgp
, c
);
6972 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
6974 struct vrf
*vrf
= NULL
;
6975 struct listnode
*next
;
6978 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
6979 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
6981 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6982 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
6985 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
6989 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
6991 struct listnode
*next
, *next2
;
6992 struct bgp
*bgp
, *bgp2
;
6995 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6997 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
6998 if (bgp2
->as
== bgp
->as
)
7006 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
7007 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
7011 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7012 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7013 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
7014 {.completions
= NULL
},
7017 struct frr_pthread
*bgp_pth_io
;
7018 struct frr_pthread
*bgp_pth_ka
;
7020 static void bgp_pthreads_init(void)
7022 assert(!bgp_pth_io
);
7023 assert(!bgp_pth_ka
);
7025 struct frr_pthread_attr io
= {
7026 .start
= frr_pthread_attr_default
.start
,
7027 .stop
= frr_pthread_attr_default
.stop
,
7029 struct frr_pthread_attr ka
= {
7030 .start
= bgp_keepalives_start
,
7031 .stop
= bgp_keepalives_stop
,
7033 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7034 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7037 void bgp_pthreads_run(void)
7039 frr_pthread_run(bgp_pth_io
, NULL
);
7040 frr_pthread_run(bgp_pth_ka
, NULL
);
7042 /* Wait until threads are ready. */
7043 frr_pthread_wait_running(bgp_pth_io
);
7044 frr_pthread_wait_running(bgp_pth_ka
);
7047 void bgp_pthreads_finish(void)
7049 frr_pthread_stop_all();
7052 void bgp_init(unsigned short instance
)
7055 /* allocates some vital data structures used by peer commands in
7058 /* pre-init pthreads */
7059 bgp_pthreads_init();
7062 bgp_zebra_init(bm
->master
, instance
);
7064 #ifdef ENABLE_BGP_VNC
7065 vnc_zebra_init(bm
->master
);
7068 /* BGP VTY commands installation. */
7076 bgp_route_map_init();
7077 bgp_scan_vty_init();
7079 #ifdef ENABLE_BGP_VNC
7082 bgp_ethernetvpn_init();
7083 bgp_flowspec_vty_init();
7085 /* Access list initialize. */
7087 access_list_add_hook(peer_distribute_update
);
7088 access_list_delete_hook(peer_distribute_update
);
7090 /* Filter list initialize. */
7092 as_list_add_hook(peer_aslist_add
);
7093 as_list_delete_hook(peer_aslist_del
);
7095 /* Prefix list initialize.*/
7097 prefix_list_add_hook(peer_prefix_list_update
);
7098 prefix_list_delete_hook(peer_prefix_list_update
);
7100 /* Community list initialize. */
7101 bgp_clist
= community_list_init();
7106 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7109 void bgp_terminate(void)
7113 struct listnode
*node
, *nnode
;
7114 struct listnode
*mnode
, *mnnode
;
7118 /* Close the listener sockets first as this prevents peers from
7120 * to reconnect on receiving the peer unconfig message. In the presence
7121 * of a large number of peers this will ensure that no peer is left with
7122 * a dangling connection
7124 /* reverse bgp_master_init */
7127 if (bm
->listen_sockets
)
7128 list_delete(&bm
->listen_sockets
);
7130 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7131 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7132 if (peer
->status
== Established
7133 || peer
->status
== OpenSent
7134 || peer
->status
== OpenConfirm
)
7135 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7136 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7138 if (bm
->process_main_queue
)
7139 work_queue_free_and_null(&bm
->process_main_queue
);
7141 if (bm
->t_rmap_update
)
7142 BGP_TIMER_OFF(bm
->t_rmap_update
);
7147 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
7148 const char *ip_str
, bool use_json
)
7154 /* Get peer sockunion. */
7155 ret
= str2sockunion(ip_str
, &su
);
7157 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
7159 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
7163 json_object
*json_no
= NULL
;
7164 json_no
= json_object_new_object();
7165 json_object_string_add(
7167 "malformedAddressOrName",
7169 vty_out(vty
, "%s\n",
7170 json_object_to_json_string_ext(
7172 JSON_C_TO_STRING_PRETTY
));
7173 json_object_free(json_no
);
7176 "%% Malformed address or name: %s\n",
7184 /* Peer structure lookup. */
7185 peer
= peer_lookup(bgp
, &su
);
7188 json_object
*json_no
= NULL
;
7189 json_no
= json_object_new_object();
7190 json_object_string_add(json_no
, "warning",
7191 "No such neighbor in this view/vrf");
7192 vty_out(vty
, "%s\n",
7193 json_object_to_json_string_ext(
7194 json_no
, JSON_C_TO_STRING_PRETTY
));
7195 json_object_free(json_no
);
7197 vty_out(vty
, "No such neighbor in this view/vrf\n");
7204 void bgp_gr_apply_running_config(void)
7206 struct peer
*peer
= NULL
;
7207 struct bgp
*bgp
= NULL
;
7208 struct listnode
*node
, *nnode
;
7209 bool gr_router_detected
= false;
7211 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
7212 zlog_debug("[BGP_GR] %s called !", __func__
);
7214 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
7215 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7216 bgp_peer_gr_flags_update(peer
);
7217 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
))
7218 gr_router_detected
= true;
7221 if (gr_router_detected
7222 && bgp
->present_zebra_gr_state
== ZEBRA_GR_DISABLE
) {
7223 bgp_zebra_send_capabilities(bgp
, true);
7224 } else if (!gr_router_detected
7225 && bgp
->present_zebra_gr_state
== ZEBRA_GR_ENABLE
) {
7226 bgp_zebra_send_capabilities(bgp
, false);
7229 gr_router_detected
= false;