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 /* BGP flag manipulation. */
205 int bgp_flag_set(struct bgp
*bgp
, int flag
)
207 SET_FLAG(bgp
->flags
, flag
);
211 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
213 UNSET_FLAG(bgp
->flags
, flag
);
217 int bgp_flag_check(struct bgp
*bgp
, int flag
)
219 return CHECK_FLAG(bgp
->flags
, flag
);
222 /* Internal function to set BGP structure configureation flag. */
223 static void bgp_config_set(struct bgp
*bgp
, int config
)
225 SET_FLAG(bgp
->config
, config
);
228 static void bgp_config_unset(struct bgp
*bgp
, int config
)
230 UNSET_FLAG(bgp
->config
, config
);
233 static int bgp_config_check(struct bgp
*bgp
, int config
)
235 return CHECK_FLAG(bgp
->config
, config
);
238 /* Set BGP router identifier; distinguish between explicit config and other
241 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
,
245 struct listnode
*node
, *nnode
;
247 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
250 /* EVPN uses router id in RD, withdraw them */
251 if (is_evpn_enabled())
252 bgp_evpn_handle_router_id_update(bgp
, true);
254 vpn_handle_router_id_update(bgp
, true, is_config
);
256 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
258 /* Set all peer's local identifier with this value. */
259 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
260 IPV4_ADDR_COPY(&peer
->local_id
, id
);
262 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
263 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
264 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
265 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
269 /* EVPN uses router id in RD, update them */
270 if (is_evpn_enabled())
271 bgp_evpn_handle_router_id_update(bgp
, false);
273 vpn_handle_router_id_update(bgp
, false, is_config
);
278 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
280 struct listnode
*node
, *nnode
;
282 struct in_addr
*addr
= NULL
;
284 if (router_id
!= NULL
)
285 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
287 if (vrf_id
== VRF_DEFAULT
) {
288 /* Router-id change for default VRF has to also update all
290 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
291 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
295 bgp
->router_id_zebra
= *addr
;
297 addr
= &bgp
->router_id_zebra
;
299 if (!bgp
->router_id_static
.s_addr
) {
300 /* Router ID is updated if there are no active
303 if (bgp
->established_peers
== 0) {
304 if (BGP_DEBUG(zebra
, ZEBRA
))
305 zlog_debug("RID change : vrf %u, RTR ID %s",
306 bgp
->vrf_id
, inet_ntoa(*addr
));
307 bgp_router_id_set(bgp
, addr
, false);
312 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
315 bgp
->router_id_zebra
= *addr
;
317 addr
= &bgp
->router_id_zebra
;
319 if (!bgp
->router_id_static
.s_addr
) {
320 /* Router ID is updated if there are no active
323 if (bgp
->established_peers
== 0) {
324 if (BGP_DEBUG(zebra
, ZEBRA
))
325 zlog_debug("RID change : vrf %u, RTR ID %s",
326 bgp
->vrf_id
, inet_ntoa(*addr
));
327 bgp_router_id_set(bgp
, addr
, false);
335 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
337 bgp
->router_id_static
= id
;
338 bgp_router_id_set(bgp
,
339 id
.s_addr
!= INADDR_ANY
? &id
: &bgp
->router_id_zebra
,
340 true /* is config */);
344 /* BGP's cluster-id control. */
345 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
348 struct listnode
*node
, *nnode
;
350 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
351 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
354 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
355 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
357 /* Clear all IBGP peer. */
358 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
359 if (peer
->sort
!= BGP_PEER_IBGP
)
362 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
363 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
364 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
365 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
371 int bgp_cluster_id_unset(struct bgp
*bgp
)
374 struct listnode
*node
, *nnode
;
376 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
379 bgp
->cluster_id
.s_addr
= 0;
380 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
382 /* Clear all IBGP peer. */
383 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
384 if (peer
->sort
!= BGP_PEER_IBGP
)
387 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
388 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
389 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
390 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
396 /* time_t value that is monotonicly increasing
397 * and uneffected by adjustments to system clock
399 time_t bgp_clock(void)
407 /* BGP timer configuration. */
408 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
,
409 uint32_t connect_retry
)
411 bgp
->default_keepalive
=
412 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
413 bgp
->default_holdtime
= holdtime
;
414 bgp
->default_connect_retry
= connect_retry
;
419 /* mostly for completeness - CLI uses its own defaults */
420 int bgp_timers_unset(struct bgp
*bgp
)
422 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
423 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
424 bgp
->default_connect_retry
= BGP_DEFAULT_CONNECT_RETRY
;
429 /* BGP confederation configuration. */
430 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
433 struct listnode
*node
, *nnode
;
437 return BGP_ERR_INVALID_AS
;
439 /* Remember - were we doing confederation before? */
440 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
442 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
444 /* If we were doing confederation already, this is just an external
445 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
446 were not doing confederation before, reset all EBGP sessions. */
447 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
448 /* We're looking for peers who's AS is not local or part of our
450 if (already_confed
) {
451 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
453 if (BGP_IS_VALID_STATE_FOR_NOTIF(
456 PEER_DOWN_CONFED_ID_CHANGE
;
458 peer
, BGP_NOTIFY_CEASE
,
459 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
461 bgp_session_reset_safe(peer
, &nnode
);
464 /* Not doign confederation before, so reset every
467 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
468 /* Reset the local_as to be our EBGP one */
469 if (peer_sort(peer
) == BGP_PEER_EBGP
)
471 if (BGP_IS_VALID_STATE_FOR_NOTIF(
474 PEER_DOWN_CONFED_ID_CHANGE
;
476 peer
, BGP_NOTIFY_CEASE
,
477 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
479 bgp_session_reset_safe(peer
, &nnode
);
486 int bgp_confederation_id_unset(struct bgp
*bgp
)
489 struct listnode
*node
, *nnode
;
492 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
494 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
495 /* We're looking for peers who's AS is not local */
496 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
497 peer
->local_as
= bgp
->as
;
498 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
499 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
500 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
501 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
505 bgp_session_reset_safe(peer
, &nnode
);
511 /* Is an AS part of the confed or not? */
512 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
519 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
520 if (bgp
->confed_peers
[i
] == as
)
526 /* Add an AS to the confederation set. */
527 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
530 struct listnode
*node
, *nnode
;
533 return BGP_ERR_INVALID_BGP
;
536 return BGP_ERR_INVALID_AS
;
538 if (bgp_confederation_peers_check(bgp
, as
))
541 if (bgp
->confed_peers
)
543 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
544 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
547 XMALLOC(MTYPE_BGP_CONFED_LIST
,
548 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
550 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
551 bgp
->confed_peers_cnt
++;
553 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
554 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
555 if (peer
->as
== as
) {
556 peer
->local_as
= bgp
->as
;
557 if (BGP_IS_VALID_STATE_FOR_NOTIF(
560 PEER_DOWN_CONFED_PEER_CHANGE
;
562 peer
, BGP_NOTIFY_CEASE
,
563 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
565 bgp_session_reset_safe(peer
, &nnode
);
572 /* Delete an AS from the confederation set. */
573 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
578 struct listnode
*node
, *nnode
;
583 if (!bgp_confederation_peers_check(bgp
, as
))
586 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
587 if (bgp
->confed_peers
[i
] == as
)
588 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
589 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
591 bgp
->confed_peers_cnt
--;
593 if (bgp
->confed_peers_cnt
== 0) {
594 if (bgp
->confed_peers
)
595 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
596 bgp
->confed_peers
= NULL
;
599 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
600 bgp
->confed_peers_cnt
* sizeof(as_t
));
602 /* Now reset any peer who's remote AS has just been removed from the
604 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
605 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
606 if (peer
->as
== as
) {
607 peer
->local_as
= bgp
->confed_id
;
608 if (BGP_IS_VALID_STATE_FOR_NOTIF(
611 PEER_DOWN_CONFED_PEER_CHANGE
;
613 peer
, BGP_NOTIFY_CEASE
,
614 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
616 bgp_session_reset_safe(peer
, &nnode
);
624 /* Local preference configuration. */
625 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
630 bgp
->default_local_pref
= local_pref
;
635 int bgp_default_local_preference_unset(struct bgp
*bgp
)
640 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
645 /* Local preference configuration. */
646 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
651 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
656 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
660 bgp
->default_subgroup_pkt_queue_max
=
661 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
666 /* Listen limit configuration. */
667 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
672 bgp
->dynamic_neighbors_limit
= listen_limit
;
677 int bgp_listen_limit_unset(struct bgp
*bgp
)
682 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
687 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
688 afi_t
*afi
, safi_t
*safi
)
690 /* Map from IANA values to internal values, return error if
691 * values are unrecognized.
693 *afi
= afi_iana2int(pkt_afi
);
694 *safi
= safi_iana2int(pkt_safi
);
695 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
701 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
702 iana_safi_t
*pkt_safi
)
704 /* Map from internal values to IANA values, return error if
705 * internal values are bad (unexpected).
707 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
709 *pkt_afi
= afi_int2iana(afi
);
710 *pkt_safi
= safi_int2iana(safi
);
714 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
723 afid
= afindex(afi
, safi
);
724 if (afid
>= BGP_AF_MAX
)
728 assert(peer
->peer_af_array
[afid
] == NULL
);
730 /* Allocate new peer af */
731 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
733 peer
->peer_af_array
[afid
] = af
;
738 bgp
->af_peer_count
[afi
][safi
]++;
743 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
750 afid
= afindex(afi
, safi
);
751 if (afid
>= BGP_AF_MAX
)
754 return peer
->peer_af_array
[afid
];
757 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
766 afid
= afindex(afi
, safi
);
767 if (afid
>= BGP_AF_MAX
)
770 af
= peer
->peer_af_array
[afid
];
775 bgp_stop_announce_route_timer(af
);
777 if (PAF_SUBGRP(af
)) {
778 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
779 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
780 af
->subgroup
->update_group
->id
,
781 af
->subgroup
->id
, peer
->host
);
785 update_subgroup_remove_peer(af
->subgroup
, af
);
787 if (bgp
->af_peer_count
[afi
][safi
])
788 bgp
->af_peer_count
[afi
][safi
]--;
790 peer
->peer_af_array
[afid
] = NULL
;
791 XFREE(MTYPE_BGP_PEER_AF
, af
);
795 /* Peer comparison function for sorting. */
796 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
798 if (p1
->group
&& !p2
->group
)
801 if (!p1
->group
&& p2
->group
)
804 if (p1
->group
== p2
->group
) {
805 if (p1
->conf_if
&& !p2
->conf_if
)
808 if (!p1
->conf_if
&& p2
->conf_if
)
811 if (p1
->conf_if
&& p2
->conf_if
)
812 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
814 return strcmp(p1
->group
->name
, p2
->group
->name
);
816 return sockunion_cmp(&p1
->su
, &p2
->su
);
819 static unsigned int peer_hash_key_make(const void *p
)
821 const struct peer
*peer
= p
;
822 return sockunion_hash(&peer
->su
);
825 static bool peer_hash_same(const void *p1
, const void *p2
)
827 const struct peer
*peer1
= p1
;
828 const struct peer
*peer2
= p2
;
829 return (sockunion_same(&peer1
->su
, &peer2
->su
)
830 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
831 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
834 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
838 /* Skip if peer is not a peer-group member. */
839 if (!peer_group_active(peer
))
842 /* Unset override flag to signal inheritance from peer-group. */
843 UNSET_FLAG(peer
->flags_override
, flag
);
846 * Inherit flag state from peer-group. If the flag of the peer-group is
847 * not being inverted, the peer must inherit the inverse of the current
848 * peer-group flag state.
850 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
851 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
852 && CHECK_FLAG(peer
->flags_invert
, flag
))
853 COND_FLAG(peer
->flags
, flag
, !group_val
);
855 COND_FLAG(peer
->flags
, flag
, group_val
);
858 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
860 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
863 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
868 /* Skip if peer is not a peer-group member. */
869 if (!peer_group_active(peer
))
872 /* Unset override flag to signal inheritance from peer-group. */
873 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
876 * Inherit flag state from peer-group. If the flag of the peer-group is
877 * not being inverted, the peer must inherit the inverse of the current
878 * peer-group flag state.
880 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
881 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
882 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
883 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
885 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
888 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
889 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
896 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
897 if (peer
->as_type
== AS_INTERNAL
)
898 return BGP_PEER_IBGP
;
900 else if (peer
->as_type
== AS_EXTERNAL
)
901 return BGP_PEER_EBGP
;
903 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
905 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
913 peer1
= listnode_head(peer
->group
->peer
);
918 return BGP_PEER_INTERNAL
;
922 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
923 if (peer
->local_as
== 0)
924 return BGP_PEER_INTERNAL
;
926 if (peer
->local_as
== peer
->as
) {
927 if (bgp
->as
== bgp
->confed_id
) {
928 if (peer
->local_as
== bgp
->as
)
929 return BGP_PEER_IBGP
;
931 return BGP_PEER_EBGP
;
933 if (peer
->local_as
== bgp
->confed_id
)
934 return BGP_PEER_EBGP
;
936 return BGP_PEER_IBGP
;
940 if (bgp_confederation_peers_check(bgp
, peer
->as
))
941 return BGP_PEER_CONFED
;
943 return BGP_PEER_EBGP
;
945 if (peer
->as_type
== AS_UNSPECIFIED
) {
946 /* check if in peer-group with AS information */
948 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
949 if (peer
->group
->conf
->as_type
952 == peer
->group
->conf
->as
)
953 return BGP_PEER_IBGP
;
955 return BGP_PEER_EBGP
;
956 } else if (peer
->group
->conf
->as_type
958 return BGP_PEER_IBGP
;
960 return BGP_PEER_EBGP
;
962 /* no AS information anywhere, let caller know */
963 return BGP_PEER_UNSPECIFIED
;
964 } else if (peer
->as_type
!= AS_SPECIFIED
)
965 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
968 return (peer
->local_as
== 0
970 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
975 /* Calculate and cache the peer "sort" */
976 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
978 peer
->sort
= peer_calc_sort(peer
);
982 static void peer_free(struct peer
*peer
)
987 assert(peer
->status
== Deleted
);
991 /* this /ought/ to have been done already through bgp_stop earlier,
992 * but just to be sure..
996 bgp_writes_off(peer
);
997 assert(!peer
->t_write
);
998 assert(!peer
->t_read
);
999 BGP_EVENT_FLUSH(peer
);
1001 pthread_mutex_destroy(&peer
->io_mtx
);
1003 /* Free connected nexthop, if present */
1004 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1005 && !peer_dynamic_neighbor(peer
))
1006 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1009 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1011 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1012 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1013 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1014 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1016 /* Update source configuration. */
1017 if (peer
->update_source
) {
1018 sockunion_free(peer
->update_source
);
1019 peer
->update_source
= NULL
;
1022 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1024 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1025 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1027 if (peer
->clear_node_queue
)
1028 work_queue_free_and_null(&peer
->clear_node_queue
);
1030 bgp_sync_delete(peer
);
1032 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1034 bfd_info_free(&(peer
->bfd_info
));
1036 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1037 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1038 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1043 bgp_unlock(peer
->bgp
);
1045 memset(peer
, 0, sizeof(struct peer
));
1047 XFREE(MTYPE_BGP_PEER
, peer
);
1050 /* increase reference count on a struct peer */
1051 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1053 assert(peer
&& (peer
->lock
>= 0));
1056 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1064 /* decrease reference count on a struct peer
1065 * struct peer is freed and NULL returned if last reference
1067 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1069 assert(peer
&& (peer
->lock
> 0));
1072 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1077 if (peer
->lock
== 0) {
1084 /* BGP GR changes */
1086 int bgp_global_gr_init(struct bgp
*bgp
)
1088 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
1089 zlog_debug("%s called ..", __func__
);
1091 int local_GLOBAL_GR_FSM
[BGP_GLOBAL_GR_MODE
][BGP_GLOBAL_GR_EVENT_CMD
] = {
1092 /* GLOBAL_HELPER Mode */
1095 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1096 GLOBAL_GR
, GLOBAL_INVALID
,
1097 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1098 GLOBAL_DISABLE
, GLOBAL_INVALID
1100 /* GLOBAL_GR Mode */
1103 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1104 GLOBAL_INVALID
, GLOBAL_HELPER
,
1105 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1106 GLOBAL_DISABLE
, GLOBAL_INVALID
1108 /* GLOBAL_DISABLE Mode */
1111 /*GLOBAL_GR_cmd */ /*no_Global_GR_cmd*/
1112 GLOBAL_GR
, GLOBAL_INVALID
,
1113 /*GLOBAL_DISABLE_cmd*//*no_Global_Disable_cmd*/
1114 GLOBAL_INVALID
, GLOBAL_HELPER
1116 /* GLOBAL_INVALID Mode */
1119 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1120 GLOBAL_INVALID
, GLOBAL_INVALID
,
1121 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1122 GLOBAL_INVALID
, GLOBAL_INVALID
1125 memcpy(bgp
->GLOBAL_GR_FSM
, local_GLOBAL_GR_FSM
,
1126 sizeof(local_GLOBAL_GR_FSM
));
1128 bgp
->global_gr_present_state
= GLOBAL_HELPER
;
1129 bgp
->present_zebra_gr_state
= ZEBRA_GR_DISABLE
;
1131 return BGP_GR_SUCCESS
;
1134 int bgp_peer_gr_init(struct peer
*peer
)
1136 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
1137 zlog_debug("%s called ..", __func__
);
1139 struct bgp_peer_gr local_Peer_GR_FSM
[BGP_PEER_GR_MODE
]
1140 [BGP_PEER_GR_EVENT_CMD
] = {
1142 /* PEER_HELPER Mode */
1143 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1144 { PEER_GR
, bgp_peer_gr_action
}, {PEER_INVALID
, NULL
},
1145 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1146 {PEER_DISABLE
, bgp_peer_gr_action
}, {PEER_INVALID
, NULL
},
1147 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1148 { PEER_INVALID
, NULL
}, {PEER_GLOBAL_INHERIT
,
1149 bgp_peer_gr_action
}
1153 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1154 { PEER_INVALID
, NULL
}, { PEER_GLOBAL_INHERIT
,
1155 bgp_peer_gr_action
},
1156 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1157 {PEER_DISABLE
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1158 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1159 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1162 /* PEER_DISABLE Mode */
1163 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1164 { PEER_GR
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1165 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1166 { PEER_INVALID
, NULL
}, { PEER_GLOBAL_INHERIT
,
1167 bgp_peer_gr_action
},
1168 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1169 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1172 /* PEER_INVALID Mode */
1173 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1174 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1175 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1176 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1177 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1178 { PEER_INVALID
, NULL
}, { PEER_INVALID
, NULL
},
1181 /* PEER_GLOBAL_INHERIT Mode */
1182 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1183 { PEER_GR
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1184 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1185 { PEER_DISABLE
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
},
1186 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1187 { PEER_HELPER
, bgp_peer_gr_action
}, { PEER_INVALID
, NULL
}
1190 memcpy(&peer
->PEER_GR_FSM
, local_Peer_GR_FSM
,
1191 sizeof(local_Peer_GR_FSM
));
1192 peer
->peer_gr_present_state
= PEER_GLOBAL_INHERIT
;
1193 bgp_peer_move_to_gr_mode(peer
, PEER_GLOBAL_INHERIT
);
1195 return BGP_GR_SUCCESS
;
1198 /* Allocate new peer object, implicitely locked. */
1199 struct peer
*peer_new(struct bgp
*bgp
)
1206 /* bgp argument is absolutely required */
1211 /* Allocate new peer. */
1212 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1214 /* Set default value. */
1216 peer
->v_start
= BGP_INIT_START_TIMER
;
1217 peer
->v_connect
= bgp
->default_connect_retry
;
1218 peer
->status
= Idle
;
1219 peer
->ostatus
= Idle
;
1220 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1221 peer
->bgp
= bgp_lock(bgp
);
1222 peer
= peer_lock(peer
); /* initial reference */
1223 peer
->password
= NULL
;
1225 /* Set default flags. */
1226 FOREACH_AFI_SAFI (afi
, safi
) {
1227 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
1228 SET_FLAG(peer
->af_flags
[afi
][safi
],
1229 PEER_FLAG_SEND_EXT_COMMUNITY
);
1230 SET_FLAG(peer
->af_flags
[afi
][safi
],
1231 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1233 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1234 PEER_FLAG_SEND_COMMUNITY
);
1235 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1236 PEER_FLAG_SEND_EXT_COMMUNITY
);
1237 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1238 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1239 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1242 /* set nexthop-unchanged for l2vpn evpn by default */
1243 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1244 PEER_FLAG_NEXTHOP_UNCHANGED
);
1246 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1248 /* Initialize per peer bgp GR FSM */
1249 bgp_peer_gr_init(peer
);
1251 /* Create buffers. */
1252 peer
->ibuf
= stream_fifo_new();
1253 peer
->obuf
= stream_fifo_new();
1254 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1256 /* We use a larger buffer for peer->obuf_work in the event that:
1257 * - We RX a BGP_UPDATE where the attributes alone are just
1258 * under BGP_MAX_PACKET_SIZE
1259 * - The user configures an outbound route-map that does many as-path
1260 * prepends or adds many communities. At most they can have
1261 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1262 * large they can make the attributes.
1264 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1265 * bounds checking for every single attribute as we construct an
1269 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1271 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1273 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1275 bgp_sync_init(peer
);
1277 /* Get service port number. */
1278 sp
= getservbyname("bgp", "tcp");
1279 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1281 QOBJ_REG(peer
, peer
);
1286 * This function is invoked when a duplicate peer structure associated with
1287 * a neighbor is being deleted. If this about-to-be-deleted structure is
1288 * the one with all the config, then we have to copy over the info.
1290 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1292 struct peer_af
*paf
;
1300 /* The following function is used by both peer group config copy to
1301 * individual peer and when we transfer config
1303 if (peer_src
->change_local_as
)
1304 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1306 /* peer flags apply */
1307 peer_dst
->flags
= peer_src
->flags
;
1308 peer_dst
->cap
= peer_src
->cap
;
1310 peer_dst
->peer_gr_present_state
= peer_src
->peer_gr_present_state
;
1311 peer_dst
->peer_gr_new_status_flag
= peer_src
->peer_gr_new_status_flag
;
1313 peer_dst
->local_as
= peer_src
->local_as
;
1314 peer_dst
->port
= peer_src
->port
;
1315 (void)peer_sort(peer_dst
);
1316 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1319 peer_dst
->holdtime
= peer_src
->holdtime
;
1320 peer_dst
->keepalive
= peer_src
->keepalive
;
1321 peer_dst
->connect
= peer_src
->connect
;
1322 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1323 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1324 peer_dst
->routeadv
= peer_src
->routeadv
;
1325 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1327 /* password apply */
1328 if (peer_src
->password
&& !peer_dst
->password
)
1329 peer_dst
->password
=
1330 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1332 FOREACH_AFI_SAFI (afi
, safi
) {
1333 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1334 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1335 peer_dst
->allowas_in
[afi
][safi
] =
1336 peer_src
->allowas_in
[afi
][safi
];
1337 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1338 peer_dst
->addpath_type
[afi
][safi
] =
1339 peer_src
->addpath_type
[afi
][safi
];
1342 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1343 paf
= peer_src
->peer_af_array
[afidx
];
1345 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1348 /* update-source apply */
1349 if (peer_src
->update_source
) {
1350 if (peer_dst
->update_source
)
1351 sockunion_free(peer_dst
->update_source
);
1352 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1353 peer_dst
->update_source
=
1354 sockunion_dup(peer_src
->update_source
);
1355 } else if (peer_src
->update_if
) {
1356 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1357 if (peer_dst
->update_source
) {
1358 sockunion_free(peer_dst
->update_source
);
1359 peer_dst
->update_source
= NULL
;
1361 peer_dst
->update_if
=
1362 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1365 if (peer_src
->ifname
) {
1366 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1369 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1373 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1374 struct interface
*ifp
)
1376 struct connected
*ifc
;
1379 struct listnode
*node
;
1381 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1382 * IPv4 address of the other end.
1384 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1385 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1386 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1387 if (p
.prefixlen
== 30) {
1388 peer
->su
.sa
.sa_family
= AF_INET
;
1389 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1391 peer
->su
.sin
.sin_addr
.s_addr
=
1393 else if (addr
% 4 == 2)
1394 peer
->su
.sin
.sin_addr
.s_addr
=
1396 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1397 peer
->su
.sin
.sin_len
=
1398 sizeof(struct sockaddr_in
);
1399 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1401 } else if (p
.prefixlen
== 31) {
1402 peer
->su
.sa
.sa_family
= AF_INET
;
1403 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1405 peer
->su
.sin
.sin_addr
.s_addr
=
1408 peer
->su
.sin
.sin_addr
.s_addr
=
1410 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1411 peer
->su
.sin
.sin_len
=
1412 sizeof(struct sockaddr_in
);
1413 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1415 } else if (bgp_debug_neighbor_events(peer
))
1417 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1425 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1426 struct interface
*ifp
)
1428 struct nbr_connected
*ifc_nbr
;
1430 /* Have we learnt the peer's IPv6 link-local address? */
1431 if (ifp
->nbr_connected
1432 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1433 peer
->su
.sa
.sa_family
= AF_INET6
;
1434 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1435 sizeof(struct in6_addr
));
1437 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1439 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1447 * Set or reset the peer address socketunion structure based on the
1448 * learnt/derived peer address. If the address has changed, update the
1449 * password on the listen socket, if needed.
1451 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1453 struct interface
*ifp
;
1455 int peer_addr_updated
= 0;
1461 * Our peer structure is stored in the bgp->peerhash
1462 * release it before we modify anything.
1464 hash_release(peer
->bgp
->peerhash
, peer
);
1466 prev_family
= peer
->su
.sa
.sa_family
;
1467 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1469 /* If BGP unnumbered is not "v6only", we first see if we can
1471 * peer's IPv4 address.
1473 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1475 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1477 /* If "v6only" or we can't derive peer's IPv4 address, see if
1479 * learnt the peer's IPv6 link-local address. This is from the
1481 * IPv6 address in router advertisement.
1483 if (!peer_addr_updated
)
1485 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1487 /* If we could derive the peer address, we may need to install the
1489 * configured for the peer, if any, on the listen socket. Otherwise,
1491 * that peer's address is not available and uninstall the password, if
1494 if (peer_addr_updated
) {
1495 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1496 && prev_family
== AF_UNSPEC
)
1499 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1500 && prev_family
!= AF_UNSPEC
)
1501 bgp_md5_unset(peer
);
1502 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1503 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1507 * Since our su changed we need to del/add peer to the peerhash
1509 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1512 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1515 struct bgp_node
*rn
, *nrn
;
1516 struct bgp_table
*table
;
1518 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1519 rn
= bgp_route_next(rn
)) {
1520 table
= bgp_node_get_bgp_table_info(rn
);
1521 if (table
!= NULL
) {
1522 /* Special handling for 2-level routing
1524 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1525 || safi
== SAFI_EVPN
) {
1526 for (nrn
= bgp_table_top(table
);
1527 nrn
; nrn
= bgp_route_next(nrn
))
1528 bgp_process(bgp
, nrn
, afi
, safi
);
1530 bgp_process(bgp
, rn
, afi
, safi
);
1535 /* Force a bestpath recalculation for all prefixes. This is used
1536 * when 'bgp bestpath' commands are entered.
1538 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1543 FOREACH_AFI_SAFI (afi
, safi
) {
1544 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1549 * Create new BGP peer.
1551 * conf_if and su are mutually exclusive if configuring from the cli.
1552 * If we are handing a doppelganger, then we *must* pass in both
1553 * the original peer's su and conf_if, so that we can appropriately
1554 * track the bgp->peerhash( ie we don't want to remove the current
1555 * one from the config ).
1557 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1558 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1559 int as_type
, afi_t afi
, safi_t safi
,
1560 struct peer_group
*group
)
1564 char buf
[SU_ADDRSTRLEN
];
1566 peer
= peer_new(bgp
);
1568 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1572 bgp_peer_conf_if_to_su_update(peer
);
1573 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1574 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1577 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1578 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1579 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1581 peer
->local_as
= local_as
;
1582 peer
->as
= remote_as
;
1583 peer
->as_type
= as_type
;
1584 peer
->local_id
= bgp
->router_id
;
1585 peer
->v_holdtime
= bgp
->default_holdtime
;
1586 peer
->v_keepalive
= bgp
->default_keepalive
;
1587 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1588 ? BGP_DEFAULT_IBGP_ROUTEADV
1589 : BGP_DEFAULT_EBGP_ROUTEADV
;
1591 peer
= peer_lock(peer
); /* bgp peer list reference */
1592 peer
->group
= group
;
1593 listnode_add_sort(bgp
->peer
, peer
);
1594 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1596 /* Adjust update-group coalesce timer heuristics for # peers. */
1597 if (bgp
->heuristic_coalesce
) {
1598 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1600 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1601 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1604 active
= peer_active(peer
);
1606 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
)
1607 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1609 peer
->last_reset
= PEER_DOWN_NOAFI_ACTIVATED
;
1612 /* Last read and reset time set */
1613 peer
->readtime
= peer
->resettime
= bgp_clock();
1615 /* Default TTL set. */
1616 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: BGP_DEFAULT_TTL
;
1618 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1621 peer
->afc
[afi
][safi
] = 1;
1622 peer_af_create(peer
, afi
, safi
);
1625 /* auto shutdown if configured */
1626 if (bgp
->autoshutdown
)
1627 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1628 /* Set up peer's events and timers. */
1629 else if (!active
&& peer_active(peer
))
1630 bgp_timer_set(peer
);
1632 bgp_peer_gr_flags_update(peer
);
1633 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp
, bgp
->peer
);
1638 /* Make accept BGP peer. This function is only called from the test code */
1639 struct peer
*peer_create_accept(struct bgp
*bgp
)
1643 peer
= peer_new(bgp
);
1645 peer
= peer_lock(peer
); /* bgp peer list reference */
1646 listnode_add_sort(bgp
->peer
, peer
);
1652 * Return true if we have a peer configured to use this afi/safi
1654 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1656 struct listnode
*node
;
1659 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1660 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1663 if (peer
->afc
[afi
][safi
])
1670 /* Change peer's AS number. */
1671 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1673 bgp_peer_sort_t type
;
1676 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1677 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1678 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1679 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1680 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1682 bgp_session_reset(peer
);
1684 type
= peer_sort(peer
);
1686 peer
->as_type
= as_specified
;
1688 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1689 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1690 && peer
->bgp
->as
!= as
)
1691 peer
->local_as
= peer
->bgp
->confed_id
;
1693 peer
->local_as
= peer
->bgp
->as
;
1695 /* Advertisement-interval reset */
1696 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1697 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1698 ? BGP_DEFAULT_IBGP_ROUTEADV
1699 : BGP_DEFAULT_EBGP_ROUTEADV
;
1703 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1705 else if (type
== BGP_PEER_IBGP
)
1706 peer
->ttl
= BGP_DEFAULT_TTL
;
1708 /* reflector-client reset */
1709 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1710 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1711 PEER_FLAG_REFLECTOR_CLIENT
);
1712 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1713 PEER_FLAG_REFLECTOR_CLIENT
);
1714 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1715 PEER_FLAG_REFLECTOR_CLIENT
);
1716 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1717 PEER_FLAG_REFLECTOR_CLIENT
);
1718 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1719 PEER_FLAG_REFLECTOR_CLIENT
);
1720 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1721 PEER_FLAG_REFLECTOR_CLIENT
);
1722 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1723 PEER_FLAG_REFLECTOR_CLIENT
);
1724 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1725 PEER_FLAG_REFLECTOR_CLIENT
);
1726 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1727 PEER_FLAG_REFLECTOR_CLIENT
);
1728 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1729 PEER_FLAG_REFLECTOR_CLIENT
);
1730 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1731 PEER_FLAG_REFLECTOR_CLIENT
);
1732 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1733 PEER_FLAG_REFLECTOR_CLIENT
);
1734 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1735 PEER_FLAG_REFLECTOR_CLIENT
);
1738 /* local-as reset */
1739 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1740 peer
->change_local_as
= 0;
1741 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1742 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1743 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1747 /* If peer does not exist, create new one. If peer already exists,
1748 set AS number to the peer. */
1749 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1750 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1756 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1758 peer
= peer_lookup(bgp
, su
);
1761 /* Not allowed for a dynamic peer. */
1762 if (peer_dynamic_neighbor(peer
)) {
1764 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1767 /* When this peer is a member of peer-group. */
1769 /* peer-group already has AS number/internal/external */
1770 if (peer
->group
->conf
->as
1771 || peer
->group
->conf
->as_type
) {
1772 /* Return peer group's AS number. */
1773 *as
= peer
->group
->conf
->as
;
1774 return BGP_ERR_PEER_GROUP_MEMBER
;
1777 bgp_peer_sort_t peer_sort_type
=
1778 peer_sort(peer
->group
->conf
);
1780 /* Explicit AS numbers used, compare AS numbers */
1781 if (as_type
== AS_SPECIFIED
) {
1782 if (((peer_sort_type
== BGP_PEER_IBGP
)
1783 && (bgp
->as
!= *as
))
1784 || ((peer_sort_type
== BGP_PEER_EBGP
)
1785 && (bgp
->as
== *as
))) {
1787 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1790 /* internal/external used, compare as-types */
1791 if (((peer_sort_type
== BGP_PEER_IBGP
)
1792 && (as_type
!= AS_INTERNAL
))
1793 || ((peer_sort_type
== BGP_PEER_EBGP
)
1794 && (as_type
!= AS_EXTERNAL
))) {
1796 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1801 /* Existing peer's AS number change. */
1802 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1803 || (peer
->as_type
!= as_type
))
1804 peer_as_change(peer
, *as
, as_type
);
1807 return BGP_ERR_NO_INTERFACE_CONFIG
;
1809 /* If the peer is not part of our confederation, and its not an
1810 iBGP peer then spoof the source AS */
1811 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1812 && !bgp_confederation_peers_check(bgp
, *as
)
1814 local_as
= bgp
->confed_id
;
1818 /* If this is IPv4 unicast configuration and "no bgp default
1819 ipv4-unicast" is specified. */
1821 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1822 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1823 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1826 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1833 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1834 struct peer
*peer
, afi_t afi
,
1838 int out
= FILTER_OUT
;
1840 uint32_t pflags_ovrd
;
1841 uint8_t *pfilter_ovrd
;
1845 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1846 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1848 /* peer af_flags apply */
1849 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1850 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1851 ^ peer
->af_flags_invert
[afi
][safi
];
1852 flags_tmp
&= ~pflags_ovrd
;
1854 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1855 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1856 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1857 conf
->af_flags_invert
[afi
][safi
]);
1859 /* maximum-prefix */
1860 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1861 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1862 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1863 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1867 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1868 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1871 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1872 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1874 /* default-originate route-map */
1875 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1876 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1877 MTYPE_ROUTE_MAP_NAME
);
1878 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1881 /* inbound filter apply */
1882 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1883 PEER_STR_ATTR_INHERIT(peer
, group
,
1884 filter
[afi
][safi
].dlist
[in
].name
,
1885 MTYPE_BGP_FILTER_NAME
);
1886 PEER_ATTR_INHERIT(peer
, group
,
1887 filter
[afi
][safi
].dlist
[in
].alist
);
1890 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1891 PEER_STR_ATTR_INHERIT(peer
, group
,
1892 filter
[afi
][safi
].plist
[in
].name
,
1893 MTYPE_BGP_FILTER_NAME
);
1894 PEER_ATTR_INHERIT(peer
, group
,
1895 filter
[afi
][safi
].plist
[in
].plist
);
1898 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1899 PEER_STR_ATTR_INHERIT(peer
, group
,
1900 filter
[afi
][safi
].aslist
[in
].name
,
1901 MTYPE_BGP_FILTER_NAME
);
1902 PEER_ATTR_INHERIT(peer
, group
,
1903 filter
[afi
][safi
].aslist
[in
].aslist
);
1906 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1907 PEER_STR_ATTR_INHERIT(peer
, group
,
1908 filter
[afi
][safi
].map
[in
].name
,
1909 MTYPE_BGP_FILTER_NAME
);
1910 PEER_ATTR_INHERIT(peer
, group
,
1911 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1914 /* outbound filter apply */
1915 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1916 PEER_STR_ATTR_INHERIT(peer
, group
,
1917 filter
[afi
][safi
].dlist
[out
].name
,
1918 MTYPE_BGP_FILTER_NAME
);
1919 PEER_ATTR_INHERIT(peer
, group
,
1920 filter
[afi
][safi
].dlist
[out
].alist
);
1923 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1924 PEER_STR_ATTR_INHERIT(peer
, group
,
1925 filter
[afi
][safi
].plist
[out
].name
,
1926 MTYPE_BGP_FILTER_NAME
);
1927 PEER_ATTR_INHERIT(peer
, group
,
1928 filter
[afi
][safi
].plist
[out
].plist
);
1931 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1932 PEER_STR_ATTR_INHERIT(peer
, group
,
1933 filter
[afi
][safi
].aslist
[out
].name
,
1934 MTYPE_BGP_FILTER_NAME
);
1935 PEER_ATTR_INHERIT(peer
, group
,
1936 filter
[afi
][safi
].aslist
[out
].aslist
);
1939 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1940 PEER_STR_ATTR_INHERIT(peer
, group
,
1941 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1942 MTYPE_BGP_FILTER_NAME
);
1943 PEER_ATTR_INHERIT(peer
, group
,
1944 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1947 /* nondirectional filter apply */
1948 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1949 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1950 MTYPE_BGP_FILTER_NAME
);
1951 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1954 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1955 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1956 bgp_addpath_type_changed(conf
->bgp
);
1960 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1965 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1966 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1967 __func__
, peer
->host
);
1971 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1973 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1974 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1975 return BGP_ERR_PEER_SAFI_CONFLICT
;
1977 /* Nothing to do if we've already activated this peer */
1978 if (peer
->afc
[afi
][safi
])
1981 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1984 active
= peer_active(peer
);
1985 peer
->afc
[afi
][safi
] = 1;
1988 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1990 if (!active
&& peer_active(peer
)) {
1991 bgp_timer_set(peer
);
1993 if (peer
->status
== Established
) {
1994 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1995 peer
->afc_adv
[afi
][safi
] = 1;
1996 bgp_capability_send(peer
, afi
, safi
,
1998 CAPABILITY_ACTION_SET
);
1999 if (peer
->afc_recv
[afi
][safi
]) {
2000 peer
->afc_nego
[afi
][safi
] = 1;
2001 bgp_announce_route(peer
, afi
, safi
);
2004 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2005 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2006 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2009 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
2010 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2011 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2012 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2015 * If we are turning on a AFI/SAFI locally and we've
2016 * started bringing a peer up, we need to tell
2017 * the other peer to restart because we might loose
2018 * configuration here because when the doppelganger
2019 * gets to a established state due to how
2020 * we resolve we could just overwrite the afi/safi
2023 other
= peer
->doppelganger
;
2025 && (other
->status
== OpenSent
2026 || other
->status
== OpenConfirm
)) {
2027 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2028 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
2029 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2036 /* Activate the peer or peer group for specified AFI and SAFI. */
2037 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2040 struct peer_group
*group
;
2041 struct listnode
*node
, *nnode
;
2042 struct peer
*tmp_peer
;
2045 /* Nothing to do if we've already activated this peer */
2046 if (peer
->afc
[afi
][safi
])
2051 /* This is a peer-group so activate all of the members of the
2052 * peer-group as well */
2053 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2055 /* Do not activate a peer for both SAFI_UNICAST and
2056 * SAFI_LABELED_UNICAST */
2057 if ((safi
== SAFI_UNICAST
2058 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2059 || (safi
== SAFI_LABELED_UNICAST
2060 && peer
->afc
[afi
][SAFI_UNICAST
]))
2061 return BGP_ERR_PEER_SAFI_CONFLICT
;
2063 peer
->afc
[afi
][safi
] = 1;
2064 group
= peer
->group
;
2066 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2067 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2070 ret
|= peer_activate_af(peer
, afi
, safi
);
2073 /* If this is the first peer to be activated for this
2074 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2075 if (safi
== SAFI_LABELED_UNICAST
2076 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2078 if (BGP_DEBUG(zebra
, ZEBRA
))
2080 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2082 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2083 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2086 if (safi
== SAFI_FLOWSPEC
) {
2087 /* connect to table manager */
2088 bgp_zebra_init_tm_connect(bgp
);
2093 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2096 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2097 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2098 __func__
, peer
->host
);
2102 /* Nothing to do if we've already deactivated this peer */
2103 if (!peer
->afc
[afi
][safi
])
2106 /* De-activate the address family configuration. */
2107 peer
->afc
[afi
][safi
] = 0;
2109 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2110 flog_err(EC_BGP_PEER_DELETE
,
2111 "couldn't delete af structure for peer %s",
2116 if (peer
->status
== Established
) {
2117 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2118 peer
->afc_adv
[afi
][safi
] = 0;
2119 peer
->afc_nego
[afi
][safi
] = 0;
2121 if (peer_active_nego(peer
)) {
2122 bgp_capability_send(peer
, afi
, safi
,
2124 CAPABILITY_ACTION_UNSET
);
2125 bgp_clear_route(peer
, afi
, safi
);
2126 peer
->pcount
[afi
][safi
] = 0;
2128 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2129 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2130 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2133 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2134 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2135 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2142 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2145 struct peer_group
*group
;
2146 struct peer
*tmp_peer
;
2147 struct listnode
*node
, *nnode
;
2150 /* Nothing to do if we've already de-activated this peer */
2151 if (!peer
->afc
[afi
][safi
])
2154 /* This is a peer-group so de-activate all of the members of the
2155 * peer-group as well */
2156 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2157 peer
->afc
[afi
][safi
] = 0;
2158 group
= peer
->group
;
2160 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2161 flog_err(EC_BGP_PEER_DELETE
,
2162 "couldn't delete af structure for peer %s",
2166 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2167 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2170 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2175 /* If this is the last peer to be deactivated for this
2176 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2177 if (safi
== SAFI_LABELED_UNICAST
2178 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2179 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2181 if (BGP_DEBUG(zebra
, ZEBRA
))
2183 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2185 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2186 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2191 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2194 return peer_activate(peer
, afi
, safi
);
2196 return peer_deactivate(peer
, afi
, safi
);
2199 void peer_nsf_stop(struct peer
*peer
)
2204 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2205 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2207 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2208 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2209 peer
->nsf
[afi
][safi
] = 0;
2211 if (peer
->t_gr_restart
) {
2212 BGP_TIMER_OFF(peer
->t_gr_restart
);
2213 if (bgp_debug_neighbor_events(peer
))
2214 zlog_debug("%s graceful restart timer stopped",
2217 if (peer
->t_gr_stale
) {
2218 BGP_TIMER_OFF(peer
->t_gr_stale
);
2219 if (bgp_debug_neighbor_events(peer
))
2221 "%s graceful restart stalepath timer stopped",
2224 bgp_clear_route_all(peer
);
2227 /* Delete peer from confguration.
2229 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2230 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2232 * This function /should/ take care to be idempotent, to guard against
2233 * it being called multiple times through stray events that come in
2234 * that happen to result in this function being called again. That
2235 * said, getting here for a "Deleted" peer is a bug in the neighbour
2238 int peer_delete(struct peer
*peer
)
2244 struct bgp_filter
*filter
;
2245 struct listnode
*pn
;
2248 assert(peer
->status
!= Deleted
);
2251 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2253 bgp_keepalives_off(peer
);
2254 bgp_reads_off(peer
);
2255 bgp_writes_off(peer
);
2256 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2257 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2258 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_KEEPALIVES_ON
));
2260 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2261 peer_nsf_stop(peer
);
2263 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2265 bgp_bfd_deregister_peer(peer
);
2267 /* If this peer belongs to peer group, clear up the
2270 if (peer_dynamic_neighbor(peer
))
2271 peer_drop_dynamic_neighbor(peer
);
2273 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2275 peer
); /* group->peer list reference */
2276 list_delete_node(peer
->group
->peer
, pn
);
2281 /* Withdraw all information from routing table. We can not use
2282 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2283 * executed after peer structure is deleted.
2285 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2287 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2289 if (peer
->doppelganger
) {
2290 peer
->doppelganger
->doppelganger
= NULL
;
2291 peer
->doppelganger
= NULL
;
2294 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2295 bgp_fsm_change_status(peer
, Deleted
);
2297 /* Remove from NHT */
2298 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2299 bgp_unlink_nexthop_by_peer(peer
);
2301 /* Password configuration */
2302 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2303 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2305 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2306 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2307 bgp_md5_unset(peer
);
2310 bgp_timer_set(peer
); /* stops all timers for Deleted */
2312 /* Delete from all peer list. */
2313 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2314 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2315 peer_unlock(peer
); /* bgp peer list reference */
2316 list_delete_node(bgp
->peer
, pn
);
2317 hash_release(bgp
->peerhash
, peer
);
2322 stream_fifo_free(peer
->ibuf
);
2327 stream_fifo_free(peer
->obuf
);
2331 if (peer
->ibuf_work
) {
2332 ringbuf_del(peer
->ibuf_work
);
2333 peer
->ibuf_work
= NULL
;
2336 if (peer
->obuf_work
) {
2337 stream_free(peer
->obuf_work
);
2338 peer
->obuf_work
= NULL
;
2341 if (peer
->scratch
) {
2342 stream_free(peer
->scratch
);
2343 peer
->scratch
= NULL
;
2346 /* Local and remote addresses. */
2347 if (peer
->su_local
) {
2348 sockunion_free(peer
->su_local
);
2349 peer
->su_local
= NULL
;
2352 if (peer
->su_remote
) {
2353 sockunion_free(peer
->su_remote
);
2354 peer
->su_remote
= NULL
;
2357 /* Free filter related memory. */
2358 FOREACH_AFI_SAFI (afi
, safi
) {
2359 filter
= &peer
->filter
[afi
][safi
];
2361 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2362 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
2363 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
2364 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
2367 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2368 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
2371 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2372 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
2375 FOREACH_AFI_SAFI (afi
, safi
)
2376 peer_af_delete(peer
, afi
, safi
);
2378 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2379 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2381 peer_unlock(peer
); /* initial reference */
2386 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2388 return strcmp(g1
->name
, g2
->name
);
2391 /* Peer group cofiguration. */
2392 static struct peer_group
*peer_group_new(void)
2394 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2397 static void peer_group_free(struct peer_group
*group
)
2399 XFREE(MTYPE_PEER_GROUP
, group
);
2402 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2404 struct peer_group
*group
;
2405 struct listnode
*node
, *nnode
;
2407 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2408 if (strcmp(group
->name
, name
) == 0)
2414 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2416 struct peer_group
*group
;
2419 group
= peer_group_lookup(bgp
, name
);
2423 group
= peer_group_new();
2425 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2426 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2427 group
->peer
= list_new();
2428 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2429 group
->listen_range
[afi
] = list_new();
2430 group
->conf
= peer_new(bgp
);
2431 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2432 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2433 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2434 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2435 group
->conf
->group
= group
;
2436 group
->conf
->as
= 0;
2437 group
->conf
->ttl
= BGP_DEFAULT_TTL
;
2438 group
->conf
->gtsm_hops
= 0;
2439 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2440 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2441 listnode_add_sort(bgp
->group
, group
);
2446 static void peer_group2peer_config_copy(struct peer_group
*group
,
2456 peer
->as
= conf
->as
;
2459 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2460 peer
->change_local_as
= conf
->change_local_as
;
2462 /* If peer-group has configured TTL then override it */
2463 if (conf
->ttl
!= BGP_DEFAULT_TTL
)
2464 peer
->ttl
= conf
->ttl
;
2467 peer
->gtsm_hops
= conf
->gtsm_hops
;
2469 /* peer flags apply */
2470 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2471 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2472 flags_tmp
&= ~peer
->flags_override
;
2474 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2475 SET_FLAG(peer
->flags
, flags_tmp
);
2476 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2478 /* peer timers apply */
2479 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2480 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2481 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2484 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2485 PEER_ATTR_INHERIT(peer
, group
, connect
);
2486 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2487 peer
->v_connect
= conf
->connect
;
2489 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
2492 /* advertisement-interval apply */
2493 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2494 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2495 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2496 peer
->v_routeadv
= conf
->routeadv
;
2498 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2499 ? BGP_DEFAULT_IBGP_ROUTEADV
2500 : BGP_DEFAULT_EBGP_ROUTEADV
;
2503 /* password apply */
2504 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2505 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2506 MTYPE_PEER_PASSWORD
);
2508 if (!BGP_PEER_SU_UNSPEC(peer
))
2511 /* update-source apply */
2512 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2513 if (conf
->update_source
) {
2514 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2515 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2516 } else if (conf
->update_if
) {
2517 sockunion_free(peer
->update_source
);
2518 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2519 MTYPE_PEER_UPDATE_SOURCE
);
2523 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2526 /* Peer group's remote AS configuration. */
2527 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2530 struct peer_group
*group
;
2532 struct listnode
*node
, *nnode
;
2534 group
= peer_group_lookup(bgp
, group_name
);
2538 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2542 /* When we setup peer-group AS number all peer group member's AS
2543 number must be updated to same number. */
2544 peer_as_change(group
->conf
, *as
, as_type
);
2546 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2547 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2548 || (peer
->as_type
!= as_type
))
2549 peer_as_change(peer
, *as
, as_type
);
2555 int peer_notify_unconfig(struct peer
*peer
)
2557 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2558 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2559 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
2563 int peer_group_notify_unconfig(struct peer_group
*group
)
2565 struct peer
*peer
, *other
;
2566 struct listnode
*node
, *nnode
;
2568 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2569 other
= peer
->doppelganger
;
2570 if (other
&& other
->status
!= Deleted
) {
2571 other
->group
= NULL
;
2572 peer_notify_unconfig(other
);
2574 peer_notify_unconfig(peer
);
2579 int peer_group_delete(struct peer_group
*group
)
2583 struct prefix
*prefix
;
2585 struct listnode
*node
, *nnode
;
2590 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2591 other
= peer
->doppelganger
;
2593 if (other
&& other
->status
!= Deleted
) {
2594 other
->group
= NULL
;
2598 list_delete(&group
->peer
);
2600 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2601 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2603 prefix_free(&prefix
);
2605 list_delete(&group
->listen_range
[afi
]);
2608 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2611 bfd_info_free(&(group
->conf
->bfd_info
));
2613 group
->conf
->group
= NULL
;
2614 peer_delete(group
->conf
);
2616 /* Delete from all peer_group list. */
2617 listnode_delete(bgp
->group
, group
);
2619 peer_group_free(group
);
2624 int peer_group_remote_as_delete(struct peer_group
*group
)
2626 struct peer
*peer
, *other
;
2627 struct listnode
*node
, *nnode
;
2629 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2630 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2633 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2634 other
= peer
->doppelganger
;
2638 if (other
&& other
->status
!= Deleted
) {
2639 other
->group
= NULL
;
2643 list_delete_all_node(group
->peer
);
2645 group
->conf
->as
= 0;
2646 group
->conf
->as_type
= AS_UNSPECIFIED
;
2651 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2653 struct prefix
*prefix
;
2654 struct listnode
*node
, *nnode
;
2657 afi
= family2afi(range
->family
);
2659 /* Group needs remote AS configured. */
2660 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2661 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2663 /* Ensure no duplicates. Currently we don't care about overlaps. */
2664 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2665 if (prefix_same(range
, prefix
))
2669 prefix
= prefix_new();
2670 prefix_copy(prefix
, range
);
2671 listnode_add(group
->listen_range
[afi
], prefix
);
2673 /* Update passwords for new ranges */
2674 if (group
->conf
->password
)
2675 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2680 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2682 struct prefix
*prefix
, prefix2
;
2683 struct listnode
*node
, *nnode
;
2686 char buf
[PREFIX2STR_BUFFER
];
2688 afi
= family2afi(range
->family
);
2690 /* Identify the listen range. */
2691 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2692 if (prefix_same(range
, prefix
))
2697 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2699 prefix2str(prefix
, buf
, sizeof(buf
));
2701 /* Dispose off any dynamic neighbors that exist due to this listen range
2703 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2704 if (!peer_dynamic_neighbor(peer
))
2707 sockunion2hostprefix(&peer
->su
, &prefix2
);
2708 if (prefix_match(prefix
, &prefix2
)) {
2709 if (bgp_debug_neighbor_events(peer
))
2711 "Deleting dynamic neighbor %s group %s upon "
2712 "delete of listen range %s",
2713 peer
->host
, group
->name
, buf
);
2718 /* Get rid of the listen range */
2719 listnode_delete(group
->listen_range
[afi
], prefix
);
2721 /* Remove passwords for deleted ranges */
2722 if (group
->conf
->password
)
2723 bgp_md5_unset_prefix(prefix
);
2728 /* Bind specified peer to peer group. */
2729 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2730 struct peer_group
*group
, as_t
*as
)
2732 int first_member
= 0;
2736 /* Lookup the peer. */
2738 peer
= peer_lookup(bgp
, su
);
2740 /* The peer exist, bind it to the peer-group */
2742 /* When the peer already belongs to a peer-group, check the
2744 if (peer_group_active(peer
)) {
2746 /* The peer is already bound to the peer-group,
2749 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2752 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2755 /* The peer has not specified a remote-as, inherit it from the
2757 if (peer
->as_type
== AS_UNSPECIFIED
) {
2758 peer
->as_type
= group
->conf
->as_type
;
2759 peer
->as
= group
->conf
->as
;
2760 peer
->sort
= group
->conf
->sort
;
2763 if (!group
->conf
->as
&& peer_sort(peer
)) {
2764 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2765 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2768 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2771 if (peer_sort(group
->conf
) == 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 /* Advertisement-interval reset */
2804 if (!CHECK_FLAG(group
->conf
->flags
,
2805 PEER_FLAG_ROUTEADV
)) {
2806 group
->conf
->v_routeadv
=
2807 (peer_sort(group
->conf
)
2809 ? BGP_DEFAULT_IBGP_ROUTEADV
2810 : BGP_DEFAULT_EBGP_ROUTEADV
;
2813 /* ebgp-multihop reset */
2814 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2815 group
->conf
->ttl
= MAXTTL
;
2817 /* local-as reset */
2818 if (peer_sort(group
->conf
) != 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
->ebgp_requires_policy
= DEFAULT_EBGP_POLICY_DISABLED
;
2984 bgp
->reject_as_sets
= BGP_REJECT_AS_SETS_DISABLED
;
2985 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2990 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2991 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2993 assert(bgp
->rfapi_cfg
);
2995 #endif /* ENABLE_BGP_VNC */
2997 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2998 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2999 bgp
->vpn_policy
[afi
].afi
= afi
;
3000 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
3001 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
3004 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
3005 bgp
->vpn_policy
[afi
].import_vrf
->del
=
3006 bgp_vrf_string_name_delete
;
3007 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
3008 bgp
->vpn_policy
[afi
].export_vrf
->del
=
3009 bgp_vrf_string_name_delete
;
3012 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
3014 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3015 bgp
->restart_time
, &bgp
->t_startup
);
3017 /* printable name we can use in debug messages */
3018 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3019 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3029 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3031 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3032 snprintf(bgp
->name_pretty
, len
, "%s %s",
3033 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3039 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3040 memory_order_relaxed
);
3041 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3042 memory_order_relaxed
);
3043 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3047 update_bgp_group_init(bgp
);
3049 /* assign a unique rd id for auto derivation of vrf's RD */
3050 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3052 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3053 sizeof(struct bgp_evpn_info
));
3058 /*initilize global GR FSM */
3059 bgp_global_gr_init(bgp
);
3063 /* Return the "default VRF" instance of BGP. */
3064 struct bgp
*bgp_get_default(void)
3067 struct listnode
*node
, *nnode
;
3069 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3070 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3075 /* Lookup BGP entry. */
3076 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3079 struct listnode
*node
, *nnode
;
3081 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3083 && ((bgp
->name
== NULL
&& name
== NULL
)
3084 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3089 /* Lookup BGP structure by view name. */
3090 struct bgp
*bgp_lookup_by_name(const char *name
)
3093 struct listnode
*node
, *nnode
;
3095 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3096 if ((bgp
->name
== NULL
&& name
== NULL
)
3097 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3102 /* Lookup BGP instance based on VRF id. */
3103 /* Note: Only to be used for incoming messages from Zebra. */
3104 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3108 /* Lookup VRF (in tree) and follow link. */
3109 vrf
= vrf_lookup_by_id(vrf_id
);
3112 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3115 /* Sets the BGP instance where EVPN is enabled */
3116 void bgp_set_evpn(struct bgp
*bgp
)
3118 if (bm
->bgp_evpn
== bgp
)
3121 /* First, release the reference count we hold on the instance */
3123 bgp_unlock(bm
->bgp_evpn
);
3127 /* Increase the reference count on this new VRF */
3129 bgp_lock(bm
->bgp_evpn
);
3132 /* Returns the BGP instance where EVPN is enabled, if any */
3133 struct bgp
*bgp_get_evpn(void)
3135 return bm
->bgp_evpn
;
3138 /* handle socket creation or deletion, if necessary
3139 * this is called for all new BGP instances
3141 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3146 /* Create BGP server socket, if listen mode not disabled */
3147 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3149 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3151 * suppress vrf socket
3153 if (create
== false) {
3154 bgp_close_vrf_socket(bgp
);
3158 return BGP_ERR_INVALID_VALUE
;
3160 * if vrf_id did not change
3162 if (vrf
->vrf_id
== old_vrf_id
)
3164 if (old_vrf_id
!= VRF_UNKNOWN
) {
3165 /* look for old socket. close it. */
3166 bgp_close_vrf_socket(bgp
);
3168 /* if backend is not yet identified ( VRF_UNKNOWN) then
3169 * creation will be done later
3171 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3173 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3175 return BGP_ERR_INVALID_VALUE
;
3178 return bgp_check_main_socket(create
, bgp
);
3181 /* Called from VTY commands. */
3182 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3183 enum bgp_instance_type inst_type
)
3186 struct vrf
*vrf
= NULL
;
3188 /* Multiple instance check. */
3190 bgp
= bgp_lookup_by_name(name
);
3192 bgp
= bgp_get_default();
3194 /* Already exists. */
3196 if (bgp
->as
!= *as
) {
3198 return BGP_ERR_INSTANCE_MISMATCH
;
3200 if (bgp
->inst_type
!= inst_type
)
3201 return BGP_ERR_INSTANCE_MISMATCH
;
3206 bgp
= bgp_create(as
, name
, inst_type
);
3207 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3208 bgp
->vrf_id
= vrf_generate_id();
3209 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3210 bgp_address_init(bgp
);
3211 bgp_tip_hash_init(bgp
);
3215 bgp
->t_rmap_def_originate_eval
= NULL
;
3217 /* If Default instance or VRF, link to the VRF structure, if present. */
3218 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3219 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3220 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3222 bgp_vrf_link(bgp
, vrf
);
3224 /* BGP server socket already processed if BGP instance
3225 * already part of the list
3227 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3228 listnode_add(bm
->bgp
, bgp
);
3230 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3231 if (BGP_DEBUG(zebra
, ZEBRA
))
3232 zlog_debug("%s: Registering BGP instance %s to zebra",
3233 __PRETTY_FUNCTION__
, name
);
3234 bgp_zebra_instance_register(bgp
);
3241 * Make BGP instance "up". Applies only to VRFs (non-default) and
3242 * implies the VRF has been learnt from Zebra.
3244 void bgp_instance_up(struct bgp
*bgp
)
3247 struct listnode
*node
, *next
;
3249 /* Register with zebra. */
3250 bgp_zebra_instance_register(bgp
);
3252 /* Kick off any peers that may have been configured. */
3253 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3254 if (!BGP_PEER_START_SUPPRESSED(peer
))
3255 BGP_EVENT_ADD(peer
, BGP_Start
);
3258 /* Process any networks that have been configured. */
3259 bgp_static_add(bgp
);
3263 * Make BGP instance "down". Applies only to VRFs (non-default) and
3264 * implies the VRF has been deleted by Zebra.
3266 void bgp_instance_down(struct bgp
*bgp
)
3269 struct listnode
*node
;
3270 struct listnode
*next
;
3273 if (bgp
->t_rmap_def_originate_eval
) {
3274 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3275 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3279 /* Bring down peers, so corresponding routes are purged. */
3280 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3281 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3282 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3283 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3285 bgp_session_reset(peer
);
3288 /* Purge network and redistributed routes. */
3289 bgp_purge_static_redist_routes(bgp
);
3291 /* Cleanup registered nexthops (flags) */
3292 bgp_cleanup_nexthops(bgp
);
3295 /* Delete BGP instance. */
3296 int bgp_delete(struct bgp
*bgp
)
3299 struct peer_group
*group
;
3300 struct listnode
*node
, *next
;
3305 struct graceful_restart_info
*gr_info
;
3309 hook_call(bgp_inst_delete
, bgp
);
3311 THREAD_OFF(bgp
->t_startup
);
3312 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3313 THREAD_OFF(bgp
->t_update_delay
);
3314 THREAD_OFF(bgp
->t_establish_wait
);
3316 /* Set flag indicating bgp instance delete in progress */
3317 bgp_flag_set(bgp
, BGP_FLAG_DELETE_IN_PROGRESS
);
3319 /* Delete the graceful restart info */
3320 FOREACH_AFI_SAFI (afi
, safi
) {
3321 gr_info
= &bgp
->gr_info
[afi
][safi
];
3325 BGP_TIMER_OFF(gr_info
->t_select_deferral
);
3326 BGP_TIMER_OFF(gr_info
->t_route_select
);
3327 if (gr_info
->route_list
)
3328 list_delete(&gr_info
->route_list
);
3331 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3332 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3333 zlog_debug("Deleting Default VRF");
3335 zlog_debug("Deleting %s %s",
3336 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3342 /* unmap from RT list */
3343 bgp_evpn_vrf_delete(bgp
);
3345 /* unmap bgp vrf label */
3346 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3347 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3350 if (bgp
->t_rmap_def_originate_eval
) {
3351 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3352 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3356 /* Inform peers we're going down. */
3357 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3358 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3359 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3360 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3363 /* Delete static routes (networks). */
3364 bgp_static_delete(bgp
);
3366 /* Unset redistribution. */
3367 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3368 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3369 if (i
!= ZEBRA_ROUTE_BGP
)
3370 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3372 /* Free peers and peer-groups. */
3373 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3374 peer_group_delete(group
);
3376 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3379 if (bgp
->peer_self
) {
3380 peer_delete(bgp
->peer_self
);
3381 bgp
->peer_self
= NULL
;
3384 update_bgp_group_free(bgp
);
3386 /* TODO - Other memory may need to be freed - e.g., NHT */
3391 bgp_cleanup_routes(bgp
);
3393 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3394 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3397 &bgp
->vpn_policy
[afi
]
3398 .import_redirect_rtlist
);
3399 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3402 /* Deregister from Zebra, if needed */
3403 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3404 if (BGP_DEBUG(zebra
, ZEBRA
))
3405 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3406 __PRETTY_FUNCTION__
, bgp
->name
);
3407 bgp_zebra_instance_deregister(bgp
);
3410 /* Remove visibility via the master list - there may however still be
3411 * routes to be processed still referencing the struct bgp.
3413 listnode_delete(bm
->bgp
, bgp
);
3415 /* Free interfaces in this instance. */
3418 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3419 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3421 bgp_vrf_unlink(bgp
, vrf
);
3423 /* Update EVPN VRF pointer */
3424 if (bm
->bgp_evpn
== bgp
) {
3425 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3428 bgp_set_evpn(bgp_get_default());
3431 thread_master_free_unused(bm
->master
);
3432 bgp_unlock(bgp
); /* initial reference */
3437 void bgp_free(struct bgp
*bgp
)
3441 struct bgp_table
*table
;
3442 struct bgp_node
*rn
;
3443 struct bgp_rmap
*rmap
;
3447 list_delete(&bgp
->group
);
3448 list_delete(&bgp
->peer
);
3450 if (bgp
->peerhash
) {
3451 hash_free(bgp
->peerhash
);
3452 bgp
->peerhash
= NULL
;
3455 FOREACH_AFI_SAFI (afi
, safi
) {
3456 /* Special handling for 2-level routing tables. */
3457 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3458 || safi
== SAFI_EVPN
) {
3459 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3460 rn
= bgp_route_next(rn
)) {
3461 table
= bgp_node_get_bgp_table_info(rn
);
3462 bgp_table_finish(&table
);
3465 if (bgp
->route
[afi
][safi
])
3466 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3467 if (bgp
->aggregate
[afi
][safi
])
3468 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3469 if (bgp
->rib
[afi
][safi
])
3470 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3471 rmap
= &bgp
->table_map
[afi
][safi
];
3472 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3475 bgp_scan_finish(bgp
);
3476 bgp_address_destroy(bgp
);
3477 bgp_tip_hash_destroy(bgp
);
3479 /* release the auto RD id */
3480 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3482 bgp_evpn_cleanup(bgp
);
3483 bgp_pbr_cleanup(bgp
);
3484 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3486 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3487 vpn_policy_direction_t dir
;
3489 if (bgp
->vpn_policy
[afi
].import_vrf
)
3490 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3491 if (bgp
->vpn_policy
[afi
].export_vrf
)
3492 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3494 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3495 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3496 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3497 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3498 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3499 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3502 XFREE(MTYPE_BGP
, bgp
->name
);
3503 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3505 XFREE(MTYPE_BGP
, bgp
);
3508 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3511 struct listnode
*node
, *nnode
;
3517 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3518 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3519 && !CHECK_FLAG(peer
->sflags
,
3520 PEER_STATUS_ACCEPT_PEER
))
3522 } else if (bm
->bgp
!= NULL
) {
3523 struct listnode
*bgpnode
, *nbgpnode
;
3525 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3526 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3528 && !strcmp(peer
->conf_if
, conf_if
)
3529 && !CHECK_FLAG(peer
->sflags
,
3530 PEER_STATUS_ACCEPT_PEER
))
3536 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3539 struct listnode
*node
, *nnode
;
3545 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3546 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3547 && !CHECK_FLAG(peer
->sflags
,
3548 PEER_STATUS_ACCEPT_PEER
))
3550 } else if (bm
->bgp
!= NULL
) {
3551 struct listnode
*bgpnode
, *nbgpnode
;
3553 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3554 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3556 && !strcmp(peer
->hostname
, hostname
)
3557 && !CHECK_FLAG(peer
->sflags
,
3558 PEER_STATUS_ACCEPT_PEER
))
3564 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3566 struct peer
*peer
= NULL
;
3567 struct peer tmp_peer
;
3569 memset(&tmp_peer
, 0, sizeof(struct peer
));
3572 * We do not want to find the doppelganger peer so search for the peer
3574 * the hash that has PEER_FLAG_CONFIG_NODE
3576 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3581 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3582 } else if (bm
->bgp
!= NULL
) {
3583 struct listnode
*bgpnode
, *nbgpnode
;
3585 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3586 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3595 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3596 union sockunion
*su
,
3597 struct peer_group
*group
)
3603 /* Create peer first; we've already checked group config is valid. */
3604 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3605 group
->conf
->as_type
, 0, 0, group
);
3610 peer
= peer_lock(peer
);
3611 listnode_add(group
->peer
, peer
);
3613 peer_group2peer_config_copy(group
, peer
);
3616 * Bind peer for all AFs configured for the group. We don't call
3617 * peer_group_bind as that is sub-optimal and does some stuff we don't
3620 FOREACH_AFI_SAFI (afi
, safi
) {
3621 if (!group
->conf
->afc
[afi
][safi
])
3623 peer
->afc
[afi
][safi
] = 1;
3625 if (!peer_af_find(peer
, afi
, safi
))
3626 peer_af_create(peer
, afi
, safi
);
3628 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3631 /* Mark as dynamic, but also as a "config node" for other things to
3633 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3634 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3640 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3641 struct prefix
*prefix
)
3643 struct listnode
*node
, *nnode
;
3644 struct prefix
*range
;
3647 afi
= family2afi(prefix
->family
);
3649 if (group
->listen_range
[afi
])
3650 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3652 if (prefix_match(range
, prefix
))
3659 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3660 struct prefix
**listen_range
)
3662 struct prefix
*range
= NULL
;
3663 struct peer_group
*group
= NULL
;
3664 struct listnode
*node
, *nnode
;
3666 *listen_range
= NULL
;
3668 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3669 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3672 } else if (bm
->bgp
!= NULL
) {
3673 struct listnode
*bgpnode
, *nbgpnode
;
3675 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3676 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3677 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3683 *listen_range
= range
;
3684 return (group
&& range
) ? group
: NULL
;
3687 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3689 struct peer_group
*group
;
3692 struct prefix prefix
;
3693 struct prefix
*listen_range
;
3695 char buf
[PREFIX2STR_BUFFER
];
3696 char buf1
[PREFIX2STR_BUFFER
];
3698 sockunion2hostprefix(su
, &prefix
);
3700 /* See if incoming connection matches a configured listen range. */
3701 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3712 prefix2str(&prefix
, buf
, sizeof(buf
));
3713 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3715 if (bgp_debug_neighbor_events(NULL
))
3717 "Dynamic Neighbor %s matches group %s listen range %s",
3718 buf
, group
->name
, buf1
);
3720 /* Are we within the listen limit? */
3721 dncount
= gbgp
->dynamic_neighbors_count
;
3723 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3724 if (bgp_debug_neighbor_events(NULL
))
3725 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3726 inet_sutop(su
, buf
),
3727 gbgp
->dynamic_neighbors_limit
);
3731 /* Ensure group is not disabled. */
3732 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3733 if (bgp_debug_neighbor_events(NULL
))
3735 "Dynamic Neighbor %s rejected - group %s disabled",
3740 /* Check that at least one AF is activated for the group. */
3741 if (!peer_group_af_configured(group
)) {
3742 if (bgp_debug_neighbor_events(NULL
))
3744 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3749 /* Create dynamic peer and bind to associated group. */
3750 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3753 gbgp
->dynamic_neighbors_count
= ++dncount
;
3755 if (bgp_debug_neighbor_events(peer
))
3756 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3757 peer
->host
, group
->name
, dncount
);
3762 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3765 if (peer
->group
->bgp
) {
3766 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3768 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3770 if (bgp_debug_neighbor_events(peer
))
3771 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3772 peer
->group
->name
, dncount
);
3775 /* If peer is configured at least one address family return 1. */
3776 int peer_active(struct peer
*peer
)
3778 if (BGP_PEER_SU_UNSPEC(peer
))
3780 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3781 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3782 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3783 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3784 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3785 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3786 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3787 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3788 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3789 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3790 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3795 /* If peer is negotiated at least one address family return 1. */
3796 int peer_active_nego(struct peer
*peer
)
3798 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3799 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3800 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3801 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3802 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3803 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3804 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3805 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3806 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3807 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3808 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3809 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3810 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3815 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3816 enum peer_change_type type
)
3818 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3821 if (peer
->status
!= Established
)
3824 if (type
== peer_change_reset
) {
3825 /* If we're resetting session, we've to delete both peer struct
3827 if ((peer
->doppelganger
)
3828 && (peer
->doppelganger
->status
!= Deleted
)
3829 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3830 PEER_FLAG_CONFIG_NODE
)))
3831 peer_delete(peer
->doppelganger
);
3833 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3834 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3835 } else if (type
== peer_change_reset_in
) {
3836 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3837 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3838 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3840 if ((peer
->doppelganger
)
3841 && (peer
->doppelganger
->status
!= Deleted
)
3842 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3843 PEER_FLAG_CONFIG_NODE
)))
3844 peer_delete(peer
->doppelganger
);
3846 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3847 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3849 } else if (type
== peer_change_reset_out
) {
3850 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3851 bgp_announce_route(peer
, afi
, safi
);
3855 struct peer_flag_action
{
3859 /* This flag can be set for peer-group member. */
3860 uint8_t not_for_member
;
3862 /* Action when the flag is changed. */
3863 enum peer_change_type type
;
3866 static const struct peer_flag_action peer_flag_action_list
[] = {
3867 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3868 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3869 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3870 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3871 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3872 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3873 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3874 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3875 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3876 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3877 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3878 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3879 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3880 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3881 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3882 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3883 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3884 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3887 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3888 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3889 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3890 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3891 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3892 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3893 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3894 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3895 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3896 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3897 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3898 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3899 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3900 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3901 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3902 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3903 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3904 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3905 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3906 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3907 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3908 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3909 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3910 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3911 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3912 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3915 /* Proper action set. */
3916 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3917 int size
, struct peer_flag_action
*action
,
3924 const struct peer_flag_action
*match
= NULL
;
3926 /* Check peer's frag action. */
3927 for (i
= 0; i
< size
; i
++) {
3928 match
= &action_list
[i
];
3930 if (match
->flag
== 0)
3933 if (match
->flag
& flag
) {
3936 if (match
->type
== peer_change_reset_in
)
3938 if (match
->type
== peer_change_reset_out
)
3940 if (match
->type
== peer_change_reset
) {
3944 if (match
->not_for_member
)
3945 action
->not_for_member
= 1;
3949 /* Set peer clear type. */
3950 if (reset_in
&& reset_out
)
3951 action
->type
= peer_change_reset
;
3953 action
->type
= peer_change_reset_in
;
3955 action
->type
= peer_change_reset_out
;
3957 action
->type
= peer_change_none
;
3962 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3964 if (flag
== PEER_FLAG_SHUTDOWN
) {
3965 if (CHECK_FLAG(peer
->flags
, flag
)) {
3966 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3967 peer_nsf_stop(peer
);
3969 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3970 if (peer
->t_pmax_restart
) {
3971 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3972 if (bgp_debug_neighbor_events(peer
))
3974 "%s Maximum-prefix restart timer canceled",
3978 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3979 peer_nsf_stop(peer
);
3981 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3982 char *msg
= peer
->tx_shutdown_message
;
3985 if (!msg
&& peer_group_active(peer
))
3986 msg
= peer
->group
->conf
3987 ->tx_shutdown_message
;
3988 msglen
= msg
? strlen(msg
) : 0;
3993 uint8_t msgbuf
[129];
3996 memcpy(msgbuf
+ 1, msg
, msglen
);
3998 bgp_notify_send_with_data(
3999 peer
, BGP_NOTIFY_CEASE
,
4000 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
4001 msgbuf
, msglen
+ 1);
4004 peer
, BGP_NOTIFY_CEASE
,
4005 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
4007 bgp_session_reset(peer
);
4009 peer
->v_start
= BGP_INIT_START_TIMER
;
4010 BGP_EVENT_ADD(peer
, BGP_Stop
);
4012 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4013 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
4014 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4015 else if (flag
== PEER_FLAG_PASSIVE
)
4016 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
4017 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
4018 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
4020 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4021 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4023 bgp_session_reset(peer
);
4026 /* Change specified peer flag. */
4027 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
4031 bool invert
, member_invert
;
4032 struct peer
*member
;
4033 struct listnode
*node
, *nnode
;
4034 struct peer_flag_action action
;
4036 memset(&action
, 0, sizeof(struct peer_flag_action
));
4037 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
4039 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4040 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4043 /* Abort if no flag action exists. */
4045 return BGP_ERR_INVALID_FLAG
;
4047 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4048 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4049 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4050 return BGP_ERR_PEER_FLAG_CONFLICT
;
4052 /* Handle flag updates where desired state matches current state. */
4053 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4054 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4055 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4059 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4060 COND_FLAG(peer
->flags_override
, flag
, invert
);
4065 /* Inherit from peer-group or set/unset flags accordingly. */
4066 if (peer_group_active(peer
) && set
== invert
)
4067 peer_flag_inherit(peer
, flag
);
4069 COND_FLAG(peer
->flags
, flag
, set
);
4071 /* Check if handling a regular peer. */
4072 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4073 /* Update flag override state accordingly. */
4074 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4076 /* Execute flag action on peer. */
4077 if (action
.type
== peer_change_reset
)
4078 peer_flag_modify_action(peer
, flag
);
4080 /* Skip peer-group mechanics for regular peers. */
4084 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4085 bgp_nht_register_enhe_capability_interfaces(peer
);
4088 * Update peer-group members, unless they are explicitely overriding
4089 * peer-group configuration.
4091 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4092 /* Skip peers with overridden configuration. */
4093 if (CHECK_FLAG(member
->flags_override
, flag
))
4096 /* Check if only member without group is inverted. */
4098 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4100 /* Skip peers with equivalent configuration. */
4101 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4104 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4107 /* Update flag on peer-group member. */
4108 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4110 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4111 bgp_nht_register_enhe_capability_interfaces(member
);
4113 /* Execute flag action on peer-group member. */
4114 if (action
.type
== peer_change_reset
)
4115 peer_flag_modify_action(member
, flag
);
4121 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4123 return peer_flag_modify(peer
, flag
, 1);
4126 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4128 return peer_flag_modify(peer
, flag
, 0);
4131 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4132 uint32_t flag
, bool set
)
4136 bool invert
, member_invert
;
4137 struct peer
*member
;
4138 struct listnode
*node
, *nnode
;
4139 struct peer_flag_action action
;
4141 memset(&action
, 0, sizeof(struct peer_flag_action
));
4142 size
= sizeof peer_af_flag_action_list
4143 / sizeof(struct peer_flag_action
);
4145 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4146 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4149 /* Abort if flag action exists. */
4151 return BGP_ERR_INVALID_FLAG
;
4153 /* Special check for reflector client. */
4154 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4155 && peer_sort(peer
) != BGP_PEER_IBGP
)
4156 return BGP_ERR_NOT_INTERNAL_PEER
;
4158 /* Special check for remove-private-AS. */
4159 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4160 && peer_sort(peer
) == BGP_PEER_IBGP
)
4161 return BGP_ERR_REMOVE_PRIVATE_AS
;
4163 /* as-override is not allowed for IBGP peers */
4164 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4165 return BGP_ERR_AS_OVERRIDE
;
4167 /* Handle flag updates where desired state matches current state. */
4168 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4169 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4170 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4175 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4176 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4183 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4184 * if we are setting/unsetting flags which conflict with this flag
4185 * handle accordingly
4187 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4191 * if we are setting NEXTHOP_SELF, we need to unset the
4192 * NEXTHOP_UNCHANGED flag
4194 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4195 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4196 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4197 PEER_FLAG_NEXTHOP_UNCHANGED
);
4201 * if we are unsetting NEXTHOP_SELF, we need to set the
4202 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4204 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4205 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4206 SET_FLAG(peer
->af_flags
[afi
][safi
],
4207 PEER_FLAG_NEXTHOP_UNCHANGED
);
4211 /* Inherit from peer-group or set/unset flags accordingly. */
4212 if (peer_group_active(peer
) && set
== invert
)
4213 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4215 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4217 /* Execute action when peer is established. */
4218 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4219 && peer
->status
== Established
) {
4220 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4221 bgp_clear_adj_in(peer
, afi
, safi
);
4223 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4224 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4225 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4226 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4227 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4228 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4229 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4230 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4232 peer_change_action(peer
, afi
, safi
, action
.type
);
4236 /* Check if handling a regular peer. */
4237 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4238 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4242 * Update peer-group members, unless they are explicitely
4243 * overriding peer-group configuration.
4245 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4247 /* Skip peers with overridden configuration. */
4248 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4252 /* Check if only member without group is inverted. */
4254 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4258 /* Skip peers with equivalent configuration. */
4259 if (set
!= member_invert
4260 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4263 if (set
== member_invert
4264 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4267 /* Update flag on peer-group member. */
4268 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4269 set
!= member_invert
);
4271 /* Execute flag action on peer-group member. */
4272 if (member
->status
== Established
) {
4273 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4274 bgp_clear_adj_in(member
, afi
, safi
);
4276 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4277 member
->last_reset
=
4278 PEER_DOWN_RR_CLIENT_CHANGE
;
4280 == PEER_FLAG_RSERVER_CLIENT
)
4281 member
->last_reset
=
4282 PEER_DOWN_RS_CLIENT_CHANGE
;
4284 == PEER_FLAG_ORF_PREFIX_SM
)
4285 member
->last_reset
=
4286 PEER_DOWN_CAPABILITY_CHANGE
;
4288 == PEER_FLAG_ORF_PREFIX_RM
)
4289 member
->last_reset
=
4290 PEER_DOWN_CAPABILITY_CHANGE
;
4292 peer_change_action(member
, afi
, safi
,
4302 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4304 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4307 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4309 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4313 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4315 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4316 peer
->tx_shutdown_message
=
4317 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4321 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4323 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4328 /* EBGP multihop configuration. */
4329 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4331 struct peer_group
*group
;
4332 struct listnode
*node
, *nnode
;
4335 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4338 /* see comment in peer_ttl_security_hops_set() */
4339 if (ttl
!= MAXTTL
) {
4340 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4341 group
= peer
->group
;
4342 if (group
->conf
->gtsm_hops
!= 0)
4343 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4345 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4347 if (peer1
->sort
== BGP_PEER_IBGP
)
4350 if (peer1
->gtsm_hops
!= 0)
4351 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4354 if (peer
->gtsm_hops
!= 0)
4355 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4361 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4362 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4363 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4364 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4365 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4367 bgp_session_reset(peer
);
4370 group
= peer
->group
;
4371 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4372 if (peer
->sort
== BGP_PEER_IBGP
)
4375 peer
->ttl
= group
->conf
->ttl
;
4377 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4378 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4379 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4381 bgp_session_reset(peer
);
4387 int peer_ebgp_multihop_unset(struct peer
*peer
)
4389 struct peer_group
*group
;
4390 struct listnode
*node
, *nnode
;
4392 if (peer
->sort
== BGP_PEER_IBGP
)
4395 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4396 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4398 if (peer_group_active(peer
))
4399 peer
->ttl
= peer
->group
->conf
->ttl
;
4401 peer
->ttl
= BGP_DEFAULT_TTL
;
4403 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4404 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4405 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4406 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4408 bgp_session_reset(peer
);
4410 group
= peer
->group
;
4411 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4412 if (peer
->sort
== BGP_PEER_IBGP
)
4415 peer
->ttl
= BGP_DEFAULT_TTL
;
4417 if (peer
->fd
>= 0) {
4418 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4420 peer
, BGP_NOTIFY_CEASE
,
4421 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4423 bgp_session_reset(peer
);
4430 /* Neighbor description. */
4431 int peer_description_set(struct peer
*peer
, const char *desc
)
4433 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4435 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4440 int peer_description_unset(struct peer
*peer
)
4442 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4447 /* Neighbor update-source. */
4448 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4450 struct peer
*member
;
4451 struct listnode
*node
, *nnode
;
4453 /* Set flag and configuration on peer. */
4454 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4455 if (peer
->update_if
) {
4456 if (strcmp(peer
->update_if
, ifname
) == 0)
4458 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4460 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4461 sockunion_free(peer
->update_source
);
4462 peer
->update_source
= NULL
;
4464 /* Check if handling a regular peer. */
4465 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4466 /* Send notification or reset peer depending on state. */
4467 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4468 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4469 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4470 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4472 bgp_session_reset(peer
);
4474 /* Skip peer-group mechanics for regular peers. */
4479 * Set flag and configuration on all peer-group members, unless they are
4480 * explicitely overriding peer-group configuration.
4482 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4483 /* Skip peers with overridden configuration. */
4484 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4487 /* Skip peers with the same configuration. */
4488 if (member
->update_if
) {
4489 if (strcmp(member
->update_if
, ifname
) == 0)
4491 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4494 /* Set flag and configuration on peer-group member. */
4495 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4496 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4497 sockunion_free(member
->update_source
);
4498 member
->update_source
= NULL
;
4500 /* Send notification or reset peer depending on state. */
4501 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4502 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4503 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4504 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4506 bgp_session_reset(member
);
4512 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4514 struct peer
*member
;
4515 struct listnode
*node
, *nnode
;
4517 /* Set flag and configuration on peer. */
4518 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4519 if (peer
->update_source
) {
4520 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4522 sockunion_free(peer
->update_source
);
4524 peer
->update_source
= sockunion_dup(su
);
4525 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4527 /* Check if handling a regular peer. */
4528 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4529 /* Send notification or reset peer depending on state. */
4530 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4531 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4532 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4533 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4535 bgp_session_reset(peer
);
4537 /* Skip peer-group mechanics for regular peers. */
4542 * Set flag and configuration on all peer-group members, unless they are
4543 * explicitely overriding peer-group configuration.
4545 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4546 /* Skip peers with overridden configuration. */
4547 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4550 /* Skip peers with the same configuration. */
4551 if (member
->update_source
) {
4552 if (sockunion_cmp(member
->update_source
, su
) == 0)
4554 sockunion_free(member
->update_source
);
4557 /* Set flag and configuration on peer-group member. */
4558 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4559 member
->update_source
= sockunion_dup(su
);
4560 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4562 /* Send notification or reset peer depending on state. */
4563 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4564 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4565 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4566 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4568 bgp_session_reset(member
);
4574 int peer_update_source_unset(struct peer
*peer
)
4576 struct peer
*member
;
4577 struct listnode
*node
, *nnode
;
4579 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4582 /* Inherit configuration from peer-group if peer is member. */
4583 if (peer_group_active(peer
)) {
4584 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4585 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4586 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4587 MTYPE_PEER_UPDATE_SOURCE
);
4589 /* Otherwise remove flag and configuration from peer. */
4590 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4591 sockunion_free(peer
->update_source
);
4592 peer
->update_source
= NULL
;
4593 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4596 /* Check if handling a regular peer. */
4597 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4598 /* Send notification or reset peer depending on state. */
4599 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4600 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4601 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4602 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4604 bgp_session_reset(peer
);
4606 /* Skip peer-group mechanics for regular peers. */
4611 * Set flag and configuration on all peer-group members, unless they are
4612 * explicitely overriding peer-group configuration.
4614 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4615 /* Skip peers with overridden configuration. */
4616 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4619 /* Skip peers with the same configuration. */
4620 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4621 && !member
->update_source
&& !member
->update_if
)
4624 /* Remove flag and configuration on peer-group member. */
4625 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4626 sockunion_free(member
->update_source
);
4627 member
->update_source
= NULL
;
4628 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4630 /* Send notification or reset peer depending on state. */
4631 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4632 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4633 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4634 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4636 bgp_session_reset(member
);
4642 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4643 const char *rmap
, struct route_map
*route_map
)
4645 struct peer
*member
;
4646 struct listnode
*node
, *nnode
;
4648 /* Set flag and configuration on peer. */
4649 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4651 if (!peer
->default_rmap
[afi
][safi
].name
4652 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4653 if (peer
->default_rmap
[afi
][safi
].name
)
4654 XFREE(MTYPE_ROUTE_MAP_NAME
,
4655 peer
->default_rmap
[afi
][safi
].name
);
4657 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4658 peer
->default_rmap
[afi
][safi
].name
=
4659 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4660 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4661 route_map_counter_increment(route_map
);
4664 if (peer
->default_rmap
[afi
][safi
].name
)
4665 XFREE(MTYPE_ROUTE_MAP_NAME
,
4666 peer
->default_rmap
[afi
][safi
].name
);
4668 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4669 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4670 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4673 /* Check if handling a regular peer. */
4674 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4675 /* Update peer route announcements. */
4676 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4677 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4678 bgp_default_originate(peer
, afi
, safi
, 0);
4679 bgp_announce_route(peer
, afi
, safi
);
4682 /* Skip peer-group mechanics for regular peers. */
4687 * Set flag and configuration on all peer-group members, unless they are
4688 * explicitely overriding peer-group configuration.
4690 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4691 /* Skip peers with overridden configuration. */
4692 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4693 PEER_FLAG_DEFAULT_ORIGINATE
))
4696 /* Set flag and configuration on peer-group member. */
4697 SET_FLAG(member
->af_flags
[afi
][safi
],
4698 PEER_FLAG_DEFAULT_ORIGINATE
);
4700 if (member
->default_rmap
[afi
][safi
].name
)
4701 XFREE(MTYPE_ROUTE_MAP_NAME
,
4702 member
->default_rmap
[afi
][safi
].name
);
4703 route_map_counter_decrement(
4704 member
->default_rmap
[afi
][safi
].map
);
4705 member
->default_rmap
[afi
][safi
].name
=
4706 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4707 member
->default_rmap
[afi
][safi
].map
= route_map
;
4708 route_map_counter_increment(route_map
);
4711 /* Update peer route announcements. */
4712 if (member
->status
== Established
4713 && member
->afc_nego
[afi
][safi
]) {
4714 update_group_adjust_peer(
4715 peer_af_find(member
, afi
, safi
));
4716 bgp_default_originate(member
, afi
, safi
, 0);
4717 bgp_announce_route(member
, afi
, safi
);
4724 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4726 struct peer
*member
;
4727 struct listnode
*node
, *nnode
;
4729 /* Inherit configuration from peer-group if peer is member. */
4730 if (peer_group_active(peer
)) {
4731 peer_af_flag_inherit(peer
, afi
, safi
,
4732 PEER_FLAG_DEFAULT_ORIGINATE
);
4733 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4734 default_rmap
[afi
][safi
].name
,
4735 MTYPE_ROUTE_MAP_NAME
);
4736 PEER_ATTR_INHERIT(peer
, peer
->group
,
4737 default_rmap
[afi
][safi
].map
);
4739 /* Otherwise remove flag and configuration from peer. */
4740 peer_af_flag_unset(peer
, afi
, safi
,
4741 PEER_FLAG_DEFAULT_ORIGINATE
);
4742 if (peer
->default_rmap
[afi
][safi
].name
)
4743 XFREE(MTYPE_ROUTE_MAP_NAME
,
4744 peer
->default_rmap
[afi
][safi
].name
);
4745 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4746 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4747 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4750 /* Check if handling a regular peer. */
4751 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4752 /* Update peer route announcements. */
4753 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4754 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4755 bgp_default_originate(peer
, afi
, safi
, 1);
4756 bgp_announce_route(peer
, afi
, safi
);
4759 /* Skip peer-group mechanics for regular peers. */
4764 * Remove flag and configuration from all peer-group members, unless
4765 * they are explicitely overriding peer-group configuration.
4767 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4768 /* Skip peers with overridden configuration. */
4769 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4770 PEER_FLAG_DEFAULT_ORIGINATE
))
4773 /* Remove flag and configuration on peer-group member. */
4774 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4775 PEER_FLAG_DEFAULT_ORIGINATE
);
4776 if (peer
->default_rmap
[afi
][safi
].name
)
4777 XFREE(MTYPE_ROUTE_MAP_NAME
,
4778 peer
->default_rmap
[afi
][safi
].name
);
4779 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4780 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4781 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4783 /* Update peer route announcements. */
4784 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4785 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4786 bgp_default_originate(peer
, afi
, safi
, 1);
4787 bgp_announce_route(peer
, afi
, safi
);
4794 int peer_port_set(struct peer
*peer
, uint16_t port
)
4800 int peer_port_unset(struct peer
*peer
)
4802 peer
->port
= BGP_PORT_DEFAULT
;
4807 * Helper function that is called after the name of the policy
4808 * being used by a peer has changed (AF specific). Automatically
4809 * initiates inbound or outbound processing as needed.
4811 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4815 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4816 if (peer
->status
== Established
)
4817 bgp_announce_route(peer
, afi
, safi
);
4819 if (peer
->status
!= Established
)
4822 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4823 PEER_FLAG_SOFT_RECONFIG
))
4824 bgp_soft_reconfig_in(peer
, afi
, safi
);
4825 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4826 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4827 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4832 /* neighbor weight. */
4833 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4835 struct peer
*member
;
4836 struct listnode
*node
, *nnode
;
4838 /* Set flag and configuration on peer. */
4839 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4840 if (peer
->weight
[afi
][safi
] != weight
) {
4841 peer
->weight
[afi
][safi
] = weight
;
4842 peer_on_policy_change(peer
, afi
, safi
, 0);
4845 /* Skip peer-group mechanics for regular peers. */
4846 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4850 * Set flag and configuration on all peer-group members, unless they are
4851 * explicitely overriding peer-group configuration.
4853 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4854 /* Skip peers with overridden configuration. */
4855 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4859 /* Set flag and configuration on peer-group member. */
4860 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4861 if (member
->weight
[afi
][safi
] != weight
) {
4862 member
->weight
[afi
][safi
] = weight
;
4863 peer_on_policy_change(member
, afi
, safi
, 0);
4870 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4872 struct peer
*member
;
4873 struct listnode
*node
, *nnode
;
4875 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4878 /* Inherit configuration from peer-group if peer is member. */
4879 if (peer_group_active(peer
)) {
4880 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4881 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4883 peer_on_policy_change(peer
, afi
, safi
, 0);
4887 /* Remove flag and configuration from peer. */
4888 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4889 peer
->weight
[afi
][safi
] = 0;
4890 peer_on_policy_change(peer
, afi
, safi
, 0);
4892 /* Skip peer-group mechanics for regular peers. */
4893 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4897 * Remove flag and configuration from all peer-group members, unless
4898 * they are explicitely overriding peer-group configuration.
4900 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4901 /* Skip peers with overridden configuration. */
4902 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4906 /* Skip peers where flag is already disabled. */
4907 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4910 /* Remove flag and configuration on peer-group member. */
4911 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4912 member
->weight
[afi
][safi
] = 0;
4913 peer_on_policy_change(member
, afi
, safi
, 0);
4919 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4921 struct peer
*member
;
4922 struct listnode
*node
, *nnode
;
4924 if (keepalive
> 65535)
4925 return BGP_ERR_INVALID_VALUE
;
4927 if (holdtime
> 65535)
4928 return BGP_ERR_INVALID_VALUE
;
4930 if (holdtime
< 3 && holdtime
!= 0)
4931 return BGP_ERR_INVALID_VALUE
;
4933 /* Set flag and configuration on peer. */
4934 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4935 peer
->holdtime
= holdtime
;
4936 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4938 /* Skip peer-group mechanics for regular peers. */
4939 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4943 * Set flag and configuration on all peer-group members, unless they are
4944 * explicitely overriding peer-group configuration.
4946 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4947 /* Skip peers with overridden configuration. */
4948 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4951 /* Set flag and configuration on peer-group member. */
4952 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4953 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4954 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4960 int peer_timers_unset(struct peer
*peer
)
4962 struct peer
*member
;
4963 struct listnode
*node
, *nnode
;
4965 /* Inherit configuration from peer-group if peer is member. */
4966 if (peer_group_active(peer
)) {
4967 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4968 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4969 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4971 /* Otherwise remove flag and configuration from peer. */
4972 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4974 peer
->keepalive
= 0;
4977 /* Skip peer-group mechanics for regular peers. */
4978 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4982 * Remove flag and configuration from all peer-group members, unless
4983 * they are explicitely overriding peer-group configuration.
4985 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4986 /* Skip peers with overridden configuration. */
4987 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4990 /* Remove flag and configuration on peer-group member. */
4991 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4992 member
->holdtime
= 0;
4993 member
->keepalive
= 0;
4999 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
5001 struct peer
*member
;
5002 struct listnode
*node
, *nnode
;
5004 if (connect
> 65535)
5005 return BGP_ERR_INVALID_VALUE
;
5007 /* Set flag and configuration on peer. */
5008 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
5009 peer
->connect
= connect
;
5010 peer
->v_connect
= connect
;
5012 /* Skip peer-group mechanics for regular peers. */
5013 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5017 * Set flag and configuration on all peer-group members, unless they are
5018 * explicitely overriding peer-group configuration.
5020 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5021 /* Skip peers with overridden configuration. */
5022 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5025 /* Set flag and configuration on peer-group member. */
5026 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5027 member
->connect
= connect
;
5028 member
->v_connect
= connect
;
5034 int peer_timers_connect_unset(struct peer
*peer
)
5036 struct peer
*member
;
5037 struct listnode
*node
, *nnode
;
5039 /* Inherit configuration from peer-group if peer is member. */
5040 if (peer_group_active(peer
)) {
5041 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5042 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5044 /* Otherwise remove flag and configuration from peer. */
5045 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5049 /* Set timer with fallback to default value. */
5051 peer
->v_connect
= peer
->connect
;
5053 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
5055 /* Skip peer-group mechanics for regular peers. */
5056 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5060 * Remove flag and configuration from all peer-group members, unless
5061 * they are explicitely overriding peer-group configuration.
5063 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5064 /* Skip peers with overridden configuration. */
5065 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5068 /* Remove flag and configuration on peer-group member. */
5069 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5070 member
->connect
= 0;
5071 member
->v_connect
= peer
->bgp
->default_connect_retry
;
5077 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5079 struct peer
*member
;
5080 struct listnode
*node
, *nnode
;
5083 return BGP_ERR_INVALID_VALUE
;
5085 /* Set flag and configuration on peer. */
5086 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5087 peer
->routeadv
= routeadv
;
5088 peer
->v_routeadv
= routeadv
;
5090 /* Check if handling a regular peer. */
5091 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5092 /* Update peer route announcements. */
5093 update_group_adjust_peer_afs(peer
);
5094 if (peer
->status
== Established
)
5095 bgp_announce_route_all(peer
);
5097 /* Skip peer-group mechanics for regular peers. */
5102 * Set flag and configuration on all peer-group members, unless they are
5103 * explicitely overriding peer-group configuration.
5105 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5106 /* Skip peers with overridden configuration. */
5107 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5110 /* Set flag and configuration on peer-group member. */
5111 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5112 member
->routeadv
= routeadv
;
5113 member
->v_routeadv
= routeadv
;
5115 /* Update peer route announcements. */
5116 update_group_adjust_peer_afs(member
);
5117 if (member
->status
== Established
)
5118 bgp_announce_route_all(member
);
5124 int peer_advertise_interval_unset(struct peer
*peer
)
5126 struct peer
*member
;
5127 struct listnode
*node
, *nnode
;
5129 /* Inherit configuration from peer-group if peer is member. */
5130 if (peer_group_active(peer
)) {
5131 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5132 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5134 /* Otherwise remove flag and configuration from peer. */
5135 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5139 /* Set timer with fallback to default value. */
5141 peer
->v_routeadv
= peer
->routeadv
;
5143 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5144 ? BGP_DEFAULT_IBGP_ROUTEADV
5145 : BGP_DEFAULT_EBGP_ROUTEADV
;
5147 /* Check if handling a regular peer. */
5148 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5149 /* Update peer route announcements. */
5150 update_group_adjust_peer_afs(peer
);
5151 if (peer
->status
== Established
)
5152 bgp_announce_route_all(peer
);
5154 /* Skip peer-group mechanics for regular peers. */
5159 * Remove flag and configuration from all peer-group members, unless
5160 * they are explicitely overriding peer-group configuration.
5162 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5163 /* Skip peers with overridden configuration. */
5164 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5167 /* Remove flag and configuration on peer-group member. */
5168 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5169 member
->routeadv
= 0;
5170 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5171 ? BGP_DEFAULT_IBGP_ROUTEADV
5172 : BGP_DEFAULT_EBGP_ROUTEADV
;
5174 /* Update peer route announcements. */
5175 update_group_adjust_peer_afs(member
);
5176 if (member
->status
== Established
)
5177 bgp_announce_route_all(member
);
5183 /* neighbor interface */
5184 void peer_interface_set(struct peer
*peer
, const char *str
)
5186 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5187 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5190 void peer_interface_unset(struct peer
*peer
)
5192 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5196 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5197 int allow_num
, int origin
)
5199 struct peer
*member
;
5200 struct listnode
*node
, *nnode
;
5202 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5203 return BGP_ERR_INVALID_VALUE
;
5205 /* Set flag and configuration on peer. */
5206 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5208 if (peer
->allowas_in
[afi
][safi
] != 0
5209 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5210 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5211 peer_af_flag_set(peer
, afi
, safi
,
5212 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5213 peer
->allowas_in
[afi
][safi
] = 0;
5214 peer_on_policy_change(peer
, afi
, safi
, 0);
5217 if (peer
->allowas_in
[afi
][safi
] != allow_num
5218 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5219 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5221 peer_af_flag_unset(peer
, afi
, safi
,
5222 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5223 peer
->allowas_in
[afi
][safi
] = allow_num
;
5224 peer_on_policy_change(peer
, afi
, safi
, 0);
5228 /* Skip peer-group mechanics for regular peers. */
5229 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5233 * Set flag and configuration on all peer-group members, unless
5234 * they are explicitely overriding peer-group configuration.
5236 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5237 /* Skip peers with overridden configuration. */
5238 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5239 PEER_FLAG_ALLOWAS_IN
))
5242 /* Set flag and configuration on peer-group member. */
5243 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5245 if (member
->allowas_in
[afi
][safi
] != 0
5246 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5247 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5248 SET_FLAG(member
->af_flags
[afi
][safi
],
5249 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5250 member
->allowas_in
[afi
][safi
] = 0;
5251 peer_on_policy_change(peer
, afi
, safi
, 0);
5254 if (member
->allowas_in
[afi
][safi
] != allow_num
5255 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5256 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5257 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5258 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5259 member
->allowas_in
[afi
][safi
] = allow_num
;
5260 peer_on_policy_change(peer
, afi
, safi
, 0);
5268 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5270 struct peer
*member
;
5271 struct listnode
*node
, *nnode
;
5273 /* Skip peer if flag is already disabled. */
5274 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5277 /* Inherit configuration from peer-group if peer is member. */
5278 if (peer_group_active(peer
)) {
5279 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5280 peer_af_flag_inherit(peer
, afi
, safi
,
5281 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5282 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5283 peer_on_policy_change(peer
, afi
, safi
, 0);
5288 /* Remove flag and configuration from peer. */
5289 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5290 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5291 peer
->allowas_in
[afi
][safi
] = 0;
5292 peer_on_policy_change(peer
, afi
, safi
, 0);
5294 /* Skip peer-group mechanics if handling a regular peer. */
5295 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5299 * Remove flags and configuration from all peer-group members, unless
5300 * they are explicitely overriding peer-group configuration.
5302 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5303 /* Skip peers with overridden configuration. */
5304 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5305 PEER_FLAG_ALLOWAS_IN
))
5308 /* Skip peers where flag is already disabled. */
5309 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5310 PEER_FLAG_ALLOWAS_IN
))
5313 /* Remove flags and configuration on peer-group member. */
5314 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5315 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5316 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5317 member
->allowas_in
[afi
][safi
] = 0;
5318 peer_on_policy_change(member
, afi
, safi
, 0);
5324 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5327 bool old_no_prepend
, old_replace_as
;
5328 struct bgp
*bgp
= peer
->bgp
;
5329 struct peer
*member
;
5330 struct listnode
*node
, *nnode
;
5332 if (peer_sort(peer
) != BGP_PEER_EBGP
5333 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5334 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5337 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5340 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5342 /* Save previous flag states. */
5344 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5346 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5348 /* Set flag and configuration on peer. */
5349 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5350 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5351 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5353 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5354 && old_replace_as
== replace_as
)
5356 peer
->change_local_as
= as
;
5358 /* Check if handling a regular peer. */
5359 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5360 /* Send notification or reset peer depending on state. */
5361 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5362 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5363 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5364 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5366 bgp_session_reset(peer
);
5368 /* Skip peer-group mechanics for regular peers. */
5373 * Set flag and configuration on all peer-group members, unless they are
5374 * explicitely overriding peer-group configuration.
5376 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5377 /* Skip peers with overridden configuration. */
5378 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5381 /* Skip peers with the same configuration. */
5382 old_no_prepend
= CHECK_FLAG(member
->flags
,
5383 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5384 old_replace_as
= CHECK_FLAG(member
->flags
,
5385 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5386 if (member
->change_local_as
== as
5387 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5388 && old_no_prepend
== no_prepend
5389 && old_replace_as
== replace_as
)
5392 /* Set flag and configuration on peer-group member. */
5393 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5394 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5396 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5398 member
->change_local_as
= as
;
5400 /* Send notification or stop peer depending on state. */
5401 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5402 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5403 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5404 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5406 BGP_EVENT_ADD(member
, BGP_Stop
);
5412 int peer_local_as_unset(struct peer
*peer
)
5414 struct peer
*member
;
5415 struct listnode
*node
, *nnode
;
5417 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5420 /* Inherit configuration from peer-group if peer is member. */
5421 if (peer_group_active(peer
)) {
5422 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5423 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5424 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5425 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5427 /* Otherwise remove flag and configuration from peer. */
5428 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5429 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5430 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5431 peer
->change_local_as
= 0;
5434 /* Check if handling a regular peer. */
5435 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5436 /* Send notification or stop peer depending on state. */
5437 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5438 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5439 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5440 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5442 BGP_EVENT_ADD(peer
, BGP_Stop
);
5444 /* Skip peer-group mechanics for regular peers. */
5449 * Remove flag and configuration from all peer-group members, unless
5450 * they are explicitely overriding peer-group configuration.
5452 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5453 /* Skip peers with overridden configuration. */
5454 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5457 /* Remove flag and configuration on peer-group member. */
5458 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5459 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5460 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5461 member
->change_local_as
= 0;
5463 /* Send notification or stop peer depending on state. */
5464 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5465 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5466 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5467 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5469 bgp_session_reset(member
);
5475 /* Set password for authenticating with the peer. */
5476 int peer_password_set(struct peer
*peer
, const char *password
)
5478 struct peer
*member
;
5479 struct listnode
*node
, *nnode
;
5480 int len
= password
? strlen(password
) : 0;
5481 int ret
= BGP_SUCCESS
;
5483 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5484 return BGP_ERR_INVALID_VALUE
;
5486 /* Set flag and configuration on peer. */
5487 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5488 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5490 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5491 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5493 /* Check if handling a regular peer. */
5494 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5495 /* Send notification or reset peer depending on state. */
5496 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5497 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5498 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5500 bgp_session_reset(peer
);
5503 * Attempt to install password on socket and skip peer-group
5506 if (BGP_PEER_SU_UNSPEC(peer
))
5508 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5509 : BGP_ERR_TCPSIG_FAILED
;
5513 * Set flag and configuration on all peer-group members, unless they are
5514 * explicitely overriding peer-group configuration.
5516 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5517 /* Skip peers with overridden configuration. */
5518 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5521 /* Skip peers with the same password. */
5522 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5525 /* Set flag and configuration on peer-group member. */
5526 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5527 if (member
->password
)
5528 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5529 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5531 /* Send notification or reset peer depending on state. */
5532 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5533 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5534 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5536 bgp_session_reset(member
);
5538 /* Attempt to install password on socket. */
5539 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5540 ret
= BGP_ERR_TCPSIG_FAILED
;
5543 /* Set flag and configuration on all peer-group listen ranges */
5544 struct listnode
*ln
;
5547 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5548 bgp_md5_set_prefix(lr
, password
);
5549 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5550 bgp_md5_set_prefix(lr
, password
);
5555 int peer_password_unset(struct peer
*peer
)
5557 struct peer
*member
;
5558 struct listnode
*node
, *nnode
;
5560 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5563 /* Inherit configuration from peer-group if peer is member. */
5564 if (peer_group_active(peer
)) {
5565 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5566 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5567 MTYPE_PEER_PASSWORD
);
5569 /* Otherwise remove flag and configuration from peer. */
5570 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5571 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5574 /* Check if handling a regular peer. */
5575 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5576 /* Send notification or reset peer depending on state. */
5577 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5578 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5579 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5581 bgp_session_reset(peer
);
5583 /* Attempt to uninstall password on socket. */
5584 if (!BGP_PEER_SU_UNSPEC(peer
))
5585 bgp_md5_unset(peer
);
5587 /* Skip peer-group mechanics for regular peers. */
5592 * Remove flag and configuration from all peer-group members, unless
5593 * they are explicitely overriding peer-group configuration.
5595 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5596 /* Skip peers with overridden configuration. */
5597 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5600 /* Remove flag and configuration on peer-group member. */
5601 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5602 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5604 /* Send notification or reset peer depending on state. */
5605 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5606 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5607 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5609 bgp_session_reset(member
);
5611 /* Attempt to uninstall password on socket. */
5612 if (!BGP_PEER_SU_UNSPEC(member
))
5613 bgp_md5_unset(member
);
5616 /* Set flag and configuration on all peer-group listen ranges */
5617 struct listnode
*ln
;
5620 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5621 bgp_md5_unset_prefix(lr
);
5622 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5623 bgp_md5_unset_prefix(lr
);
5629 /* Set distribute list to the peer. */
5630 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5633 struct peer
*member
;
5634 struct bgp_filter
*filter
;
5635 struct listnode
*node
, *nnode
;
5637 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5638 return BGP_ERR_INVALID_VALUE
;
5640 /* Set configuration on peer. */
5641 filter
= &peer
->filter
[afi
][safi
];
5642 if (filter
->plist
[direct
].name
)
5643 return BGP_ERR_PEER_FILTER_CONFLICT
;
5644 if (filter
->dlist
[direct
].name
)
5645 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5646 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5647 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5649 /* Check if handling a regular peer. */
5650 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5651 /* Set override-flag and process peer route updates. */
5652 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5653 PEER_FT_DISTRIBUTE_LIST
);
5654 peer_on_policy_change(peer
, afi
, safi
,
5655 (direct
== FILTER_OUT
) ? 1 : 0);
5657 /* Skip peer-group mechanics for regular peers. */
5662 * Set configuration on all peer-group members, un less they are
5663 * explicitely overriding peer-group configuration.
5665 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5666 /* Skip peers with overridden configuration. */
5667 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5668 PEER_FT_DISTRIBUTE_LIST
))
5671 /* Set configuration on peer-group member. */
5672 filter
= &member
->filter
[afi
][safi
];
5673 if (filter
->dlist
[direct
].name
)
5674 XFREE(MTYPE_BGP_FILTER_NAME
,
5675 filter
->dlist
[direct
].name
);
5676 filter
->dlist
[direct
].name
=
5677 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5678 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5680 /* Process peer route updates. */
5681 peer_on_policy_change(member
, afi
, safi
,
5682 (direct
== FILTER_OUT
) ? 1 : 0);
5688 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5690 struct peer
*member
;
5691 struct bgp_filter
*filter
;
5692 struct listnode
*node
, *nnode
;
5694 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5695 return BGP_ERR_INVALID_VALUE
;
5697 /* Unset override-flag unconditionally. */
5698 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5699 PEER_FT_DISTRIBUTE_LIST
);
5701 /* Inherit configuration from peer-group if peer is member. */
5702 if (peer_group_active(peer
)) {
5703 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5704 filter
[afi
][safi
].dlist
[direct
].name
,
5705 MTYPE_BGP_FILTER_NAME
);
5706 PEER_ATTR_INHERIT(peer
, peer
->group
,
5707 filter
[afi
][safi
].dlist
[direct
].alist
);
5709 /* Otherwise remove configuration from peer. */
5710 filter
= &peer
->filter
[afi
][safi
];
5711 if (filter
->dlist
[direct
].name
)
5712 XFREE(MTYPE_BGP_FILTER_NAME
,
5713 filter
->dlist
[direct
].name
);
5714 filter
->dlist
[direct
].name
= NULL
;
5715 filter
->dlist
[direct
].alist
= NULL
;
5718 /* Check if handling a regular peer. */
5719 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5720 /* Process peer route updates. */
5721 peer_on_policy_change(peer
, afi
, safi
,
5722 (direct
== FILTER_OUT
) ? 1 : 0);
5724 /* Skip peer-group mechanics for regular peers. */
5729 * Remove configuration on all peer-group members, unless they are
5730 * explicitely overriding peer-group configuration.
5732 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5733 /* Skip peers with overridden configuration. */
5734 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5735 PEER_FT_DISTRIBUTE_LIST
))
5738 /* Remove configuration on peer-group member. */
5739 filter
= &member
->filter
[afi
][safi
];
5740 if (filter
->dlist
[direct
].name
)
5741 XFREE(MTYPE_BGP_FILTER_NAME
,
5742 filter
->dlist
[direct
].name
);
5743 filter
->dlist
[direct
].name
= NULL
;
5744 filter
->dlist
[direct
].alist
= NULL
;
5746 /* Process peer route updates. */
5747 peer_on_policy_change(member
, afi
, safi
,
5748 (direct
== FILTER_OUT
) ? 1 : 0);
5754 /* Update distribute list. */
5755 static void peer_distribute_update(struct access_list
*access
)
5760 struct listnode
*mnode
, *mnnode
;
5761 struct listnode
*node
, *nnode
;
5764 struct peer_group
*group
;
5765 struct bgp_filter
*filter
;
5767 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5769 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5770 access
->name
, 0, 0);
5771 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5772 FOREACH_AFI_SAFI (afi
, safi
) {
5773 filter
= &peer
->filter
[afi
][safi
];
5775 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5777 if (filter
->dlist
[direct
].name
)
5778 filter
->dlist
[direct
]
5779 .alist
= access_list_lookup(
5781 filter
->dlist
[direct
]
5784 filter
->dlist
[direct
].alist
=
5789 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5790 FOREACH_AFI_SAFI (afi
, safi
) {
5791 filter
= &group
->conf
->filter
[afi
][safi
];
5793 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5795 if (filter
->dlist
[direct
].name
)
5796 filter
->dlist
[direct
]
5797 .alist
= access_list_lookup(
5799 filter
->dlist
[direct
]
5802 filter
->dlist
[direct
].alist
=
5808 vnc_prefix_list_update(bgp
);
5813 /* Set prefix list to the peer. */
5814 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5817 struct peer
*member
;
5818 struct bgp_filter
*filter
;
5819 struct listnode
*node
, *nnode
;
5821 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5822 return BGP_ERR_INVALID_VALUE
;
5824 /* Set configuration on peer. */
5825 filter
= &peer
->filter
[afi
][safi
];
5826 if (filter
->dlist
[direct
].name
)
5827 return BGP_ERR_PEER_FILTER_CONFLICT
;
5828 if (filter
->plist
[direct
].name
)
5829 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5830 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5831 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5833 /* Check if handling a regular peer. */
5834 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5835 /* Set override-flag and process peer route updates. */
5836 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5837 PEER_FT_PREFIX_LIST
);
5838 peer_on_policy_change(peer
, afi
, safi
,
5839 (direct
== FILTER_OUT
) ? 1 : 0);
5841 /* Skip peer-group mechanics for regular peers. */
5846 * Set configuration on all peer-group members, unless they are
5847 * explicitely overriding peer-group configuration.
5849 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5850 /* Skip peers with overridden configuration. */
5851 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5852 PEER_FT_PREFIX_LIST
))
5855 /* Set configuration on peer-group member. */
5856 filter
= &member
->filter
[afi
][safi
];
5857 if (filter
->plist
[direct
].name
)
5858 XFREE(MTYPE_BGP_FILTER_NAME
,
5859 filter
->plist
[direct
].name
);
5860 filter
->plist
[direct
].name
=
5861 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5862 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5864 /* Process peer route updates. */
5865 peer_on_policy_change(member
, afi
, safi
,
5866 (direct
== FILTER_OUT
) ? 1 : 0);
5872 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5875 struct peer
*member
;
5876 struct bgp_filter
*filter
;
5877 struct listnode
*node
, *nnode
;
5879 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5880 return BGP_ERR_INVALID_VALUE
;
5882 /* Unset override-flag unconditionally. */
5883 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5884 PEER_FT_PREFIX_LIST
);
5886 /* Inherit configuration from peer-group if peer is member. */
5887 if (peer_group_active(peer
)) {
5888 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5889 filter
[afi
][safi
].plist
[direct
].name
,
5890 MTYPE_BGP_FILTER_NAME
);
5891 PEER_ATTR_INHERIT(peer
, peer
->group
,
5892 filter
[afi
][safi
].plist
[direct
].plist
);
5894 /* Otherwise remove configuration from peer. */
5895 filter
= &peer
->filter
[afi
][safi
];
5896 if (filter
->plist
[direct
].name
)
5897 XFREE(MTYPE_BGP_FILTER_NAME
,
5898 filter
->plist
[direct
].name
);
5899 filter
->plist
[direct
].name
= NULL
;
5900 filter
->plist
[direct
].plist
= NULL
;
5903 /* Check if handling a regular peer. */
5904 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5905 /* Process peer route updates. */
5906 peer_on_policy_change(peer
, afi
, safi
,
5907 (direct
== FILTER_OUT
) ? 1 : 0);
5909 /* Skip peer-group mechanics for regular peers. */
5914 * Remove configuration on all peer-group members, unless they are
5915 * explicitely overriding peer-group configuration.
5917 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5918 /* Skip peers with overridden configuration. */
5919 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5920 PEER_FT_PREFIX_LIST
))
5923 /* Remove configuration on peer-group member. */
5924 filter
= &member
->filter
[afi
][safi
];
5925 if (filter
->plist
[direct
].name
)
5926 XFREE(MTYPE_BGP_FILTER_NAME
,
5927 filter
->plist
[direct
].name
);
5928 filter
->plist
[direct
].name
= NULL
;
5929 filter
->plist
[direct
].plist
= NULL
;
5931 /* Process peer route updates. */
5932 peer_on_policy_change(member
, afi
, safi
,
5933 (direct
== FILTER_OUT
) ? 1 : 0);
5939 /* Update prefix-list list. */
5940 static void peer_prefix_list_update(struct prefix_list
*plist
)
5942 struct listnode
*mnode
, *mnnode
;
5943 struct listnode
*node
, *nnode
;
5946 struct peer_group
*group
;
5947 struct bgp_filter
*filter
;
5952 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5955 * Update the prefix-list on update groups.
5957 update_group_policy_update(
5958 bgp
, BGP_POLICY_PREFIX_LIST
,
5959 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5961 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5962 FOREACH_AFI_SAFI (afi
, safi
) {
5963 filter
= &peer
->filter
[afi
][safi
];
5965 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5967 if (filter
->plist
[direct
].name
)
5968 filter
->plist
[direct
]
5969 .plist
= prefix_list_lookup(
5971 filter
->plist
[direct
]
5974 filter
->plist
[direct
].plist
=
5979 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5980 FOREACH_AFI_SAFI (afi
, safi
) {
5981 filter
= &group
->conf
->filter
[afi
][safi
];
5983 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5985 if (filter
->plist
[direct
].name
)
5986 filter
->plist
[direct
]
5987 .plist
= prefix_list_lookup(
5989 filter
->plist
[direct
]
5992 filter
->plist
[direct
].plist
=
6000 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6003 struct peer
*member
;
6004 struct bgp_filter
*filter
;
6005 struct listnode
*node
, *nnode
;
6007 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6008 return BGP_ERR_INVALID_VALUE
;
6010 /* Set configuration on peer. */
6011 filter
= &peer
->filter
[afi
][safi
];
6012 if (filter
->aslist
[direct
].name
)
6013 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
6014 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6015 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6017 /* Check if handling a regular peer. */
6018 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6019 /* Set override-flag and process peer route updates. */
6020 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6021 PEER_FT_FILTER_LIST
);
6022 peer_on_policy_change(peer
, afi
, safi
,
6023 (direct
== FILTER_OUT
) ? 1 : 0);
6025 /* Skip peer-group mechanics for regular peers. */
6030 * Set configuration on all peer-group members, unless they are
6031 * explicitely overriding peer-group configuration.
6033 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6034 /* Skip peers with overridden configuration. */
6035 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6036 PEER_FT_FILTER_LIST
))
6039 /* Set configuration on peer-group member. */
6040 filter
= &member
->filter
[afi
][safi
];
6041 if (filter
->aslist
[direct
].name
)
6042 XFREE(MTYPE_BGP_FILTER_NAME
,
6043 filter
->aslist
[direct
].name
);
6044 filter
->aslist
[direct
].name
=
6045 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6046 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6048 /* Process peer route updates. */
6049 peer_on_policy_change(member
, afi
, safi
,
6050 (direct
== FILTER_OUT
) ? 1 : 0);
6056 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6058 struct peer
*member
;
6059 struct bgp_filter
*filter
;
6060 struct listnode
*node
, *nnode
;
6062 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6063 return BGP_ERR_INVALID_VALUE
;
6065 /* Unset override-flag unconditionally. */
6066 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6067 PEER_FT_FILTER_LIST
);
6069 /* Inherit configuration from peer-group if peer is member. */
6070 if (peer_group_active(peer
)) {
6071 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6072 filter
[afi
][safi
].aslist
[direct
].name
,
6073 MTYPE_BGP_FILTER_NAME
);
6074 PEER_ATTR_INHERIT(peer
, peer
->group
,
6075 filter
[afi
][safi
].aslist
[direct
].aslist
);
6077 /* Otherwise remove configuration from peer. */
6078 filter
= &peer
->filter
[afi
][safi
];
6079 if (filter
->aslist
[direct
].name
)
6080 XFREE(MTYPE_BGP_FILTER_NAME
,
6081 filter
->aslist
[direct
].name
);
6082 filter
->aslist
[direct
].name
= NULL
;
6083 filter
->aslist
[direct
].aslist
= NULL
;
6086 /* Check if handling a regular peer. */
6087 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6088 /* Process peer route updates. */
6089 peer_on_policy_change(peer
, afi
, safi
,
6090 (direct
== FILTER_OUT
) ? 1 : 0);
6092 /* Skip peer-group mechanics for regular peers. */
6097 * Remove configuration on all peer-group members, unless they are
6098 * explicitely overriding peer-group configuration.
6100 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6101 /* Skip peers with overridden configuration. */
6102 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6103 PEER_FT_FILTER_LIST
))
6106 /* Remove configuration on peer-group member. */
6107 filter
= &member
->filter
[afi
][safi
];
6108 if (filter
->aslist
[direct
].name
)
6109 XFREE(MTYPE_BGP_FILTER_NAME
,
6110 filter
->aslist
[direct
].name
);
6111 filter
->aslist
[direct
].name
= NULL
;
6112 filter
->aslist
[direct
].aslist
= NULL
;
6114 /* Process peer route updates. */
6115 peer_on_policy_change(member
, afi
, safi
,
6116 (direct
== FILTER_OUT
) ? 1 : 0);
6122 static void peer_aslist_update(const char *aslist_name
)
6127 struct listnode
*mnode
, *mnnode
;
6128 struct listnode
*node
, *nnode
;
6131 struct peer_group
*group
;
6132 struct bgp_filter
*filter
;
6134 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6135 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6138 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6139 FOREACH_AFI_SAFI (afi
, safi
) {
6140 filter
= &peer
->filter
[afi
][safi
];
6142 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6144 if (filter
->aslist
[direct
].name
)
6145 filter
->aslist
[direct
]
6146 .aslist
= as_list_lookup(
6147 filter
->aslist
[direct
]
6150 filter
->aslist
[direct
].aslist
=
6155 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6156 FOREACH_AFI_SAFI (afi
, safi
) {
6157 filter
= &group
->conf
->filter
[afi
][safi
];
6159 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6161 if (filter
->aslist
[direct
].name
)
6162 filter
->aslist
[direct
]
6163 .aslist
= as_list_lookup(
6164 filter
->aslist
[direct
]
6167 filter
->aslist
[direct
].aslist
=
6175 static void peer_aslist_add(char *aslist_name
)
6177 peer_aslist_update(aslist_name
);
6178 route_map_notify_dependencies((char *)aslist_name
,
6179 RMAP_EVENT_ASLIST_ADDED
);
6182 static void peer_aslist_del(const char *aslist_name
)
6184 peer_aslist_update(aslist_name
);
6185 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6189 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6190 const char *name
, struct route_map
*route_map
)
6192 struct peer
*member
;
6193 struct bgp_filter
*filter
;
6194 struct listnode
*node
, *nnode
;
6196 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6197 return BGP_ERR_INVALID_VALUE
;
6199 /* Set configuration on peer. */
6200 filter
= &peer
->filter
[afi
][safi
];
6201 if (filter
->map
[direct
].name
) {
6202 /* If the neighbor is configured with the same route-map
6203 * again then, ignore the duplicate configuration.
6205 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6208 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6210 route_map_counter_decrement(filter
->map
[direct
].map
);
6211 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6212 filter
->map
[direct
].map
= route_map
;
6213 route_map_counter_increment(route_map
);
6215 /* Check if handling a regular peer. */
6216 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6217 /* Set override-flag and process peer route updates. */
6218 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6220 peer_on_policy_change(peer
, afi
, safi
,
6221 (direct
== RMAP_OUT
) ? 1 : 0);
6223 /* Skip peer-group mechanics for regular peers. */
6228 * Set configuration on all peer-group members, unless they are
6229 * explicitely overriding peer-group configuration.
6231 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6232 /* Skip peers with overridden configuration. */
6233 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6237 /* Set configuration on peer-group member. */
6238 filter
= &member
->filter
[afi
][safi
];
6239 if (filter
->map
[direct
].name
)
6240 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6241 route_map_counter_decrement(filter
->map
[direct
].map
);
6242 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6243 filter
->map
[direct
].map
= route_map
;
6244 route_map_counter_increment(route_map
);
6246 /* Process peer route updates. */
6247 peer_on_policy_change(member
, afi
, safi
,
6248 (direct
== RMAP_OUT
) ? 1 : 0);
6253 /* Unset route-map from the peer. */
6254 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6256 struct peer
*member
;
6257 struct bgp_filter
*filter
;
6258 struct listnode
*node
, *nnode
;
6260 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6261 return BGP_ERR_INVALID_VALUE
;
6263 /* Unset override-flag unconditionally. */
6264 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6266 /* Inherit configuration from peer-group if peer is member. */
6267 if (peer_group_active(peer
)) {
6268 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6269 filter
[afi
][safi
].map
[direct
].name
,
6270 MTYPE_BGP_FILTER_NAME
);
6271 PEER_ATTR_INHERIT(peer
, peer
->group
,
6272 filter
[afi
][safi
].map
[direct
].map
);
6274 /* Otherwise remove configuration from peer. */
6275 filter
= &peer
->filter
[afi
][safi
];
6276 if (filter
->map
[direct
].name
)
6277 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6278 route_map_counter_decrement(filter
->map
[direct
].map
);
6279 filter
->map
[direct
].name
= NULL
;
6280 filter
->map
[direct
].map
= NULL
;
6283 /* Check if handling a regular peer. */
6284 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6285 /* Process peer route updates. */
6286 peer_on_policy_change(peer
, afi
, safi
,
6287 (direct
== RMAP_OUT
) ? 1 : 0);
6289 /* Skip peer-group mechanics for regular peers. */
6294 * Remove configuration on all peer-group members, unless they are
6295 * explicitely overriding peer-group configuration.
6297 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6298 /* Skip peers with overridden configuration. */
6299 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6303 /* Remove configuration on peer-group member. */
6304 filter
= &member
->filter
[afi
][safi
];
6305 if (filter
->map
[direct
].name
)
6306 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6307 route_map_counter_decrement(filter
->map
[direct
].map
);
6308 filter
->map
[direct
].name
= NULL
;
6309 filter
->map
[direct
].map
= NULL
;
6311 /* Process peer route updates. */
6312 peer_on_policy_change(member
, afi
, safi
,
6313 (direct
== RMAP_OUT
) ? 1 : 0);
6319 /* Set unsuppress-map to the peer. */
6320 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6321 const char *name
, struct route_map
*route_map
)
6323 struct peer
*member
;
6324 struct bgp_filter
*filter
;
6325 struct listnode
*node
, *nnode
;
6327 /* Set configuration on peer. */
6328 filter
= &peer
->filter
[afi
][safi
];
6329 if (filter
->usmap
.name
)
6330 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6331 route_map_counter_decrement(filter
->usmap
.map
);
6332 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6333 filter
->usmap
.map
= route_map
;
6334 route_map_counter_increment(route_map
);
6336 /* Check if handling a regular peer. */
6337 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6338 /* Set override-flag and process peer route updates. */
6339 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6340 PEER_FT_UNSUPPRESS_MAP
);
6341 peer_on_policy_change(peer
, afi
, safi
, 1);
6343 /* Skip peer-group mechanics for regular peers. */
6348 * Set configuration on all peer-group members, unless they are
6349 * explicitely overriding peer-group configuration.
6351 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6352 /* Skip peers with overridden configuration. */
6353 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6354 PEER_FT_UNSUPPRESS_MAP
))
6357 /* Set configuration on peer-group member. */
6358 filter
= &member
->filter
[afi
][safi
];
6359 if (filter
->usmap
.name
)
6360 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6361 route_map_counter_decrement(filter
->usmap
.map
);
6362 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6363 filter
->usmap
.map
= route_map
;
6364 route_map_counter_increment(route_map
);
6366 /* Process peer route updates. */
6367 peer_on_policy_change(member
, afi
, safi
, 1);
6373 /* Unset route-map from the peer. */
6374 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6376 struct peer
*member
;
6377 struct bgp_filter
*filter
;
6378 struct listnode
*node
, *nnode
;
6380 /* Unset override-flag unconditionally. */
6381 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6383 /* Inherit configuration from peer-group if peer is member. */
6384 if (peer_group_active(peer
)) {
6385 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6386 filter
[afi
][safi
].usmap
.name
,
6387 MTYPE_BGP_FILTER_NAME
);
6388 PEER_ATTR_INHERIT(peer
, peer
->group
,
6389 filter
[afi
][safi
].usmap
.map
);
6391 /* Otherwise remove configuration from peer. */
6392 filter
= &peer
->filter
[afi
][safi
];
6393 if (filter
->usmap
.name
)
6394 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6395 route_map_counter_decrement(filter
->usmap
.map
);
6396 filter
->usmap
.name
= NULL
;
6397 filter
->usmap
.map
= NULL
;
6400 /* Check if handling a regular peer. */
6401 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6402 /* Process peer route updates. */
6403 peer_on_policy_change(peer
, afi
, safi
, 1);
6405 /* Skip peer-group mechanics for regular peers. */
6410 * Remove configuration on all peer-group members, unless they are
6411 * explicitely overriding peer-group configuration.
6413 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6414 /* Skip peers with overridden configuration. */
6415 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6416 PEER_FT_UNSUPPRESS_MAP
))
6419 /* Remove configuration on peer-group member. */
6420 filter
= &member
->filter
[afi
][safi
];
6421 if (filter
->usmap
.name
)
6422 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6423 route_map_counter_decrement(filter
->usmap
.map
);
6424 filter
->usmap
.name
= NULL
;
6425 filter
->usmap
.map
= NULL
;
6427 /* Process peer route updates. */
6428 peer_on_policy_change(member
, afi
, safi
, 1);
6434 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6435 uint32_t max
, uint8_t threshold
, int warning
,
6438 struct peer
*member
;
6439 struct listnode
*node
, *nnode
;
6441 /* Set flags and configuration on peer. */
6442 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6444 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6446 peer_af_flag_unset(peer
, afi
, safi
,
6447 PEER_FLAG_MAX_PREFIX_WARNING
);
6449 peer
->pmax
[afi
][safi
] = max
;
6450 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6451 peer
->pmax_restart
[afi
][safi
] = restart
;
6453 /* Check if handling a regular peer. */
6454 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6455 /* Re-check if peer violates maximum-prefix. */
6456 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6457 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6459 /* Skip peer-group mechanics for regular peers. */
6464 * Set flags and configuration on all peer-group members, unless they
6465 * are explicitely overriding peer-group configuration.
6467 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6468 /* Skip peers with overridden configuration. */
6469 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6470 PEER_FLAG_MAX_PREFIX
))
6473 /* Set flag and configuration on peer-group member. */
6474 member
->pmax
[afi
][safi
] = max
;
6475 member
->pmax_threshold
[afi
][safi
] = threshold
;
6476 member
->pmax_restart
[afi
][safi
] = restart
;
6478 SET_FLAG(member
->af_flags
[afi
][safi
],
6479 PEER_FLAG_MAX_PREFIX_WARNING
);
6481 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6482 PEER_FLAG_MAX_PREFIX_WARNING
);
6484 /* Re-check if peer violates maximum-prefix. */
6485 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6486 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6492 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6494 /* Inherit configuration from peer-group if peer is member. */
6495 if (peer_group_active(peer
)) {
6496 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6497 peer_af_flag_inherit(peer
, afi
, safi
,
6498 PEER_FLAG_MAX_PREFIX_WARNING
);
6499 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6500 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6501 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6506 /* Remove flags and configuration from peer. */
6507 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6508 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6509 peer
->pmax
[afi
][safi
] = 0;
6510 peer
->pmax_threshold
[afi
][safi
] = 0;
6511 peer
->pmax_restart
[afi
][safi
] = 0;
6514 * Remove flags and configuration from all peer-group members, unless
6515 * they are explicitely overriding peer-group configuration.
6517 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6518 struct peer
*member
;
6519 struct listnode
*node
;
6521 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6522 /* Skip peers with overridden configuration. */
6523 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6524 PEER_FLAG_MAX_PREFIX
))
6527 /* Remove flag and configuration on peer-group member.
6529 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6530 PEER_FLAG_MAX_PREFIX
);
6531 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6532 PEER_FLAG_MAX_PREFIX_WARNING
);
6533 member
->pmax
[afi
][safi
] = 0;
6534 member
->pmax_threshold
[afi
][safi
] = 0;
6535 member
->pmax_restart
[afi
][safi
] = 0;
6542 int is_ebgp_multihop_configured(struct peer
*peer
)
6544 struct peer_group
*group
;
6545 struct listnode
*node
, *nnode
;
6548 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6549 group
= peer
->group
;
6550 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6551 && (group
->conf
->ttl
!= BGP_DEFAULT_TTL
))
6554 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6555 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6556 && (peer1
->ttl
!= BGP_DEFAULT_TTL
))
6560 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6561 && (peer
->ttl
!= BGP_DEFAULT_TTL
))
6567 /* Set # of hops between us and BGP peer. */
6568 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6570 struct peer_group
*group
;
6571 struct listnode
*node
, *nnode
;
6574 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6575 gtsm_hops
, peer
->host
);
6577 /* We cannot configure ttl-security hops when ebgp-multihop is already
6578 set. For non peer-groups, the check is simple. For peer-groups,
6580 slightly messy, because we need to check both the peer-group
6582 and all peer-group members for any trace of ebgp-multihop
6584 before actually applying the ttl-security rules. Cisco really made a
6585 mess of this configuration parameter, and OpenBGPD got it right.
6588 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6589 if (is_ebgp_multihop_configured(peer
))
6590 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6592 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6593 peer
->gtsm_hops
= gtsm_hops
;
6595 /* Calling ebgp multihop also resets the session.
6596 * On restart, NHT will get setup correctly as will the
6597 * min & max ttls on the socket. The return value is
6600 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6605 group
= peer
->group
;
6606 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6608 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6610 /* Calling ebgp multihop also resets the
6612 * On restart, NHT will get setup correctly as
6614 * min & max ttls on the socket. The return
6618 peer_ebgp_multihop_set(peer
, MAXTTL
);
6622 /* Post the first gtsm setup or if its ibgp, maxttl setting
6624 * necessary, just set the minttl.
6626 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6627 peer
->gtsm_hops
= gtsm_hops
;
6630 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6631 MAXTTL
+ 1 - gtsm_hops
);
6632 if ((peer
->status
< Established
) && peer
->doppelganger
6633 && (peer
->doppelganger
->fd
>= 0))
6634 sockopt_minttl(peer
->su
.sa
.sa_family
,
6635 peer
->doppelganger
->fd
,
6636 MAXTTL
+ 1 - gtsm_hops
);
6638 group
= peer
->group
;
6639 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6641 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6643 /* Change setting of existing peer
6644 * established then change value (may break
6646 * not established yet (teardown session and
6648 * no session then do nothing (will get
6649 * handled by next connection)
6651 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6653 peer
->su
.sa
.sa_family
, peer
->fd
,
6654 MAXTTL
+ 1 - peer
->gtsm_hops
);
6655 if ((peer
->status
< Established
)
6656 && peer
->doppelganger
6657 && (peer
->doppelganger
->fd
>= 0))
6658 sockopt_minttl(peer
->su
.sa
.sa_family
,
6659 peer
->doppelganger
->fd
,
6660 MAXTTL
+ 1 - gtsm_hops
);
6668 int peer_ttl_security_hops_unset(struct peer
*peer
)
6670 struct peer_group
*group
;
6671 struct listnode
*node
, *nnode
;
6674 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6677 /* if a peer-group member, then reset to peer-group default rather than
6679 if (peer_group_active(peer
))
6680 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6682 peer
->gtsm_hops
= 0;
6684 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6685 /* Invoking ebgp_multihop_set will set the TTL back to the
6687 * value as well as restting the NHT and such. The session is
6690 if (peer
->sort
== BGP_PEER_EBGP
)
6691 ret
= peer_ebgp_multihop_unset(peer
);
6694 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6697 if ((peer
->status
< Established
) && peer
->doppelganger
6698 && (peer
->doppelganger
->fd
>= 0))
6699 sockopt_minttl(peer
->su
.sa
.sa_family
,
6700 peer
->doppelganger
->fd
, 0);
6703 group
= peer
->group
;
6704 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6705 peer
->gtsm_hops
= 0;
6706 if (peer
->sort
== BGP_PEER_EBGP
)
6707 ret
= peer_ebgp_multihop_unset(peer
);
6710 sockopt_minttl(peer
->su
.sa
.sa_family
,
6713 if ((peer
->status
< Established
)
6714 && peer
->doppelganger
6715 && (peer
->doppelganger
->fd
>= 0))
6716 sockopt_minttl(peer
->su
.sa
.sa_family
,
6717 peer
->doppelganger
->fd
,
6727 * If peer clear is invoked in a loop for all peers on the BGP instance,
6728 * it may end up freeing the doppelganger, and if this was the next node
6729 * to the current node, we would end up accessing the freed next node.
6730 * Pass along additional parameter which can be updated if next node
6731 * is freed; only required when walking the peer list on BGP instance.
6733 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6735 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6736 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6737 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6738 if (peer
->t_pmax_restart
) {
6739 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6740 if (bgp_debug_neighbor_events(peer
))
6742 "%s Maximum-prefix restart timer canceled",
6745 BGP_EVENT_ADD(peer
, BGP_Start
);
6749 peer
->v_start
= BGP_INIT_START_TIMER
;
6750 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6751 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6752 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6754 bgp_session_reset_safe(peer
, nnode
);
6759 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6760 enum bgp_clear_type stype
)
6762 struct peer_af
*paf
;
6764 if (peer
->status
!= Established
)
6767 if (!peer
->afc
[afi
][safi
])
6768 return BGP_ERR_AF_UNCONFIGURED
;
6770 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6772 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6773 /* Clear the "neighbor x.x.x.x default-originate" flag */
6774 paf
= peer_af_find(peer
, afi
, safi
);
6775 if (paf
&& paf
->subgroup
6776 && CHECK_FLAG(paf
->subgroup
->sflags
,
6777 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6778 UNSET_FLAG(paf
->subgroup
->sflags
,
6779 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6781 bgp_announce_route(peer
, afi
, safi
);
6784 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6785 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6786 PEER_CAP_ORF_PREFIX_SM_ADV
)
6787 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6788 PEER_CAP_ORF_PREFIX_RM_RCV
)
6789 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6790 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6791 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6792 uint8_t prefix_type
;
6794 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6795 PEER_CAP_ORF_PREFIX_RM_RCV
))
6796 prefix_type
= ORF_TYPE_PREFIX
;
6798 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6800 if (filter
->plist
[FILTER_IN
].plist
) {
6801 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6802 PEER_STATUS_ORF_PREFIX_SEND
))
6803 bgp_route_refresh_send(
6804 peer
, afi
, safi
, prefix_type
,
6806 bgp_route_refresh_send(peer
, afi
, safi
,
6808 REFRESH_IMMEDIATE
, 0);
6810 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6811 PEER_STATUS_ORF_PREFIX_SEND
))
6812 bgp_route_refresh_send(
6813 peer
, afi
, safi
, prefix_type
,
6814 REFRESH_IMMEDIATE
, 1);
6816 bgp_route_refresh_send(peer
, afi
, safi
,
6823 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6824 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6825 /* If neighbor has soft reconfiguration inbound flag.
6826 Use Adj-RIB-In database. */
6827 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6828 PEER_FLAG_SOFT_RECONFIG
))
6829 bgp_soft_reconfig_in(peer
, afi
, safi
);
6831 /* If neighbor has route refresh capability, send route
6833 message to the peer. */
6834 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6835 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6836 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6839 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6845 /* Display peer uptime.*/
6846 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6849 time_t uptime1
, epoch_tbuf
;
6852 /* If there is no connection has been done before print `never'. */
6855 json_object_string_add(json
, "peerUptime", "never");
6856 json_object_int_add(json
, "peerUptimeMsec", 0);
6858 snprintf(buf
, len
, "never");
6862 /* Get current time. */
6863 uptime1
= bgp_clock();
6865 tm
= gmtime(&uptime1
);
6867 if (uptime1
< ONE_DAY_SECOND
)
6868 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6870 else if (uptime1
< ONE_WEEK_SECOND
)
6871 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6873 else if (uptime1
< ONE_YEAR_SECOND
)
6874 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6875 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6877 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6879 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6882 epoch_tbuf
= time(NULL
) - uptime1
;
6883 json_object_string_add(json
, "peerUptime", buf
);
6884 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6885 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6892 void bgp_master_init(struct thread_master
*master
, const int buffer_size
)
6896 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
6899 bm
->bgp
= list_new();
6900 bm
->listen_sockets
= list_new();
6901 bm
->port
= BGP_PORT_DEFAULT
;
6902 bm
->master
= master
;
6903 bm
->start_time
= bgp_clock();
6904 bm
->t_rmap_update
= NULL
;
6905 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
6906 bm
->terminating
= false;
6907 bm
->socket_buffer
= buffer_size
;
6909 bgp_process_queue_init();
6912 /* init the rd id space.
6913 assign 0th index in the bitfield,
6914 so that we start with id 1
6916 bf_init(bm
->rd_idspace
, UINT16_MAX
);
6917 bf_assign_zero_index(bm
->rd_idspace
);
6919 /* mpls label dynamic allocation pool */
6920 bgp_lp_init(bm
->master
, &bm
->labelpool
);
6922 QOBJ_REG(bm
, bgp_master
);
6926 * Free up connected routes and interfaces for a BGP instance. Invoked upon
6927 * instance delete (non-default only) or BGP exit.
6929 static void bgp_if_finish(struct bgp
*bgp
)
6932 struct interface
*ifp
;
6934 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
6936 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
6939 FOR_ALL_INTERFACES (vrf
, ifp
) {
6940 struct listnode
*c_node
, *c_nnode
;
6941 struct connected
*c
;
6943 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
6944 bgp_connected_delete(bgp
, c
);
6948 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
6950 struct vrf
*vrf
= NULL
;
6951 struct listnode
*next
;
6954 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
6955 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
6957 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6958 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
6961 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
6965 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
6967 struct listnode
*next
, *next2
;
6968 struct bgp
*bgp
, *bgp2
;
6971 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6973 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
6974 if (bgp2
->as
== bgp
->as
)
6982 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
6983 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
6987 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
6988 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
6989 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
6990 {.completions
= NULL
},
6993 struct frr_pthread
*bgp_pth_io
;
6994 struct frr_pthread
*bgp_pth_ka
;
6996 static void bgp_pthreads_init(void)
6998 assert(!bgp_pth_io
);
6999 assert(!bgp_pth_ka
);
7001 struct frr_pthread_attr io
= {
7002 .start
= frr_pthread_attr_default
.start
,
7003 .stop
= frr_pthread_attr_default
.stop
,
7005 struct frr_pthread_attr ka
= {
7006 .start
= bgp_keepalives_start
,
7007 .stop
= bgp_keepalives_stop
,
7009 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7010 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7013 void bgp_pthreads_run(void)
7015 frr_pthread_run(bgp_pth_io
, NULL
);
7016 frr_pthread_run(bgp_pth_ka
, NULL
);
7018 /* Wait until threads are ready. */
7019 frr_pthread_wait_running(bgp_pth_io
);
7020 frr_pthread_wait_running(bgp_pth_ka
);
7023 void bgp_pthreads_finish(void)
7025 frr_pthread_stop_all();
7028 void bgp_init(unsigned short instance
)
7031 /* allocates some vital data structures used by peer commands in
7034 /* pre-init pthreads */
7035 bgp_pthreads_init();
7038 bgp_zebra_init(bm
->master
, instance
);
7041 vnc_zebra_init(bm
->master
);
7044 /* BGP VTY commands installation. */
7052 bgp_route_map_init();
7053 bgp_scan_vty_init();
7058 bgp_ethernetvpn_init();
7059 bgp_flowspec_vty_init();
7061 /* Access list initialize. */
7063 access_list_add_hook(peer_distribute_update
);
7064 access_list_delete_hook(peer_distribute_update
);
7066 /* Filter list initialize. */
7068 as_list_add_hook(peer_aslist_add
);
7069 as_list_delete_hook(peer_aslist_del
);
7071 /* Prefix list initialize.*/
7073 prefix_list_add_hook(peer_prefix_list_update
);
7074 prefix_list_delete_hook(peer_prefix_list_update
);
7076 /* Community list initialize. */
7077 bgp_clist
= community_list_init();
7082 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7085 void bgp_terminate(void)
7089 struct listnode
*node
, *nnode
;
7090 struct listnode
*mnode
, *mnnode
;
7094 /* Close the listener sockets first as this prevents peers from
7096 * to reconnect on receiving the peer unconfig message. In the presence
7097 * of a large number of peers this will ensure that no peer is left with
7098 * a dangling connection
7100 /* reverse bgp_master_init */
7103 if (bm
->listen_sockets
)
7104 list_delete(&bm
->listen_sockets
);
7106 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7107 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7108 if (peer
->status
== Established
7109 || peer
->status
== OpenSent
7110 || peer
->status
== OpenConfirm
)
7111 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7112 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7114 if (bm
->process_main_queue
)
7115 work_queue_free_and_null(&bm
->process_main_queue
);
7117 if (bm
->t_rmap_update
)
7118 BGP_TIMER_OFF(bm
->t_rmap_update
);
7123 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
7124 const char *ip_str
, bool use_json
)
7130 /* Get peer sockunion. */
7131 ret
= str2sockunion(ip_str
, &su
);
7133 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
7135 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
7139 json_object
*json_no
= NULL
;
7140 json_no
= json_object_new_object();
7141 json_object_string_add(
7143 "malformedAddressOrName",
7145 vty_out(vty
, "%s\n",
7146 json_object_to_json_string_ext(
7148 JSON_C_TO_STRING_PRETTY
));
7149 json_object_free(json_no
);
7152 "%% Malformed address or name: %s\n",
7160 /* Peer structure lookup. */
7161 peer
= peer_lookup(bgp
, &su
);
7164 json_object
*json_no
= NULL
;
7165 json_no
= json_object_new_object();
7166 json_object_string_add(json_no
, "warning",
7167 "No such neighbor in this view/vrf");
7168 vty_out(vty
, "%s\n",
7169 json_object_to_json_string_ext(
7170 json_no
, JSON_C_TO_STRING_PRETTY
));
7171 json_object_free(json_no
);
7173 vty_out(vty
, "No such neighbor in this view/vrf\n");
7180 void bgp_gr_apply_running_config(void)
7182 struct peer
*peer
= NULL
;
7183 struct bgp
*bgp
= NULL
;
7184 struct listnode
*node
, *nnode
;
7185 bool gr_router_detected
= false;
7187 if (BGP_DEBUG(graceful_restart
, GRACEFUL_RESTART
))
7188 zlog_debug("[BGP_GR] %s called !", __func__
);
7190 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
7191 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7192 bgp_peer_gr_flags_update(peer
);
7193 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_GRACEFUL_RESTART
))
7194 gr_router_detected
= true;
7197 if (gr_router_detected
7198 && bgp
->present_zebra_gr_state
== ZEBRA_GR_DISABLE
) {
7199 bgp_zebra_send_capabilities(bgp
, true);
7200 } else if (!gr_router_detected
7201 && bgp
->present_zebra_gr_state
== ZEBRA_GR_ENABLE
) {
7202 bgp_zebra_send_capabilities(bgp
, false);
7205 gr_router_detected
= false;