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
)
98 /* BGP process wide configuration. */
99 static struct bgp_master bgp_master
;
101 /* BGP process wide configuration pointer to export. */
102 struct bgp_master
*bm
;
104 /* BGP community-list. */
105 struct community_list_handler
*bgp_clist
;
107 unsigned int multipath_num
= MULTIPATH_NUM
;
109 static void bgp_if_finish(struct bgp
*bgp
);
110 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
112 extern struct zclient
*zclient
;
114 /* handle main socket creation or deletion */
115 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
117 static int bgp_server_main_created
;
119 if (create
== true) {
120 if (bgp_server_main_created
)
122 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
123 return BGP_ERR_INVALID_VALUE
;
124 bgp_server_main_created
= 1;
127 if (!bgp_server_main_created
)
130 bgp_server_main_created
= 0;
134 void bgp_session_reset(struct peer
*peer
)
136 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
137 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
138 peer_delete(peer
->doppelganger
);
140 BGP_EVENT_ADD(peer
, BGP_Stop
);
144 * During session reset, we may delete the doppelganger peer, which would
145 * be the next node to the current node. If the session reset was invoked
146 * during walk of peer list, we would end up accessing the freed next
147 * node. This function moves the next node along.
149 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
154 n
= (nnode
) ? *nnode
: NULL
;
155 npeer
= (n
) ? listgetdata(n
) : NULL
;
157 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
158 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
159 PEER_FLAG_CONFIG_NODE
))) {
160 if (peer
->doppelganger
== npeer
)
161 /* nnode and *nnode are confirmed to be non-NULL here */
162 *nnode
= (*nnode
)->next
;
163 peer_delete(peer
->doppelganger
);
166 BGP_EVENT_ADD(peer
, BGP_Stop
);
169 /* BGP global flag manipulation. */
170 int bgp_option_set(int flag
)
174 case BGP_OPT_MULTIPLE_INSTANCE
:
175 case BGP_OPT_CONFIG_CISCO
:
176 case BGP_OPT_NO_LISTEN
:
177 case BGP_OPT_NO_ZEBRA
:
178 SET_FLAG(bm
->options
, flag
);
181 return BGP_ERR_INVALID_FLAG
;
186 int bgp_option_unset(int flag
)
189 case BGP_OPT_MULTIPLE_INSTANCE
:
190 if (listcount(bm
->bgp
) > 1)
191 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
193 case BGP_OPT_NO_ZEBRA
:
195 case BGP_OPT_CONFIG_CISCO
:
196 UNSET_FLAG(bm
->options
, flag
);
199 return BGP_ERR_INVALID_FLAG
;
204 int bgp_option_check(int flag
)
206 return CHECK_FLAG(bm
->options
, flag
);
209 /* BGP flag manipulation. */
210 int bgp_flag_set(struct bgp
*bgp
, int flag
)
212 SET_FLAG(bgp
->flags
, flag
);
216 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
218 UNSET_FLAG(bgp
->flags
, flag
);
222 int bgp_flag_check(struct bgp
*bgp
, int flag
)
224 return CHECK_FLAG(bgp
->flags
, flag
);
227 /* Internal function to set BGP structure configureation flag. */
228 static void bgp_config_set(struct bgp
*bgp
, int config
)
230 SET_FLAG(bgp
->config
, config
);
233 static void bgp_config_unset(struct bgp
*bgp
, int config
)
235 UNSET_FLAG(bgp
->config
, config
);
238 static int bgp_config_check(struct bgp
*bgp
, int config
)
240 return CHECK_FLAG(bgp
->config
, config
);
243 /* Set BGP router identifier. */
244 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
247 struct listnode
*node
, *nnode
;
249 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
252 /* EVPN uses router id in RD, withdraw them */
253 if (is_evpn_enabled())
254 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
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
);
276 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
278 struct listnode
*node
, *nnode
;
280 struct in_addr
*addr
= NULL
;
282 if (router_id
!= NULL
)
283 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
285 if (vrf_id
== VRF_DEFAULT
) {
286 /* Router-id change for default VRF has to also update all
288 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
289 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
293 bgp
->router_id_zebra
= *addr
;
295 addr
= &bgp
->router_id_zebra
;
297 if (!bgp
->router_id_static
.s_addr
) {
298 /* Router ID is updated if there are no active
301 if (bgp
->established_peers
== 0) {
302 if (BGP_DEBUG(zebra
, ZEBRA
))
303 zlog_debug("RID change : vrf %u, RTR ID %s",
304 bgp
->vrf_id
, inet_ntoa(*addr
));
305 bgp_router_id_set(bgp
, addr
);
310 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
313 bgp
->router_id_zebra
= *addr
;
315 addr
= &bgp
->router_id_zebra
;
317 if (!bgp
->router_id_static
.s_addr
) {
318 /* Router ID is updated if there are no active
321 if (bgp
->established_peers
== 0) {
322 if (BGP_DEBUG(zebra
, ZEBRA
))
323 zlog_debug("RID change : vrf %u, RTR ID %s",
324 bgp
->vrf_id
, inet_ntoa(*addr
));
325 bgp_router_id_set(bgp
, addr
);
333 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
335 bgp
->router_id_static
= id
;
336 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
340 /* BGP's cluster-id control. */
341 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
344 struct listnode
*node
, *nnode
;
346 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
347 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
350 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
351 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
353 /* Clear all IBGP peer. */
354 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
355 if (peer
->sort
!= BGP_PEER_IBGP
)
358 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
359 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
360 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
361 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
367 int bgp_cluster_id_unset(struct bgp
*bgp
)
370 struct listnode
*node
, *nnode
;
372 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
375 bgp
->cluster_id
.s_addr
= 0;
376 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
378 /* Clear all IBGP peer. */
379 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
380 if (peer
->sort
!= BGP_PEER_IBGP
)
383 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
384 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
385 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
386 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
392 /* time_t value that is monotonicly increasing
393 * and uneffected by adjustments to system clock
395 time_t bgp_clock(void)
403 /* BGP timer configuration. */
404 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
406 bgp
->default_keepalive
=
407 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
408 bgp
->default_holdtime
= holdtime
;
413 int bgp_timers_unset(struct bgp
*bgp
)
415 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
416 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
421 /* BGP confederation configuration. */
422 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
425 struct listnode
*node
, *nnode
;
429 return BGP_ERR_INVALID_AS
;
431 /* Remember - were we doing confederation before? */
432 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
434 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
436 /* If we were doing confederation already, this is just an external
437 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
438 were not doing confederation before, reset all EBGP sessions. */
439 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
440 /* We're looking for peers who's AS is not local or part of our
442 if (already_confed
) {
443 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
445 if (BGP_IS_VALID_STATE_FOR_NOTIF(
448 PEER_DOWN_CONFED_ID_CHANGE
;
450 peer
, BGP_NOTIFY_CEASE
,
451 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
453 bgp_session_reset_safe(peer
, &nnode
);
456 /* Not doign confederation before, so reset every
459 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
460 /* Reset the local_as to be our EBGP one */
461 if (peer_sort(peer
) == BGP_PEER_EBGP
)
463 if (BGP_IS_VALID_STATE_FOR_NOTIF(
466 PEER_DOWN_CONFED_ID_CHANGE
;
468 peer
, BGP_NOTIFY_CEASE
,
469 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
471 bgp_session_reset_safe(peer
, &nnode
);
478 int bgp_confederation_id_unset(struct bgp
*bgp
)
481 struct listnode
*node
, *nnode
;
484 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
486 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
487 /* We're looking for peers who's AS is not local */
488 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
489 peer
->local_as
= bgp
->as
;
490 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
491 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
492 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
493 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
497 bgp_session_reset_safe(peer
, &nnode
);
503 /* Is an AS part of the confed or not? */
504 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
511 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
512 if (bgp
->confed_peers
[i
] == as
)
518 /* Add an AS to the confederation set. */
519 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
522 struct listnode
*node
, *nnode
;
525 return BGP_ERR_INVALID_BGP
;
528 return BGP_ERR_INVALID_AS
;
530 if (bgp_confederation_peers_check(bgp
, as
))
533 if (bgp
->confed_peers
)
535 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
536 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
539 XMALLOC(MTYPE_BGP_CONFED_LIST
,
540 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
542 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
543 bgp
->confed_peers_cnt
++;
545 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
546 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
547 if (peer
->as
== as
) {
548 peer
->local_as
= bgp
->as
;
549 if (BGP_IS_VALID_STATE_FOR_NOTIF(
552 PEER_DOWN_CONFED_PEER_CHANGE
;
554 peer
, BGP_NOTIFY_CEASE
,
555 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
557 bgp_session_reset_safe(peer
, &nnode
);
564 /* Delete an AS from the confederation set. */
565 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
570 struct listnode
*node
, *nnode
;
575 if (!bgp_confederation_peers_check(bgp
, as
))
578 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
579 if (bgp
->confed_peers
[i
] == as
)
580 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
581 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
583 bgp
->confed_peers_cnt
--;
585 if (bgp
->confed_peers_cnt
== 0) {
586 if (bgp
->confed_peers
)
587 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
588 bgp
->confed_peers
= NULL
;
591 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
592 bgp
->confed_peers_cnt
* sizeof(as_t
));
594 /* Now reset any peer who's remote AS has just been removed from the
596 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
597 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
598 if (peer
->as
== as
) {
599 peer
->local_as
= bgp
->confed_id
;
600 if (BGP_IS_VALID_STATE_FOR_NOTIF(
603 PEER_DOWN_CONFED_PEER_CHANGE
;
605 peer
, BGP_NOTIFY_CEASE
,
606 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
608 bgp_session_reset_safe(peer
, &nnode
);
616 /* Local preference configuration. */
617 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
622 bgp
->default_local_pref
= local_pref
;
627 int bgp_default_local_preference_unset(struct bgp
*bgp
)
632 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
637 /* Local preference configuration. */
638 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
643 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
648 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
652 bgp
->default_subgroup_pkt_queue_max
=
653 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
658 /* Listen limit configuration. */
659 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
664 bgp
->dynamic_neighbors_limit
= listen_limit
;
669 int bgp_listen_limit_unset(struct bgp
*bgp
)
674 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
679 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
680 afi_t
*afi
, safi_t
*safi
)
682 /* Map from IANA values to internal values, return error if
683 * values are unrecognized.
685 *afi
= afi_iana2int(pkt_afi
);
686 *safi
= safi_iana2int(pkt_safi
);
687 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
693 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
694 iana_safi_t
*pkt_safi
)
696 /* Map from internal values to IANA values, return error if
697 * internal values are bad (unexpected).
699 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
701 *pkt_afi
= afi_int2iana(afi
);
702 *pkt_safi
= safi_int2iana(safi
);
706 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
714 afid
= afindex(afi
, safi
);
715 if (afid
>= BGP_AF_MAX
)
718 assert(peer
->peer_af_array
[afid
] == NULL
);
720 /* Allocate new peer af */
721 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
723 peer
->peer_af_array
[afid
] = af
;
732 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
739 afid
= afindex(afi
, safi
);
740 if (afid
>= BGP_AF_MAX
)
743 return peer
->peer_af_array
[afid
];
746 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
754 afid
= afindex(afi
, safi
);
755 if (afid
>= BGP_AF_MAX
)
758 af
= peer
->peer_af_array
[afid
];
762 bgp_stop_announce_route_timer(af
);
764 if (PAF_SUBGRP(af
)) {
765 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
766 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
767 af
->subgroup
->update_group
->id
,
768 af
->subgroup
->id
, peer
->host
);
771 update_subgroup_remove_peer(af
->subgroup
, af
);
773 peer
->peer_af_array
[afid
] = NULL
;
774 XFREE(MTYPE_BGP_PEER_AF
, af
);
778 /* Peer comparison function for sorting. */
779 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
781 if (p1
->group
&& !p2
->group
)
784 if (!p1
->group
&& p2
->group
)
787 if (p1
->group
== p2
->group
) {
788 if (p1
->conf_if
&& !p2
->conf_if
)
791 if (!p1
->conf_if
&& p2
->conf_if
)
794 if (p1
->conf_if
&& p2
->conf_if
)
795 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
797 return strcmp(p1
->group
->name
, p2
->group
->name
);
799 return sockunion_cmp(&p1
->su
, &p2
->su
);
802 static unsigned int peer_hash_key_make(void *p
)
804 struct peer
*peer
= p
;
805 return sockunion_hash(&peer
->su
);
808 static bool peer_hash_same(const void *p1
, const void *p2
)
810 const struct peer
*peer1
= p1
;
811 const struct peer
*peer2
= p2
;
812 return (sockunion_same(&peer1
->su
, &peer2
->su
)
813 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
814 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
817 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
821 /* Skip if peer is not a peer-group member. */
822 if (!peer_group_active(peer
))
825 /* Unset override flag to signal inheritance from peer-group. */
826 UNSET_FLAG(peer
->flags_override
, flag
);
829 * Inherit flag state from peer-group. If the flag of the peer-group is
830 * not being inverted, the peer must inherit the inverse of the current
831 * peer-group flag state.
833 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
834 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
835 && CHECK_FLAG(peer
->flags_invert
, flag
))
836 COND_FLAG(peer
->flags
, flag
, !group_val
);
838 COND_FLAG(peer
->flags
, flag
, group_val
);
841 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
843 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
846 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
851 /* Skip if peer is not a peer-group member. */
852 if (!peer_group_active(peer
))
855 /* Unset override flag to signal inheritance from peer-group. */
856 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
859 * Inherit flag state from peer-group. If the flag of the peer-group is
860 * not being inverted, the peer must inherit the inverse of the current
861 * peer-group flag state.
863 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
864 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
865 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
866 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
868 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
871 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
873 if (!peer_group_active(peer
)) {
874 if (CHECK_FLAG(peer
->flags_invert
, flag
))
875 return !CHECK_FLAG(peer
->flags
, flag
);
877 return !!CHECK_FLAG(peer
->flags
, flag
);
880 return !!CHECK_FLAG(peer
->flags_override
, flag
);
883 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
886 if (!peer_group_active(peer
)) {
887 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
888 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
890 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
893 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
896 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
897 uint8_t type
, int direct
)
899 struct bgp_filter
*filter
;
901 if (peer_group_active(peer
))
902 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
905 filter
= &peer
->filter
[afi
][safi
];
907 case PEER_FT_DISTRIBUTE_LIST
:
908 return !!(filter
->dlist
[direct
].name
);
909 case PEER_FT_FILTER_LIST
:
910 return !!(filter
->aslist
[direct
].name
);
911 case PEER_FT_PREFIX_LIST
:
912 return !!(filter
->plist
[direct
].name
);
913 case PEER_FT_ROUTE_MAP
:
914 return !!(filter
->map
[direct
].name
);
915 case PEER_FT_UNSUPPRESS_MAP
:
916 return !!(filter
->usmap
.name
);
922 /* Return true if the addpath type is set for peer and different from
925 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
927 enum bgp_addpath_strat type
, g_type
;
929 type
= peer
->addpath_type
[afi
][safi
];
931 if (type
!= BGP_ADDPATH_NONE
) {
932 if (peer_group_active(peer
)) {
933 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
947 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
948 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
955 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
956 if (peer
->as_type
== AS_INTERNAL
)
957 return BGP_PEER_IBGP
;
959 else if (peer
->as_type
== AS_EXTERNAL
)
960 return BGP_PEER_EBGP
;
962 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
964 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
972 peer1
= listnode_head(peer
->group
->peer
);
977 return BGP_PEER_INTERNAL
;
981 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
982 if (peer
->local_as
== 0)
983 return BGP_PEER_INTERNAL
;
985 if (peer
->local_as
== peer
->as
) {
986 if (bgp
->as
== bgp
->confed_id
) {
987 if (peer
->local_as
== bgp
->as
)
988 return BGP_PEER_IBGP
;
990 return BGP_PEER_EBGP
;
992 if (peer
->local_as
== bgp
->confed_id
)
993 return BGP_PEER_EBGP
;
995 return BGP_PEER_IBGP
;
999 if (bgp_confederation_peers_check(bgp
, peer
->as
))
1000 return BGP_PEER_CONFED
;
1002 return BGP_PEER_EBGP
;
1004 if (peer
->as_type
== AS_UNSPECIFIED
) {
1005 /* check if in peer-group with AS information */
1007 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
1008 if (peer
->group
->conf
->as_type
1011 == peer
->group
->conf
->as
)
1012 return BGP_PEER_IBGP
;
1014 return BGP_PEER_EBGP
;
1015 } else if (peer
->group
->conf
->as_type
1017 return BGP_PEER_IBGP
;
1019 return BGP_PEER_EBGP
;
1021 /* no AS information anywhere, let caller know */
1022 return BGP_PEER_UNSPECIFIED
;
1023 } else if (peer
->as_type
!= AS_SPECIFIED
)
1024 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1027 return (peer
->local_as
== 0
1029 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1034 /* Calculate and cache the peer "sort" */
1035 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1037 peer
->sort
= peer_calc_sort(peer
);
1041 static void peer_free(struct peer
*peer
)
1046 assert(peer
->status
== Deleted
);
1050 /* this /ought/ to have been done already through bgp_stop earlier,
1051 * but just to be sure..
1053 bgp_timer_set(peer
);
1054 bgp_reads_off(peer
);
1055 bgp_writes_off(peer
);
1056 assert(!peer
->t_write
);
1057 assert(!peer
->t_read
);
1058 BGP_EVENT_FLUSH(peer
);
1060 pthread_mutex_destroy(&peer
->io_mtx
);
1062 /* Free connected nexthop, if present */
1063 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1064 && !peer_dynamic_neighbor(peer
))
1065 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1068 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1071 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1075 /* Free allocated host character. */
1077 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1081 if (peer
->domainname
) {
1082 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1083 peer
->domainname
= NULL
;
1087 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1088 peer
->ifname
= NULL
;
1091 /* Update source configuration. */
1092 if (peer
->update_source
) {
1093 sockunion_free(peer
->update_source
);
1094 peer
->update_source
= NULL
;
1097 if (peer
->update_if
) {
1098 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1099 peer
->update_if
= NULL
;
1102 if (peer
->notify
.data
)
1103 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1104 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1106 if (peer
->clear_node_queue
)
1107 work_queue_free_and_null(&peer
->clear_node_queue
);
1109 bgp_sync_delete(peer
);
1111 if (peer
->conf_if
) {
1112 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1113 peer
->conf_if
= NULL
;
1116 bfd_info_free(&(peer
->bfd_info
));
1118 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1119 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1120 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1125 bgp_unlock(peer
->bgp
);
1127 memset(peer
, 0, sizeof(struct peer
));
1129 XFREE(MTYPE_BGP_PEER
, peer
);
1132 /* increase reference count on a struct peer */
1133 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1135 assert(peer
&& (peer
->lock
>= 0));
1138 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1146 /* decrease reference count on a struct peer
1147 * struct peer is freed and NULL returned if last reference
1149 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1151 assert(peer
&& (peer
->lock
> 0));
1154 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1159 if (peer
->lock
== 0) {
1167 /* Allocate new peer object, implicitely locked. */
1168 struct peer
*peer_new(struct bgp
*bgp
)
1175 /* bgp argument is absolutely required */
1180 /* Allocate new peer. */
1181 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1183 /* Set default value. */
1185 peer
->v_start
= BGP_INIT_START_TIMER
;
1186 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1187 peer
->status
= Idle
;
1188 peer
->ostatus
= Idle
;
1189 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1190 peer
->bgp
= bgp_lock(bgp
);
1191 peer
= peer_lock(peer
); /* initial reference */
1192 peer
->password
= NULL
;
1194 /* Set default flags. */
1195 FOREACH_AFI_SAFI (afi
, safi
) {
1196 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1197 SET_FLAG(peer
->af_flags
[afi
][safi
],
1198 PEER_FLAG_SEND_COMMUNITY
);
1199 SET_FLAG(peer
->af_flags
[afi
][safi
],
1200 PEER_FLAG_SEND_EXT_COMMUNITY
);
1201 SET_FLAG(peer
->af_flags
[afi
][safi
],
1202 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1204 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1205 PEER_FLAG_SEND_COMMUNITY
);
1206 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1207 PEER_FLAG_SEND_EXT_COMMUNITY
);
1208 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1209 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1211 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1214 /* set nexthop-unchanged for l2vpn evpn by default */
1215 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1216 PEER_FLAG_NEXTHOP_UNCHANGED
);
1218 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1220 /* Create buffers. */
1221 peer
->ibuf
= stream_fifo_new();
1222 peer
->obuf
= stream_fifo_new();
1223 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1225 /* We use a larger buffer for peer->obuf_work in the event that:
1226 * - We RX a BGP_UPDATE where the attributes alone are just
1227 * under BGP_MAX_PACKET_SIZE
1228 * - The user configures an outbound route-map that does many as-path
1229 * prepends or adds many communities. At most they can have
1230 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1231 * large they can make the attributes.
1233 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1234 * bounds checking for every single attribute as we construct an
1238 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1240 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1242 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1244 bgp_sync_init(peer
);
1246 /* Get service port number. */
1247 sp
= getservbyname("bgp", "tcp");
1248 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1250 QOBJ_REG(peer
, peer
);
1255 * This function is invoked when a duplicate peer structure associated with
1256 * a neighbor is being deleted. If this about-to-be-deleted structure is
1257 * the one with all the config, then we have to copy over the info.
1259 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1261 struct peer_af
*paf
;
1269 /* The following function is used by both peer group config copy to
1270 * individual peer and when we transfer config
1272 if (peer_src
->change_local_as
)
1273 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1275 /* peer flags apply */
1276 peer_dst
->flags
= peer_src
->flags
;
1277 peer_dst
->cap
= peer_src
->cap
;
1279 peer_dst
->local_as
= peer_src
->local_as
;
1280 peer_dst
->port
= peer_src
->port
;
1281 (void)peer_sort(peer_dst
);
1282 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1285 peer_dst
->holdtime
= peer_src
->holdtime
;
1286 peer_dst
->keepalive
= peer_src
->keepalive
;
1287 peer_dst
->connect
= peer_src
->connect
;
1288 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1289 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1290 peer_dst
->routeadv
= peer_src
->routeadv
;
1291 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1293 /* password apply */
1294 if (peer_src
->password
&& !peer_dst
->password
)
1295 peer_dst
->password
=
1296 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1298 FOREACH_AFI_SAFI (afi
, safi
) {
1299 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1300 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1301 peer_dst
->allowas_in
[afi
][safi
] =
1302 peer_src
->allowas_in
[afi
][safi
];
1303 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1304 peer_dst
->addpath_type
[afi
][safi
] =
1305 peer_src
->addpath_type
[afi
][safi
];
1308 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1309 paf
= peer_src
->peer_af_array
[afidx
];
1311 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1314 /* update-source apply */
1315 if (peer_src
->update_source
) {
1316 if (peer_dst
->update_source
)
1317 sockunion_free(peer_dst
->update_source
);
1318 if (peer_dst
->update_if
) {
1319 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1320 peer_dst
->update_if
= NULL
;
1322 peer_dst
->update_source
=
1323 sockunion_dup(peer_src
->update_source
);
1324 } else if (peer_src
->update_if
) {
1325 if (peer_dst
->update_if
)
1326 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1327 if (peer_dst
->update_source
) {
1328 sockunion_free(peer_dst
->update_source
);
1329 peer_dst
->update_source
= NULL
;
1331 peer_dst
->update_if
=
1332 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1335 if (peer_src
->ifname
) {
1336 if (peer_dst
->ifname
)
1337 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1340 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1344 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1345 struct interface
*ifp
)
1347 struct connected
*ifc
;
1350 struct listnode
*node
;
1352 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1353 * IPv4 address of the other end.
1355 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1356 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1357 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1358 if (p
.prefixlen
== 30) {
1359 peer
->su
.sa
.sa_family
= AF_INET
;
1360 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1362 peer
->su
.sin
.sin_addr
.s_addr
=
1364 else if (addr
% 4 == 2)
1365 peer
->su
.sin
.sin_addr
.s_addr
=
1367 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1368 peer
->su
.sin
.sin_len
=
1369 sizeof(struct sockaddr_in
);
1370 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1372 } else if (p
.prefixlen
== 31) {
1373 peer
->su
.sa
.sa_family
= AF_INET
;
1374 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1376 peer
->su
.sin
.sin_addr
.s_addr
=
1379 peer
->su
.sin
.sin_addr
.s_addr
=
1381 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1382 peer
->su
.sin
.sin_len
=
1383 sizeof(struct sockaddr_in
);
1384 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1386 } else if (bgp_debug_neighbor_events(peer
))
1388 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1396 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1397 struct interface
*ifp
)
1399 struct nbr_connected
*ifc_nbr
;
1401 /* Have we learnt the peer's IPv6 link-local address? */
1402 if (ifp
->nbr_connected
1403 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1404 peer
->su
.sa
.sa_family
= AF_INET6
;
1405 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1406 sizeof(struct in6_addr
));
1408 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1410 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1418 * Set or reset the peer address socketunion structure based on the
1419 * learnt/derived peer address. If the address has changed, update the
1420 * password on the listen socket, if needed.
1422 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1424 struct interface
*ifp
;
1426 int peer_addr_updated
= 0;
1432 * Our peer structure is stored in the bgp->peerhash
1433 * release it before we modify anything.
1435 hash_release(peer
->bgp
->peerhash
, peer
);
1437 prev_family
= peer
->su
.sa
.sa_family
;
1438 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1440 /* If BGP unnumbered is not "v6only", we first see if we can
1442 * peer's IPv4 address.
1444 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1446 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1448 /* If "v6only" or we can't derive peer's IPv4 address, see if
1450 * learnt the peer's IPv6 link-local address. This is from the
1452 * IPv6 address in router advertisement.
1454 if (!peer_addr_updated
)
1456 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1458 /* If we could derive the peer address, we may need to install the
1460 * configured for the peer, if any, on the listen socket. Otherwise,
1462 * that peer's address is not available and uninstall the password, if
1465 if (peer_addr_updated
) {
1466 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1467 && prev_family
== AF_UNSPEC
)
1470 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1471 && prev_family
!= AF_UNSPEC
)
1472 bgp_md5_unset(peer
);
1473 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1474 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1478 * Since our su changed we need to del/add peer to the peerhash
1480 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1483 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1486 struct bgp_node
*rn
, *nrn
;
1487 struct bgp_table
*table
;
1489 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1490 rn
= bgp_route_next(rn
)) {
1491 table
= bgp_node_get_bgp_table_info(rn
);
1492 if (table
!= NULL
) {
1493 /* Special handling for 2-level routing
1495 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1496 || safi
== SAFI_EVPN
) {
1497 for (nrn
= bgp_table_top(table
);
1498 nrn
; nrn
= bgp_route_next(nrn
))
1499 bgp_process(bgp
, nrn
, afi
, safi
);
1501 bgp_process(bgp
, rn
, afi
, safi
);
1506 /* Force a bestpath recalculation for all prefixes. This is used
1507 * when 'bgp bestpath' commands are entered.
1509 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1514 FOREACH_AFI_SAFI (afi
, safi
) {
1515 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1520 * Create new BGP peer.
1522 * conf_if and su are mutually exclusive if configuring from the cli.
1523 * If we are handing a doppelganger, then we *must* pass in both
1524 * the original peer's su and conf_if, so that we can appropriately
1525 * track the bgp->peerhash( ie we don't want to remove the current
1526 * one from the config ).
1528 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1529 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1530 int as_type
, afi_t afi
, safi_t safi
,
1531 struct peer_group
*group
)
1535 char buf
[SU_ADDRSTRLEN
];
1537 peer
= peer_new(bgp
);
1539 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1543 bgp_peer_conf_if_to_su_update(peer
);
1545 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1546 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1549 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1551 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1552 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1554 peer
->local_as
= local_as
;
1555 peer
->as
= remote_as
;
1556 peer
->as_type
= as_type
;
1557 peer
->local_id
= bgp
->router_id
;
1558 peer
->v_holdtime
= bgp
->default_holdtime
;
1559 peer
->v_keepalive
= bgp
->default_keepalive
;
1560 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1561 ? BGP_DEFAULT_IBGP_ROUTEADV
1562 : BGP_DEFAULT_EBGP_ROUTEADV
;
1564 peer
= peer_lock(peer
); /* bgp peer list reference */
1565 peer
->group
= group
;
1566 listnode_add_sort(bgp
->peer
, peer
);
1567 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1569 /* Adjust update-group coalesce timer heuristics for # peers. */
1570 if (bgp
->heuristic_coalesce
) {
1571 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1573 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1574 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1577 active
= peer_active(peer
);
1579 /* Last read and reset time set */
1580 peer
->readtime
= peer
->resettime
= bgp_clock();
1582 /* Default TTL set. */
1583 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1585 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1588 peer
->afc
[afi
][safi
] = 1;
1589 peer_af_create(peer
, afi
, safi
);
1592 /* auto shutdown if configured */
1593 if (bgp
->autoshutdown
)
1594 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1595 /* Set up peer's events and timers. */
1596 else if (!active
&& peer_active(peer
))
1597 bgp_timer_set(peer
);
1602 /* Make accept BGP peer. This function is only called from the test code */
1603 struct peer
*peer_create_accept(struct bgp
*bgp
)
1607 peer
= peer_new(bgp
);
1609 peer
= peer_lock(peer
); /* bgp peer list reference */
1610 listnode_add_sort(bgp
->peer
, peer
);
1616 * Return true if we have a peer configured to use this afi/safi
1618 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1620 struct listnode
*node
;
1623 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1624 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1627 if (peer
->afc
[afi
][safi
])
1634 /* Change peer's AS number. */
1635 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1637 bgp_peer_sort_t type
;
1640 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1641 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1642 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1643 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1644 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1646 bgp_session_reset(peer
);
1648 type
= peer_sort(peer
);
1650 peer
->as_type
= as_specified
;
1652 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1653 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1654 && peer
->bgp
->as
!= as
)
1655 peer
->local_as
= peer
->bgp
->confed_id
;
1657 peer
->local_as
= peer
->bgp
->as
;
1659 /* Advertisement-interval reset */
1660 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1661 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1662 ? BGP_DEFAULT_IBGP_ROUTEADV
1663 : BGP_DEFAULT_EBGP_ROUTEADV
;
1667 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1669 else if (type
== BGP_PEER_IBGP
)
1672 /* reflector-client reset */
1673 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1674 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1675 PEER_FLAG_REFLECTOR_CLIENT
);
1676 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1677 PEER_FLAG_REFLECTOR_CLIENT
);
1678 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1679 PEER_FLAG_REFLECTOR_CLIENT
);
1680 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1681 PEER_FLAG_REFLECTOR_CLIENT
);
1682 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1683 PEER_FLAG_REFLECTOR_CLIENT
);
1684 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1685 PEER_FLAG_REFLECTOR_CLIENT
);
1686 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1687 PEER_FLAG_REFLECTOR_CLIENT
);
1688 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1689 PEER_FLAG_REFLECTOR_CLIENT
);
1690 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1691 PEER_FLAG_REFLECTOR_CLIENT
);
1692 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1693 PEER_FLAG_REFLECTOR_CLIENT
);
1694 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1695 PEER_FLAG_REFLECTOR_CLIENT
);
1696 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1697 PEER_FLAG_REFLECTOR_CLIENT
);
1698 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1699 PEER_FLAG_REFLECTOR_CLIENT
);
1702 /* local-as reset */
1703 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1704 peer
->change_local_as
= 0;
1705 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1706 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1707 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1711 /* If peer does not exist, create new one. If peer already exists,
1712 set AS number to the peer. */
1713 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1714 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1720 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1722 peer
= peer_lookup(bgp
, su
);
1725 /* Not allowed for a dynamic peer. */
1726 if (peer_dynamic_neighbor(peer
)) {
1728 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1731 /* When this peer is a member of peer-group. */
1733 /* peer-group already has AS number/internal/external */
1734 if (peer
->group
->conf
->as
1735 || peer
->group
->conf
->as_type
) {
1736 /* Return peer group's AS number. */
1737 *as
= peer
->group
->conf
->as
;
1738 return BGP_ERR_PEER_GROUP_MEMBER
;
1741 bgp_peer_sort_t peer_sort_type
=
1742 peer_sort(peer
->group
->conf
);
1744 /* Explicit AS numbers used, compare AS numbers */
1745 if (as_type
== AS_SPECIFIED
) {
1746 if (((peer_sort_type
== BGP_PEER_IBGP
)
1747 && (bgp
->as
!= *as
))
1748 || ((peer_sort_type
== BGP_PEER_EBGP
)
1749 && (bgp
->as
== *as
))) {
1751 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1754 /* internal/external used, compare as-types */
1755 if (((peer_sort_type
== BGP_PEER_IBGP
)
1756 && (as_type
!= AS_INTERNAL
))
1757 || ((peer_sort_type
== BGP_PEER_EBGP
)
1758 && (as_type
!= AS_EXTERNAL
))) {
1760 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1765 /* Existing peer's AS number change. */
1766 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1767 || (peer
->as_type
!= as_type
))
1768 peer_as_change(peer
, *as
, as_type
);
1771 return BGP_ERR_NO_INTERFACE_CONFIG
;
1773 /* If the peer is not part of our confederation, and its not an
1774 iBGP peer then spoof the source AS */
1775 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1776 && !bgp_confederation_peers_check(bgp
, *as
)
1778 local_as
= bgp
->confed_id
;
1782 /* If this is IPv4 unicast configuration and "no bgp default
1783 ipv4-unicast" is specified. */
1785 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1786 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1787 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1790 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1797 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1798 struct peer
*peer
, afi_t afi
,
1802 int out
= FILTER_OUT
;
1804 uint32_t pflags_ovrd
;
1805 uint8_t *pfilter_ovrd
;
1809 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1810 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1812 /* peer af_flags apply */
1813 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1814 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1815 ^ peer
->af_flags_invert
[afi
][safi
];
1816 flags_tmp
&= ~pflags_ovrd
;
1818 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1819 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1820 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1821 conf
->af_flags_invert
[afi
][safi
]);
1823 /* maximum-prefix */
1824 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1825 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1826 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1827 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1831 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1832 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1835 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1836 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1838 /* default-originate route-map */
1839 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1840 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1841 MTYPE_ROUTE_MAP_NAME
);
1842 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1845 /* inbound filter apply */
1846 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1847 PEER_STR_ATTR_INHERIT(peer
, group
,
1848 filter
[afi
][safi
].dlist
[in
].name
,
1849 MTYPE_BGP_FILTER_NAME
);
1850 PEER_ATTR_INHERIT(peer
, group
,
1851 filter
[afi
][safi
].dlist
[in
].alist
);
1854 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1855 PEER_STR_ATTR_INHERIT(peer
, group
,
1856 filter
[afi
][safi
].plist
[in
].name
,
1857 MTYPE_BGP_FILTER_NAME
);
1858 PEER_ATTR_INHERIT(peer
, group
,
1859 filter
[afi
][safi
].plist
[in
].plist
);
1862 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1863 PEER_STR_ATTR_INHERIT(peer
, group
,
1864 filter
[afi
][safi
].aslist
[in
].name
,
1865 MTYPE_BGP_FILTER_NAME
);
1866 PEER_ATTR_INHERIT(peer
, group
,
1867 filter
[afi
][safi
].aslist
[in
].aslist
);
1870 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1871 PEER_STR_ATTR_INHERIT(peer
, group
,
1872 filter
[afi
][safi
].map
[in
].name
,
1873 MTYPE_BGP_FILTER_NAME
);
1874 PEER_ATTR_INHERIT(peer
, group
,
1875 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1878 /* outbound filter apply */
1879 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1880 PEER_STR_ATTR_INHERIT(peer
, group
,
1881 filter
[afi
][safi
].dlist
[out
].name
,
1882 MTYPE_BGP_FILTER_NAME
);
1883 PEER_ATTR_INHERIT(peer
, group
,
1884 filter
[afi
][safi
].dlist
[out
].alist
);
1887 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1888 PEER_STR_ATTR_INHERIT(peer
, group
,
1889 filter
[afi
][safi
].plist
[out
].name
,
1890 MTYPE_BGP_FILTER_NAME
);
1891 PEER_ATTR_INHERIT(peer
, group
,
1892 filter
[afi
][safi
].plist
[out
].plist
);
1895 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1896 PEER_STR_ATTR_INHERIT(peer
, group
,
1897 filter
[afi
][safi
].aslist
[out
].name
,
1898 MTYPE_BGP_FILTER_NAME
);
1899 PEER_ATTR_INHERIT(peer
, group
,
1900 filter
[afi
][safi
].aslist
[out
].aslist
);
1903 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1904 PEER_STR_ATTR_INHERIT(peer
, group
,
1905 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1906 MTYPE_BGP_FILTER_NAME
);
1907 PEER_ATTR_INHERIT(peer
, group
,
1908 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1911 /* nondirectional filter apply */
1912 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1913 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1914 MTYPE_BGP_FILTER_NAME
);
1915 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1918 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1919 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1920 bgp_addpath_type_changed(conf
->bgp
);
1924 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1929 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1930 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1931 __func__
, peer
->host
);
1935 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1937 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1938 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1939 return BGP_ERR_PEER_SAFI_CONFLICT
;
1941 /* Nothing to do if we've already activated this peer */
1942 if (peer
->afc
[afi
][safi
])
1945 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1948 active
= peer_active(peer
);
1949 peer
->afc
[afi
][safi
] = 1;
1952 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1954 if (!active
&& peer_active(peer
)) {
1955 bgp_timer_set(peer
);
1957 if (peer
->status
== Established
) {
1958 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1959 peer
->afc_adv
[afi
][safi
] = 1;
1960 bgp_capability_send(peer
, afi
, safi
,
1962 CAPABILITY_ACTION_SET
);
1963 if (peer
->afc_recv
[afi
][safi
]) {
1964 peer
->afc_nego
[afi
][safi
] = 1;
1965 bgp_announce_route(peer
, afi
, safi
);
1968 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1969 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1970 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1973 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1974 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1975 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1976 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1979 * If we are turning on a AFI/SAFI locally and we've
1980 * started bringing a peer up, we need to tell
1981 * the other peer to restart because we might loose
1982 * configuration here because when the doppelganger
1983 * gets to a established state due to how
1984 * we resolve we could just overwrite the afi/safi
1987 other
= peer
->doppelganger
;
1989 && (other
->status
== OpenSent
1990 || other
->status
== OpenConfirm
)) {
1991 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1992 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1993 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2000 /* Activate the peer or peer group for specified AFI and SAFI. */
2001 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2004 struct peer_group
*group
;
2005 struct listnode
*node
, *nnode
;
2006 struct peer
*tmp_peer
;
2009 /* Nothing to do if we've already activated this peer */
2010 if (peer
->afc
[afi
][safi
])
2015 /* This is a peer-group so activate all of the members of the
2016 * peer-group as well */
2017 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2019 /* Do not activate a peer for both SAFI_UNICAST and
2020 * SAFI_LABELED_UNICAST */
2021 if ((safi
== SAFI_UNICAST
2022 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2023 || (safi
== SAFI_LABELED_UNICAST
2024 && peer
->afc
[afi
][SAFI_UNICAST
]))
2025 return BGP_ERR_PEER_SAFI_CONFLICT
;
2027 peer
->afc
[afi
][safi
] = 1;
2028 group
= peer
->group
;
2030 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2031 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2034 ret
|= peer_activate_af(peer
, afi
, safi
);
2037 /* If this is the first peer to be activated for this
2038 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2039 if (safi
== SAFI_LABELED_UNICAST
2040 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2042 if (BGP_DEBUG(zebra
, ZEBRA
))
2044 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2046 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2047 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2050 if (safi
== SAFI_FLOWSPEC
) {
2051 /* connect to table manager */
2052 bgp_zebra_init_tm_connect(bgp
);
2057 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2060 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2061 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2062 __func__
, peer
->host
);
2066 /* Nothing to do if we've already deactivated this peer */
2067 if (!peer
->afc
[afi
][safi
])
2070 /* De-activate the address family configuration. */
2071 peer
->afc
[afi
][safi
] = 0;
2073 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2074 flog_err(EC_BGP_PEER_DELETE
,
2075 "couldn't delete af structure for peer %s",
2080 if (peer
->status
== Established
) {
2081 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2082 peer
->afc_adv
[afi
][safi
] = 0;
2083 peer
->afc_nego
[afi
][safi
] = 0;
2085 if (peer_active_nego(peer
)) {
2086 bgp_capability_send(peer
, afi
, safi
,
2088 CAPABILITY_ACTION_UNSET
);
2089 bgp_clear_route(peer
, afi
, safi
);
2090 peer
->pcount
[afi
][safi
] = 0;
2092 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2093 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2094 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2097 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2098 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2099 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2106 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2109 struct peer_group
*group
;
2110 struct peer
*tmp_peer
;
2111 struct listnode
*node
, *nnode
;
2114 /* Nothing to do if we've already de-activated this peer */
2115 if (!peer
->afc
[afi
][safi
])
2118 /* This is a peer-group so de-activate all of the members of the
2119 * peer-group as well */
2120 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2121 peer
->afc
[afi
][safi
] = 0;
2122 group
= peer
->group
;
2124 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2125 flog_err(EC_BGP_PEER_DELETE
,
2126 "couldn't delete af structure for peer %s",
2130 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2131 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2134 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2139 /* If this is the last peer to be deactivated for this
2140 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2141 if (safi
== SAFI_LABELED_UNICAST
2142 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2143 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2145 if (BGP_DEBUG(zebra
, ZEBRA
))
2147 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2149 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2150 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2155 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2158 return peer_activate(peer
, afi
, safi
);
2160 return peer_deactivate(peer
, afi
, safi
);
2163 static void peer_nsf_stop(struct peer
*peer
)
2168 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2169 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2171 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2172 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2173 peer
->nsf
[afi
][safi
] = 0;
2175 if (peer
->t_gr_restart
) {
2176 BGP_TIMER_OFF(peer
->t_gr_restart
);
2177 if (bgp_debug_neighbor_events(peer
))
2178 zlog_debug("%s graceful restart timer stopped",
2181 if (peer
->t_gr_stale
) {
2182 BGP_TIMER_OFF(peer
->t_gr_stale
);
2183 if (bgp_debug_neighbor_events(peer
))
2185 "%s graceful restart stalepath timer stopped",
2188 bgp_clear_route_all(peer
);
2191 /* Delete peer from confguration.
2193 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2194 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2196 * This function /should/ take care to be idempotent, to guard against
2197 * it being called multiple times through stray events that come in
2198 * that happen to result in this function being called again. That
2199 * said, getting here for a "Deleted" peer is a bug in the neighbour
2202 int peer_delete(struct peer
*peer
)
2208 struct bgp_filter
*filter
;
2209 struct listnode
*pn
;
2212 assert(peer
->status
!= Deleted
);
2215 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2217 bgp_reads_off(peer
);
2218 bgp_writes_off(peer
);
2219 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2220 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2222 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2223 peer_nsf_stop(peer
);
2225 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2227 /* If this peer belongs to peer group, clear up the
2230 if (peer_dynamic_neighbor(peer
))
2231 peer_drop_dynamic_neighbor(peer
);
2233 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2235 peer
); /* group->peer list reference */
2236 list_delete_node(peer
->group
->peer
, pn
);
2241 /* Withdraw all information from routing table. We can not use
2242 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2243 * executed after peer structure is deleted.
2245 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2247 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2249 if (peer
->doppelganger
) {
2250 peer
->doppelganger
->doppelganger
= NULL
;
2251 peer
->doppelganger
= NULL
;
2254 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2255 bgp_fsm_change_status(peer
, Deleted
);
2257 /* Remove from NHT */
2258 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2259 bgp_unlink_nexthop_by_peer(peer
);
2261 /* Password configuration */
2262 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2263 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2265 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2266 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2267 bgp_md5_unset(peer
);
2270 bgp_timer_set(peer
); /* stops all timers for Deleted */
2272 /* Delete from all peer list. */
2273 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2274 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2275 peer_unlock(peer
); /* bgp peer list reference */
2276 list_delete_node(bgp
->peer
, pn
);
2277 hash_release(bgp
->peerhash
, peer
);
2282 stream_fifo_free(peer
->ibuf
);
2287 stream_fifo_free(peer
->obuf
);
2291 if (peer
->ibuf_work
) {
2292 ringbuf_del(peer
->ibuf_work
);
2293 peer
->ibuf_work
= NULL
;
2296 if (peer
->obuf_work
) {
2297 stream_free(peer
->obuf_work
);
2298 peer
->obuf_work
= NULL
;
2301 if (peer
->scratch
) {
2302 stream_free(peer
->scratch
);
2303 peer
->scratch
= NULL
;
2306 /* Local and remote addresses. */
2307 if (peer
->su_local
) {
2308 sockunion_free(peer
->su_local
);
2309 peer
->su_local
= NULL
;
2312 if (peer
->su_remote
) {
2313 sockunion_free(peer
->su_remote
);
2314 peer
->su_remote
= NULL
;
2317 /* Free filter related memory. */
2318 FOREACH_AFI_SAFI (afi
, safi
) {
2319 filter
= &peer
->filter
[afi
][safi
];
2321 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2322 if (filter
->dlist
[i
].name
) {
2323 XFREE(MTYPE_BGP_FILTER_NAME
,
2324 filter
->dlist
[i
].name
);
2325 filter
->dlist
[i
].name
= NULL
;
2328 if (filter
->plist
[i
].name
) {
2329 XFREE(MTYPE_BGP_FILTER_NAME
,
2330 filter
->plist
[i
].name
);
2331 filter
->plist
[i
].name
= NULL
;
2334 if (filter
->aslist
[i
].name
) {
2335 XFREE(MTYPE_BGP_FILTER_NAME
,
2336 filter
->aslist
[i
].name
);
2337 filter
->aslist
[i
].name
= NULL
;
2341 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2342 if (filter
->map
[i
].name
) {
2343 XFREE(MTYPE_BGP_FILTER_NAME
,
2344 filter
->map
[i
].name
);
2345 filter
->map
[i
].name
= NULL
;
2349 if (filter
->usmap
.name
) {
2350 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2351 filter
->usmap
.name
= NULL
;
2354 if (peer
->default_rmap
[afi
][safi
].name
) {
2355 XFREE(MTYPE_ROUTE_MAP_NAME
,
2356 peer
->default_rmap
[afi
][safi
].name
);
2357 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2361 FOREACH_AFI_SAFI (afi
, safi
)
2362 peer_af_delete(peer
, afi
, safi
);
2364 if (peer
->hostname
) {
2365 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2366 peer
->hostname
= NULL
;
2369 if (peer
->domainname
) {
2370 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2371 peer
->domainname
= NULL
;
2374 peer_unlock(peer
); /* initial reference */
2379 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2381 return strcmp(g1
->name
, g2
->name
);
2384 /* Peer group cofiguration. */
2385 static struct peer_group
*peer_group_new(void)
2387 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2388 sizeof(struct peer_group
));
2391 static void peer_group_free(struct peer_group
*group
)
2393 XFREE(MTYPE_PEER_GROUP
, group
);
2396 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2398 struct peer_group
*group
;
2399 struct listnode
*node
, *nnode
;
2401 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2402 if (strcmp(group
->name
, name
) == 0)
2408 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2410 struct peer_group
*group
;
2413 group
= peer_group_lookup(bgp
, name
);
2417 group
= peer_group_new();
2420 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2421 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2422 group
->peer
= list_new();
2423 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2424 group
->listen_range
[afi
] = list_new();
2425 group
->conf
= peer_new(bgp
);
2426 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2427 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2428 if (group
->conf
->host
)
2429 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2430 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2431 group
->conf
->group
= group
;
2432 group
->conf
->as
= 0;
2433 group
->conf
->ttl
= 1;
2434 group
->conf
->gtsm_hops
= 0;
2435 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2436 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2437 listnode_add_sort(bgp
->group
, group
);
2442 static void peer_group2peer_config_copy(struct peer_group
*group
,
2452 peer
->as
= conf
->as
;
2455 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2456 peer
->change_local_as
= conf
->change_local_as
;
2459 peer
->ttl
= conf
->ttl
;
2462 peer
->gtsm_hops
= conf
->gtsm_hops
;
2464 /* peer flags apply */
2465 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2466 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2467 flags_tmp
&= ~peer
->flags_override
;
2469 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2470 SET_FLAG(peer
->flags
, flags_tmp
);
2471 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2473 /* peer timers apply */
2474 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2475 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2476 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2479 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2480 PEER_ATTR_INHERIT(peer
, group
, connect
);
2481 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2482 peer
->v_connect
= conf
->connect
;
2484 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2487 /* advertisement-interval apply */
2488 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2489 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2490 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2491 peer
->v_routeadv
= conf
->routeadv
;
2493 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2494 ? BGP_DEFAULT_IBGP_ROUTEADV
2495 : BGP_DEFAULT_EBGP_ROUTEADV
;
2498 /* password apply */
2499 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2500 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2501 MTYPE_PEER_PASSWORD
);
2503 if (!BGP_PEER_SU_UNSPEC(peer
))
2506 /* update-source apply */
2507 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2508 if (conf
->update_source
) {
2509 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2510 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2511 } else if (conf
->update_if
) {
2512 sockunion_free(peer
->update_source
);
2513 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2514 MTYPE_PEER_UPDATE_SOURCE
);
2518 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2521 /* Peer group's remote AS configuration. */
2522 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2525 struct peer_group
*group
;
2527 struct listnode
*node
, *nnode
;
2529 group
= peer_group_lookup(bgp
, group_name
);
2533 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2537 /* When we setup peer-group AS number all peer group member's AS
2538 number must be updated to same number. */
2539 peer_as_change(group
->conf
, *as
, as_type
);
2541 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2542 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2543 || (peer
->as_type
!= as_type
))
2544 peer_as_change(peer
, *as
, as_type
);
2550 int peer_group_delete(struct peer_group
*group
)
2554 struct prefix
*prefix
;
2556 struct listnode
*node
, *nnode
;
2561 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2562 other
= peer
->doppelganger
;
2564 if (other
&& other
->status
!= Deleted
) {
2565 other
->group
= NULL
;
2569 list_delete(&group
->peer
);
2571 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2572 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2574 prefix_free(prefix
);
2576 list_delete(&group
->listen_range
[afi
]);
2579 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2582 bfd_info_free(&(group
->conf
->bfd_info
));
2584 group
->conf
->group
= NULL
;
2585 peer_delete(group
->conf
);
2587 /* Delete from all peer_group list. */
2588 listnode_delete(bgp
->group
, group
);
2590 peer_group_free(group
);
2595 int peer_group_remote_as_delete(struct peer_group
*group
)
2597 struct peer
*peer
, *other
;
2598 struct listnode
*node
, *nnode
;
2600 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2601 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2604 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2605 other
= peer
->doppelganger
;
2609 if (other
&& other
->status
!= Deleted
) {
2610 other
->group
= NULL
;
2614 list_delete_all_node(group
->peer
);
2616 group
->conf
->as
= 0;
2617 group
->conf
->as_type
= AS_UNSPECIFIED
;
2622 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2624 struct prefix
*prefix
;
2625 struct listnode
*node
, *nnode
;
2628 afi
= family2afi(range
->family
);
2630 /* Group needs remote AS configured. */
2631 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2632 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2634 /* Ensure no duplicates. Currently we don't care about overlaps. */
2635 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2636 if (prefix_same(range
, prefix
))
2640 prefix
= prefix_new();
2641 prefix_copy(prefix
, range
);
2642 listnode_add(group
->listen_range
[afi
], prefix
);
2646 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2648 struct prefix
*prefix
, prefix2
;
2649 struct listnode
*node
, *nnode
;
2652 char buf
[PREFIX2STR_BUFFER
];
2654 afi
= family2afi(range
->family
);
2656 /* Identify the listen range. */
2657 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2658 if (prefix_same(range
, prefix
))
2663 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2665 prefix2str(prefix
, buf
, sizeof(buf
));
2667 /* Dispose off any dynamic neighbors that exist due to this listen range
2669 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2670 if (!peer_dynamic_neighbor(peer
))
2673 sockunion2hostprefix(&peer
->su
, &prefix2
);
2674 if (prefix_match(prefix
, &prefix2
)) {
2675 if (bgp_debug_neighbor_events(peer
))
2677 "Deleting dynamic neighbor %s group %s upon "
2678 "delete of listen range %s",
2679 peer
->host
, group
->name
, buf
);
2684 /* Get rid of the listen range */
2685 listnode_delete(group
->listen_range
[afi
], prefix
);
2690 /* Bind specified peer to peer group. */
2691 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2692 struct peer_group
*group
, as_t
*as
)
2694 int first_member
= 0;
2698 /* Lookup the peer. */
2700 peer
= peer_lookup(bgp
, su
);
2702 /* The peer exist, bind it to the peer-group */
2704 /* When the peer already belongs to a peer-group, check the
2706 if (peer_group_active(peer
)) {
2708 /* The peer is already bound to the peer-group,
2711 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2714 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2717 /* The peer has not specified a remote-as, inherit it from the
2719 if (peer
->as_type
== AS_UNSPECIFIED
) {
2720 peer
->as_type
= group
->conf
->as_type
;
2721 peer
->as
= group
->conf
->as
;
2722 peer
->sort
= group
->conf
->sort
;
2725 if (!group
->conf
->as
) {
2726 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2727 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2730 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2733 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2737 peer_group2peer_config_copy(group
, peer
);
2739 FOREACH_AFI_SAFI (afi
, safi
) {
2740 if (group
->conf
->afc
[afi
][safi
]) {
2741 peer
->afc
[afi
][safi
] = 1;
2743 if (peer_af_find(peer
, afi
, safi
)
2744 || peer_af_create(peer
, afi
, safi
)) {
2745 peer_group2peer_config_copy_af(
2746 group
, peer
, afi
, safi
);
2748 } else if (peer
->afc
[afi
][safi
])
2749 peer_deactivate(peer
, afi
, safi
);
2753 assert(group
&& peer
->group
== group
);
2755 listnode_delete(bgp
->peer
, peer
);
2757 peer
->group
= group
;
2758 listnode_add_sort(bgp
->peer
, peer
);
2760 peer
= peer_lock(peer
); /* group->peer list reference */
2761 listnode_add(group
->peer
, peer
);
2765 /* Advertisement-interval reset */
2766 if (!CHECK_FLAG(group
->conf
->flags
,
2767 PEER_FLAG_ROUTEADV
)) {
2768 group
->conf
->v_routeadv
=
2769 (peer_sort(group
->conf
)
2771 ? BGP_DEFAULT_IBGP_ROUTEADV
2772 : BGP_DEFAULT_EBGP_ROUTEADV
;
2775 /* ebgp-multihop reset */
2776 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2777 group
->conf
->ttl
= MAXTTL
;
2779 /* local-as reset */
2780 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2781 group
->conf
->change_local_as
= 0;
2782 peer_flag_unset(group
->conf
,
2783 PEER_FLAG_LOCAL_AS
);
2784 peer_flag_unset(group
->conf
,
2785 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2786 peer_flag_unset(group
->conf
,
2787 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2791 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2793 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2794 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2795 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2796 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2798 bgp_session_reset(peer
);
2802 /* Create a new peer. */
2804 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2805 && (!group
->conf
->as
)) {
2806 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2809 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2810 group
->conf
->as_type
, 0, 0, group
);
2812 peer
= peer_lock(peer
); /* group->peer list reference */
2813 listnode_add(group
->peer
, peer
);
2815 peer_group2peer_config_copy(group
, peer
);
2817 /* If the peer-group is active for this afi/safi then activate
2819 FOREACH_AFI_SAFI (afi
, safi
) {
2820 if (group
->conf
->afc
[afi
][safi
]) {
2821 peer
->afc
[afi
][safi
] = 1;
2822 peer_af_create(peer
, afi
, safi
);
2823 peer_group2peer_config_copy_af(group
, peer
, afi
,
2825 } else if (peer
->afc
[afi
][safi
])
2826 peer_deactivate(peer
, afi
, safi
);
2829 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2831 /* Set up peer's events and timers. */
2832 if (peer_active(peer
))
2833 bgp_timer_set(peer
);
2839 static int bgp_startup_timer_expire(struct thread
*thread
)
2843 bgp
= THREAD_ARG(thread
);
2844 bgp
->t_startup
= NULL
;
2850 * On shutdown we call the cleanup function which
2851 * does a free of the link list nodes, free up
2852 * the data we are pointing at too.
2854 static void bgp_vrf_string_name_delete(void *data
)
2858 XFREE(MTYPE_TMP
, vname
);
2861 /* BGP instance creation by `router bgp' commands. */
2862 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2863 enum bgp_instance_type inst_type
)
2869 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2872 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2873 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2874 zlog_debug("Creating Default VRF, AS %u", *as
);
2876 zlog_debug("Creating %s %s, AS %u",
2877 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2884 bgp
->heuristic_coalesce
= true;
2885 bgp
->inst_type
= inst_type
;
2886 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2888 bgp
->peer_self
= peer_new(bgp
);
2889 if (bgp
->peer_self
->host
)
2890 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2891 bgp
->peer_self
->host
=
2892 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2893 if (bgp
->peer_self
->hostname
!= NULL
) {
2894 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2895 bgp
->peer_self
->hostname
= NULL
;
2897 if (cmd_hostname_get())
2898 bgp
->peer_self
->hostname
=
2899 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2901 if (bgp
->peer_self
->domainname
!= NULL
) {
2902 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2903 bgp
->peer_self
->domainname
= NULL
;
2905 if (cmd_domainname_get())
2906 bgp
->peer_self
->domainname
=
2907 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2908 bgp
->peer
= list_new();
2909 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2910 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2912 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2914 bgp
->group
= list_new();
2915 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2917 FOREACH_AFI_SAFI (afi
, safi
) {
2918 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2919 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2920 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2922 /* Enable maximum-paths */
2923 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2925 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2929 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2930 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2931 bgp
->default_subgroup_pkt_queue_max
=
2932 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2933 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2934 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2935 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2936 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2937 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2938 bgp
->dynamic_neighbors_count
= 0;
2939 #if DFLT_BGP_IMPORT_CHECK
2940 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2942 #if DFLT_BGP_SHOW_HOSTNAME
2943 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2945 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2946 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2948 #if DFLT_BGP_DETERMINISTIC_MED
2949 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2951 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2956 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2957 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2959 assert(bgp
->rfapi_cfg
);
2961 #endif /* ENABLE_BGP_VNC */
2963 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2964 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2965 bgp
->vpn_policy
[afi
].afi
= afi
;
2966 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2967 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2970 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2971 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2972 bgp_vrf_string_name_delete
;
2973 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2974 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2975 bgp_vrf_string_name_delete
;
2978 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2980 /* TODO - The startup timer needs to be run for the whole of BGP
2982 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2983 bgp
->restart_time
, &bgp
->t_startup
);
2986 /* printable name we can use in debug messages */
2987 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2988 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2998 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3000 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3001 snprintf(bgp
->name_pretty
, len
, "%s %s",
3002 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3008 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3009 memory_order_relaxed
);
3010 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3011 memory_order_relaxed
);
3012 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3016 update_bgp_group_init(bgp
);
3018 /* assign a unique rd id for auto derivation of vrf's RD */
3019 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3021 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3022 sizeof(struct bgp_evpn_info
));
3029 /* Return the "default VRF" instance of BGP. */
3030 struct bgp
*bgp_get_default(void)
3033 struct listnode
*node
, *nnode
;
3035 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3036 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3041 /* Lookup BGP entry. */
3042 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3045 struct listnode
*node
, *nnode
;
3047 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3049 && ((bgp
->name
== NULL
&& name
== NULL
)
3050 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3055 /* Lookup BGP structure by view name. */
3056 struct bgp
*bgp_lookup_by_name(const char *name
)
3059 struct listnode
*node
, *nnode
;
3061 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3062 if ((bgp
->name
== NULL
&& name
== NULL
)
3063 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3068 /* Lookup BGP instance based on VRF id. */
3069 /* Note: Only to be used for incoming messages from Zebra. */
3070 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3074 /* Lookup VRF (in tree) and follow link. */
3075 vrf
= vrf_lookup_by_id(vrf_id
);
3078 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3081 /* handle socket creation or deletion, if necessary
3082 * this is called for all new BGP instances
3084 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3089 /* Create BGP server socket, if listen mode not disabled */
3090 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3092 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3094 * suppress vrf socket
3096 if (create
== FALSE
) {
3097 bgp_close_vrf_socket(bgp
);
3101 return BGP_ERR_INVALID_VALUE
;
3103 * if vrf_id did not change
3105 if (vrf
->vrf_id
== old_vrf_id
)
3107 if (old_vrf_id
!= VRF_UNKNOWN
) {
3108 /* look for old socket. close it. */
3109 bgp_close_vrf_socket(bgp
);
3111 /* if backend is not yet identified ( VRF_UNKNOWN) then
3112 * creation will be done later
3114 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3116 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3118 return BGP_ERR_INVALID_VALUE
;
3121 return bgp_check_main_socket(create
, bgp
);
3124 /* Called from VTY commands. */
3125 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3126 enum bgp_instance_type inst_type
)
3129 struct vrf
*vrf
= NULL
;
3131 /* Multiple instance check. */
3132 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3134 bgp
= bgp_lookup_by_name(name
);
3136 bgp
= bgp_get_default();
3138 /* Already exists. */
3140 if (bgp
->as
!= *as
) {
3142 return BGP_ERR_INSTANCE_MISMATCH
;
3144 if (bgp
->inst_type
!= inst_type
)
3145 return BGP_ERR_INSTANCE_MISMATCH
;
3150 /* BGP instance name can not be specified for single instance.
3153 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3155 /* Get default BGP structure if exists. */
3156 bgp
= bgp_get_default();
3159 if (bgp
->as
!= *as
) {
3161 return BGP_ERR_AS_MISMATCH
;
3168 bgp
= bgp_create(as
, name
, inst_type
);
3169 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3170 bgp
->vrf_id
= vrf_generate_id();
3171 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3172 bgp_address_init(bgp
);
3173 bgp_tip_hash_init(bgp
);
3177 bgp
->t_rmap_def_originate_eval
= NULL
;
3179 /* If Default instance or VRF, link to the VRF structure, if present. */
3180 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3181 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3182 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3184 bgp_vrf_link(bgp
, vrf
);
3186 /* BGP server socket already processed if BGP instance
3187 * already part of the list
3189 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3190 listnode_add(bm
->bgp
, bgp
);
3192 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3193 if (BGP_DEBUG(zebra
, ZEBRA
))
3194 zlog_debug("%s: Registering BGP instance %s to zebra",
3195 __PRETTY_FUNCTION__
, name
);
3196 bgp_zebra_instance_register(bgp
);
3203 * Make BGP instance "up". Applies only to VRFs (non-default) and
3204 * implies the VRF has been learnt from Zebra.
3206 void bgp_instance_up(struct bgp
*bgp
)
3209 struct listnode
*node
, *next
;
3211 /* Register with zebra. */
3212 bgp_zebra_instance_register(bgp
);
3214 /* Kick off any peers that may have been configured. */
3215 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3216 if (!BGP_PEER_START_SUPPRESSED(peer
))
3217 BGP_EVENT_ADD(peer
, BGP_Start
);
3220 /* Process any networks that have been configured. */
3221 bgp_static_add(bgp
);
3225 * Make BGP instance "down". Applies only to VRFs (non-default) and
3226 * implies the VRF has been deleted by Zebra.
3228 void bgp_instance_down(struct bgp
*bgp
)
3231 struct listnode
*node
;
3232 struct listnode
*next
;
3235 if (bgp
->t_rmap_def_originate_eval
) {
3236 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3237 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3241 /* Bring down peers, so corresponding routes are purged. */
3242 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3243 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3244 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3245 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3247 bgp_session_reset(peer
);
3250 /* Purge network and redistributed routes. */
3251 bgp_purge_static_redist_routes(bgp
);
3253 /* Cleanup registered nexthops (flags) */
3254 bgp_cleanup_nexthops(bgp
);
3257 /* Delete BGP instance. */
3258 int bgp_delete(struct bgp
*bgp
)
3261 struct peer_group
*group
;
3262 struct listnode
*node
, *next
;
3268 THREAD_OFF(bgp
->t_startup
);
3269 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3270 THREAD_OFF(bgp
->t_update_delay
);
3271 THREAD_OFF(bgp
->t_establish_wait
);
3273 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3274 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3275 zlog_debug("Deleting Default VRF");
3277 zlog_debug("Deleting %s %s",
3278 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3284 /* unmap from RT list */
3285 bgp_evpn_vrf_delete(bgp
);
3288 if (bgp
->t_rmap_def_originate_eval
) {
3289 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3290 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3294 /* Inform peers we're going down. */
3295 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3296 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3297 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3298 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3301 /* Delete static routes (networks). */
3302 bgp_static_delete(bgp
);
3304 /* Unset redistribution. */
3305 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3306 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3307 if (i
!= ZEBRA_ROUTE_BGP
)
3308 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3310 /* Free peers and peer-groups. */
3311 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3312 peer_group_delete(group
);
3314 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3317 if (bgp
->peer_self
) {
3318 peer_delete(bgp
->peer_self
);
3319 bgp
->peer_self
= NULL
;
3322 update_bgp_group_free(bgp
);
3324 /* TODO - Other memory may need to be freed - e.g., NHT */
3329 bgp_cleanup_routes(bgp
);
3331 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3332 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3335 &bgp
->vpn_policy
[afi
]
3336 .import_redirect_rtlist
);
3337 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3340 /* Deregister from Zebra, if needed */
3341 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3342 if (BGP_DEBUG(zebra
, ZEBRA
))
3343 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3344 __PRETTY_FUNCTION__
, bgp
->name
);
3345 bgp_zebra_instance_deregister(bgp
);
3348 /* Remove visibility via the master list - there may however still be
3349 * routes to be processed still referencing the struct bgp.
3351 listnode_delete(bm
->bgp
, bgp
);
3353 /* Free interfaces in this instance. */
3356 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3357 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3359 bgp_vrf_unlink(bgp
, vrf
);
3361 thread_master_free_unused(bm
->master
);
3362 bgp_unlock(bgp
); /* initial reference */
3367 void bgp_free(struct bgp
*bgp
)
3371 struct bgp_table
*table
;
3372 struct bgp_node
*rn
;
3373 struct bgp_rmap
*rmap
;
3377 list_delete(&bgp
->group
);
3378 list_delete(&bgp
->peer
);
3380 if (bgp
->peerhash
) {
3381 hash_free(bgp
->peerhash
);
3382 bgp
->peerhash
= NULL
;
3385 FOREACH_AFI_SAFI (afi
, safi
) {
3386 /* Special handling for 2-level routing tables. */
3387 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3388 || safi
== SAFI_EVPN
) {
3389 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3390 rn
= bgp_route_next(rn
)) {
3391 table
= bgp_node_get_bgp_table_info(rn
);
3392 bgp_table_finish(&table
);
3395 if (bgp
->route
[afi
][safi
])
3396 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3397 if (bgp
->aggregate
[afi
][safi
])
3398 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3399 if (bgp
->rib
[afi
][safi
])
3400 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3401 rmap
= &bgp
->table_map
[afi
][safi
];
3403 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3406 bgp_scan_finish(bgp
);
3407 bgp_address_destroy(bgp
);
3408 bgp_tip_hash_destroy(bgp
);
3410 /* release the auto RD id */
3411 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3413 bgp_evpn_cleanup(bgp
);
3414 bgp_pbr_cleanup(bgp
);
3415 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3417 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3418 vpn_policy_direction_t dir
;
3420 if (bgp
->vpn_policy
[afi
].import_vrf
)
3421 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3422 if (bgp
->vpn_policy
[afi
].export_vrf
)
3423 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3425 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3426 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3427 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3428 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3429 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3430 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3434 XFREE(MTYPE_BGP
, bgp
->name
);
3435 if (bgp
->name_pretty
)
3436 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3438 XFREE(MTYPE_BGP
, bgp
);
3441 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3444 struct listnode
*node
, *nnode
;
3450 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3451 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3452 && !CHECK_FLAG(peer
->sflags
,
3453 PEER_STATUS_ACCEPT_PEER
))
3455 } else if (bm
->bgp
!= NULL
) {
3456 struct listnode
*bgpnode
, *nbgpnode
;
3458 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3459 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3461 && !strcmp(peer
->conf_if
, conf_if
)
3462 && !CHECK_FLAG(peer
->sflags
,
3463 PEER_STATUS_ACCEPT_PEER
))
3469 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3472 struct listnode
*node
, *nnode
;
3478 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3479 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3480 && !CHECK_FLAG(peer
->sflags
,
3481 PEER_STATUS_ACCEPT_PEER
))
3483 } else if (bm
->bgp
!= NULL
) {
3484 struct listnode
*bgpnode
, *nbgpnode
;
3486 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3487 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3489 && !strcmp(peer
->hostname
, hostname
)
3490 && !CHECK_FLAG(peer
->sflags
,
3491 PEER_STATUS_ACCEPT_PEER
))
3497 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3499 struct peer
*peer
= NULL
;
3500 struct peer tmp_peer
;
3502 memset(&tmp_peer
, 0, sizeof(struct peer
));
3505 * We do not want to find the doppelganger peer so search for the peer
3507 * the hash that has PEER_FLAG_CONFIG_NODE
3509 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3514 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3515 } else if (bm
->bgp
!= NULL
) {
3516 struct listnode
*bgpnode
, *nbgpnode
;
3518 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3519 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3528 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3529 union sockunion
*su
,
3530 struct peer_group
*group
)
3536 /* Create peer first; we've already checked group config is valid. */
3537 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3538 group
->conf
->as_type
, 0, 0, group
);
3543 peer
= peer_lock(peer
);
3544 listnode_add(group
->peer
, peer
);
3546 peer_group2peer_config_copy(group
, peer
);
3549 * Bind peer for all AFs configured for the group. We don't call
3550 * peer_group_bind as that is sub-optimal and does some stuff we don't
3553 FOREACH_AFI_SAFI (afi
, safi
) {
3554 if (!group
->conf
->afc
[afi
][safi
])
3556 peer
->afc
[afi
][safi
] = 1;
3558 if (!peer_af_find(peer
, afi
, safi
))
3559 peer_af_create(peer
, afi
, safi
);
3561 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3564 /* Mark as dynamic, but also as a "config node" for other things to
3566 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3567 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3573 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3574 struct prefix
*prefix
)
3576 struct listnode
*node
, *nnode
;
3577 struct prefix
*range
;
3580 afi
= family2afi(prefix
->family
);
3582 if (group
->listen_range
[afi
])
3583 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3585 if (prefix_match(range
, prefix
))
3592 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3593 struct prefix
**listen_range
)
3595 struct prefix
*range
= NULL
;
3596 struct peer_group
*group
= NULL
;
3597 struct listnode
*node
, *nnode
;
3599 *listen_range
= NULL
;
3601 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3602 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3605 } else if (bm
->bgp
!= NULL
) {
3606 struct listnode
*bgpnode
, *nbgpnode
;
3608 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3609 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3610 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3616 *listen_range
= range
;
3617 return (group
&& range
) ? group
: NULL
;
3620 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3622 struct peer_group
*group
;
3625 struct prefix prefix
;
3626 struct prefix
*listen_range
;
3628 char buf
[PREFIX2STR_BUFFER
];
3629 char buf1
[PREFIX2STR_BUFFER
];
3631 sockunion2hostprefix(su
, &prefix
);
3633 /* See if incoming connection matches a configured listen range. */
3634 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3645 prefix2str(&prefix
, buf
, sizeof(buf
));
3646 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3648 if (bgp_debug_neighbor_events(NULL
))
3650 "Dynamic Neighbor %s matches group %s listen range %s",
3651 buf
, group
->name
, buf1
);
3653 /* Are we within the listen limit? */
3654 dncount
= gbgp
->dynamic_neighbors_count
;
3656 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3657 if (bgp_debug_neighbor_events(NULL
))
3658 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3659 inet_sutop(su
, buf
),
3660 gbgp
->dynamic_neighbors_limit
);
3664 /* Ensure group is not disabled. */
3665 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3666 if (bgp_debug_neighbor_events(NULL
))
3668 "Dynamic Neighbor %s rejected - group %s disabled",
3673 /* Check that at least one AF is activated for the group. */
3674 if (!peer_group_af_configured(group
)) {
3675 if (bgp_debug_neighbor_events(NULL
))
3677 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3682 /* Create dynamic peer and bind to associated group. */
3683 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3686 gbgp
->dynamic_neighbors_count
= ++dncount
;
3688 if (bgp_debug_neighbor_events(peer
))
3689 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3690 peer
->host
, group
->name
, dncount
);
3695 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3698 if (peer
->group
->bgp
) {
3699 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3701 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3703 if (bgp_debug_neighbor_events(peer
))
3704 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3705 peer
->group
->name
, dncount
);
3708 /* If peer is configured at least one address family return 1. */
3709 int peer_active(struct peer
*peer
)
3711 if (BGP_PEER_SU_UNSPEC(peer
))
3713 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3714 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3715 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3716 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3717 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3718 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3719 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3720 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3721 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3722 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3723 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3728 /* If peer is negotiated at least one address family return 1. */
3729 int peer_active_nego(struct peer
*peer
)
3731 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3732 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3733 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3734 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3735 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3736 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3737 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3738 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3739 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3740 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3741 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3742 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3743 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3748 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3749 enum peer_change_type type
)
3751 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3754 if (peer
->status
!= Established
)
3757 if (type
== peer_change_reset
) {
3758 /* If we're resetting session, we've to delete both peer struct
3760 if ((peer
->doppelganger
)
3761 && (peer
->doppelganger
->status
!= Deleted
)
3762 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3763 PEER_FLAG_CONFIG_NODE
)))
3764 peer_delete(peer
->doppelganger
);
3766 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3767 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3768 } else if (type
== peer_change_reset_in
) {
3769 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3770 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3771 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3773 if ((peer
->doppelganger
)
3774 && (peer
->doppelganger
->status
!= Deleted
)
3775 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3776 PEER_FLAG_CONFIG_NODE
)))
3777 peer_delete(peer
->doppelganger
);
3779 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3780 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3782 } else if (type
== peer_change_reset_out
) {
3783 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3784 bgp_announce_route(peer
, afi
, safi
);
3788 struct peer_flag_action
{
3792 /* This flag can be set for peer-group member. */
3793 uint8_t not_for_member
;
3795 /* Action when the flag is changed. */
3796 enum peer_change_type type
;
3799 static const struct peer_flag_action peer_flag_action_list
[] = {
3800 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3801 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3802 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3803 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3804 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3805 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3806 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3807 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3808 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3809 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3810 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3811 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3812 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3813 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3814 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3815 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3816 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3819 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3820 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3821 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3822 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3823 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3824 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3825 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3826 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3827 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3828 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3829 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3830 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3831 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3832 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3833 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3834 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3835 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3836 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3837 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3838 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3839 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3840 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3841 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3842 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3843 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3844 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3847 /* Proper action set. */
3848 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3849 int size
, struct peer_flag_action
*action
,
3856 const struct peer_flag_action
*match
= NULL
;
3858 /* Check peer's frag action. */
3859 for (i
= 0; i
< size
; i
++) {
3860 match
= &action_list
[i
];
3862 if (match
->flag
== 0)
3865 if (match
->flag
& flag
) {
3868 if (match
->type
== peer_change_reset_in
)
3870 if (match
->type
== peer_change_reset_out
)
3872 if (match
->type
== peer_change_reset
) {
3876 if (match
->not_for_member
)
3877 action
->not_for_member
= 1;
3881 /* Set peer clear type. */
3882 if (reset_in
&& reset_out
)
3883 action
->type
= peer_change_reset
;
3885 action
->type
= peer_change_reset_in
;
3887 action
->type
= peer_change_reset_out
;
3889 action
->type
= peer_change_none
;
3894 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3896 if (flag
== PEER_FLAG_SHUTDOWN
) {
3897 if (CHECK_FLAG(peer
->flags
, flag
)) {
3898 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3899 peer_nsf_stop(peer
);
3901 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3902 if (peer
->t_pmax_restart
) {
3903 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3904 if (bgp_debug_neighbor_events(peer
))
3906 "%s Maximum-prefix restart timer canceled",
3910 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3911 peer_nsf_stop(peer
);
3913 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3914 char *msg
= peer
->tx_shutdown_message
;
3917 if (!msg
&& peer_group_active(peer
))
3918 msg
= peer
->group
->conf
3919 ->tx_shutdown_message
;
3920 msglen
= msg
? strlen(msg
) : 0;
3925 uint8_t msgbuf
[129];
3928 memcpy(msgbuf
+ 1, msg
, msglen
);
3930 bgp_notify_send_with_data(
3931 peer
, BGP_NOTIFY_CEASE
,
3932 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3933 msgbuf
, msglen
+ 1);
3936 peer
, BGP_NOTIFY_CEASE
,
3937 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3939 bgp_session_reset(peer
);
3941 peer
->v_start
= BGP_INIT_START_TIMER
;
3942 BGP_EVENT_ADD(peer
, BGP_Stop
);
3944 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3945 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3946 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3947 else if (flag
== PEER_FLAG_PASSIVE
)
3948 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3949 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3950 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3952 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3953 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3955 bgp_session_reset(peer
);
3958 /* Change specified peer flag. */
3959 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3963 bool invert
, member_invert
;
3964 struct peer
*member
;
3965 struct listnode
*node
, *nnode
;
3966 struct peer_flag_action action
;
3968 memset(&action
, 0, sizeof(struct peer_flag_action
));
3969 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3971 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3972 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3975 /* Abort if no flag action exists. */
3977 return BGP_ERR_INVALID_FLAG
;
3979 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3980 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3981 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3982 return BGP_ERR_PEER_FLAG_CONFLICT
;
3984 /* Handle flag updates where desired state matches current state. */
3985 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3986 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3987 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3991 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3992 COND_FLAG(peer
->flags_override
, flag
, invert
);
3997 /* Inherit from peer-group or set/unset flags accordingly. */
3998 if (peer_group_active(peer
) && set
== invert
)
3999 peer_flag_inherit(peer
, flag
);
4001 COND_FLAG(peer
->flags
, flag
, set
);
4003 /* Check if handling a regular peer. */
4004 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4005 /* Update flag override state accordingly. */
4006 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4008 /* Execute flag action on peer. */
4009 if (action
.type
== peer_change_reset
)
4010 peer_flag_modify_action(peer
, flag
);
4012 /* Skip peer-group mechanics for regular peers. */
4016 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4017 bgp_nht_register_enhe_capability_interfaces(peer
);
4020 * Update peer-group members, unless they are explicitely overriding
4021 * peer-group configuration.
4023 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4024 /* Skip peers with overridden configuration. */
4025 if (CHECK_FLAG(member
->flags_override
, flag
))
4028 /* Check if only member without group is inverted. */
4030 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4032 /* Skip peers with equivalent configuration. */
4033 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4036 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4039 /* Update flag on peer-group member. */
4040 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4042 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4043 bgp_nht_register_enhe_capability_interfaces(member
);
4045 /* Execute flag action on peer-group member. */
4046 if (action
.type
== peer_change_reset
)
4047 peer_flag_modify_action(member
, flag
);
4053 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4055 return peer_flag_modify(peer
, flag
, 1);
4058 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4060 return peer_flag_modify(peer
, flag
, 0);
4063 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4064 uint32_t flag
, bool set
)
4068 bool invert
, member_invert
;
4069 struct peer
*member
;
4070 struct listnode
*node
, *nnode
;
4071 struct peer_flag_action action
;
4073 memset(&action
, 0, sizeof(struct peer_flag_action
));
4074 size
= sizeof peer_af_flag_action_list
4075 / sizeof(struct peer_flag_action
);
4077 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4078 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4081 /* Abort if flag action exists. */
4083 return BGP_ERR_INVALID_FLAG
;
4085 /* Special check for reflector client. */
4086 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4087 && peer_sort(peer
) != BGP_PEER_IBGP
)
4088 return BGP_ERR_NOT_INTERNAL_PEER
;
4090 /* Special check for remove-private-AS. */
4091 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4092 && peer_sort(peer
) == BGP_PEER_IBGP
)
4093 return BGP_ERR_REMOVE_PRIVATE_AS
;
4095 /* as-override is not allowed for IBGP peers */
4096 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4097 return BGP_ERR_AS_OVERRIDE
;
4099 /* Handle flag updates where desired state matches current state. */
4100 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4101 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4102 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4107 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4108 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4115 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4116 * if we are setting/unsetting flags which conflict with this flag
4117 * handle accordingly
4119 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4123 * if we are setting NEXTHOP_SELF, we need to unset the
4124 * NEXTHOP_UNCHANGED flag
4126 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4127 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4128 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4129 PEER_FLAG_NEXTHOP_UNCHANGED
);
4133 * if we are unsetting NEXTHOP_SELF, we need to set the
4134 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4136 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4137 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4138 SET_FLAG(peer
->af_flags
[afi
][safi
],
4139 PEER_FLAG_NEXTHOP_UNCHANGED
);
4143 /* Inherit from peer-group or set/unset flags accordingly. */
4144 if (peer_group_active(peer
) && set
== invert
)
4145 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4147 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4149 /* Execute action when peer is established. */
4150 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4151 && peer
->status
== Established
) {
4152 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4153 bgp_clear_adj_in(peer
, afi
, safi
);
4155 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4156 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4157 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4158 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4159 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4160 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4161 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4162 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4164 peer_change_action(peer
, afi
, safi
, action
.type
);
4168 /* Check if handling a regular peer. */
4169 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4170 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4174 * Update peer-group members, unless they are explicitely
4175 * overriding peer-group configuration.
4177 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4179 /* Skip peers with overridden configuration. */
4180 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4184 /* Check if only member without group is inverted. */
4186 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4190 /* Skip peers with equivalent configuration. */
4191 if (set
!= member_invert
4192 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4195 if (set
== member_invert
4196 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4199 /* Update flag on peer-group member. */
4200 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4201 set
!= member_invert
);
4203 /* Execute flag action on peer-group member. */
4204 if (member
->status
== Established
) {
4205 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4206 bgp_clear_adj_in(member
, afi
, safi
);
4208 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4209 member
->last_reset
=
4210 PEER_DOWN_RR_CLIENT_CHANGE
;
4212 == PEER_FLAG_RSERVER_CLIENT
)
4213 member
->last_reset
=
4214 PEER_DOWN_RS_CLIENT_CHANGE
;
4216 == PEER_FLAG_ORF_PREFIX_SM
)
4217 member
->last_reset
=
4218 PEER_DOWN_CAPABILITY_CHANGE
;
4220 == PEER_FLAG_ORF_PREFIX_RM
)
4221 member
->last_reset
=
4222 PEER_DOWN_CAPABILITY_CHANGE
;
4224 peer_change_action(member
, afi
, safi
,
4234 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4236 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4239 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4241 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4245 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4247 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4248 peer
->tx_shutdown_message
=
4249 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4253 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4255 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4260 /* EBGP multihop configuration. */
4261 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4263 struct peer_group
*group
;
4264 struct listnode
*node
, *nnode
;
4267 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4270 /* see comment in peer_ttl_security_hops_set() */
4271 if (ttl
!= MAXTTL
) {
4272 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4273 group
= peer
->group
;
4274 if (group
->conf
->gtsm_hops
!= 0)
4275 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4277 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4279 if (peer1
->sort
== BGP_PEER_IBGP
)
4282 if (peer1
->gtsm_hops
!= 0)
4283 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4286 if (peer
->gtsm_hops
!= 0)
4287 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4293 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4294 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4295 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4296 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4297 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4299 bgp_session_reset(peer
);
4302 group
= peer
->group
;
4303 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4304 if (peer
->sort
== BGP_PEER_IBGP
)
4307 peer
->ttl
= group
->conf
->ttl
;
4309 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4310 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4311 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4313 bgp_session_reset(peer
);
4319 int peer_ebgp_multihop_unset(struct peer
*peer
)
4321 struct peer_group
*group
;
4322 struct listnode
*node
, *nnode
;
4324 if (peer
->sort
== BGP_PEER_IBGP
)
4327 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4328 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4330 if (peer_group_active(peer
))
4331 peer
->ttl
= peer
->group
->conf
->ttl
;
4335 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4336 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4337 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4338 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4340 bgp_session_reset(peer
);
4342 group
= peer
->group
;
4343 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4344 if (peer
->sort
== BGP_PEER_IBGP
)
4349 if (peer
->fd
>= 0) {
4350 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4352 peer
, BGP_NOTIFY_CEASE
,
4353 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4355 bgp_session_reset(peer
);
4362 /* Neighbor description. */
4363 int peer_description_set(struct peer
*peer
, const char *desc
)
4366 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4368 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4373 int peer_description_unset(struct peer
*peer
)
4376 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4383 /* Neighbor update-source. */
4384 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4386 struct peer
*member
;
4387 struct listnode
*node
, *nnode
;
4389 /* Set flag and configuration on peer. */
4390 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4391 if (peer
->update_if
) {
4392 if (strcmp(peer
->update_if
, ifname
) == 0)
4394 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4396 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4397 sockunion_free(peer
->update_source
);
4398 peer
->update_source
= NULL
;
4400 /* Check if handling a regular peer. */
4401 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4402 /* Send notification or reset peer depending on state. */
4403 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4404 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4405 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4406 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4408 bgp_session_reset(peer
);
4410 /* Skip peer-group mechanics for regular peers. */
4415 * Set flag and configuration on all peer-group members, unless they are
4416 * explicitely overriding peer-group configuration.
4418 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4419 /* Skip peers with overridden configuration. */
4420 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4423 /* Skip peers with the same configuration. */
4424 if (member
->update_if
) {
4425 if (strcmp(member
->update_if
, ifname
) == 0)
4427 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4430 /* Set flag and configuration on peer-group member. */
4431 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4432 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4433 sockunion_free(member
->update_source
);
4434 member
->update_source
= NULL
;
4436 /* Send notification or reset peer depending on state. */
4437 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4438 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4439 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4440 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4442 bgp_session_reset(member
);
4448 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
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_source
) {
4456 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4458 sockunion_free(peer
->update_source
);
4460 peer
->update_source
= sockunion_dup(su
);
4461 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4463 /* Check if handling a regular peer. */
4464 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4465 /* Send notification or reset peer depending on state. */
4466 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4467 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4468 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4469 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4471 bgp_session_reset(peer
);
4473 /* Skip peer-group mechanics for regular peers. */
4478 * Set flag and configuration on all peer-group members, unless they are
4479 * explicitely overriding peer-group configuration.
4481 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4482 /* Skip peers with overridden configuration. */
4483 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4486 /* Skip peers with the same configuration. */
4487 if (member
->update_source
) {
4488 if (sockunion_cmp(member
->update_source
, su
) == 0)
4490 sockunion_free(member
->update_source
);
4493 /* Set flag and configuration on peer-group member. */
4494 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4495 member
->update_source
= sockunion_dup(su
);
4496 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4498 /* Send notification or reset peer depending on state. */
4499 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4500 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4501 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4502 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4504 bgp_session_reset(member
);
4510 int peer_update_source_unset(struct peer
*peer
)
4512 struct peer
*member
;
4513 struct listnode
*node
, *nnode
;
4515 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4518 /* Inherit configuration from peer-group if peer is member. */
4519 if (peer_group_active(peer
)) {
4520 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4521 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4522 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4523 MTYPE_PEER_UPDATE_SOURCE
);
4525 /* Otherwise remove flag and configuration from peer. */
4526 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4527 sockunion_free(peer
->update_source
);
4528 peer
->update_source
= NULL
;
4529 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4532 /* Check if handling a regular peer. */
4533 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4534 /* Send notification or reset peer depending on state. */
4535 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4536 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4537 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4538 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4540 bgp_session_reset(peer
);
4542 /* Skip peer-group mechanics for regular peers. */
4547 * Set flag and configuration on all peer-group members, unless they are
4548 * explicitely overriding peer-group configuration.
4550 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4551 /* Skip peers with overridden configuration. */
4552 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4555 /* Skip peers with the same configuration. */
4556 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4557 && !member
->update_source
&& !member
->update_if
)
4560 /* Remove flag and configuration on peer-group member. */
4561 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4562 sockunion_free(member
->update_source
);
4563 member
->update_source
= NULL
;
4564 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4566 /* Send notification or reset peer depending on state. */
4567 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4568 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4569 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4570 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4572 bgp_session_reset(member
);
4578 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4579 const char *rmap
, struct route_map
*route_map
)
4581 struct peer
*member
;
4582 struct listnode
*node
, *nnode
;
4584 /* Set flag and configuration on peer. */
4585 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4587 if (!peer
->default_rmap
[afi
][safi
].name
4588 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4589 if (peer
->default_rmap
[afi
][safi
].name
)
4590 XFREE(MTYPE_ROUTE_MAP_NAME
,
4591 peer
->default_rmap
[afi
][safi
].name
);
4593 peer
->default_rmap
[afi
][safi
].name
=
4594 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4595 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4598 if (peer
->default_rmap
[afi
][safi
].name
)
4599 XFREE(MTYPE_ROUTE_MAP_NAME
,
4600 peer
->default_rmap
[afi
][safi
].name
);
4602 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4603 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4606 /* Check if handling a regular peer. */
4607 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4608 /* Update peer route announcements. */
4609 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4610 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4611 bgp_default_originate(peer
, afi
, safi
, 0);
4612 bgp_announce_route(peer
, afi
, safi
);
4615 /* Skip peer-group mechanics for regular peers. */
4620 * Set flag and configuration on all peer-group members, unless they are
4621 * explicitely overriding peer-group configuration.
4623 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4624 /* Skip peers with overridden configuration. */
4625 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4626 PEER_FLAG_DEFAULT_ORIGINATE
))
4629 /* Set flag and configuration on peer-group member. */
4630 SET_FLAG(member
->af_flags
[afi
][safi
],
4631 PEER_FLAG_DEFAULT_ORIGINATE
);
4633 if (member
->default_rmap
[afi
][safi
].name
)
4634 XFREE(MTYPE_ROUTE_MAP_NAME
,
4635 member
->default_rmap
[afi
][safi
].name
);
4637 member
->default_rmap
[afi
][safi
].name
=
4638 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4639 member
->default_rmap
[afi
][safi
].map
= route_map
;
4642 /* Update peer route announcements. */
4643 if (member
->status
== Established
4644 && member
->afc_nego
[afi
][safi
]) {
4645 update_group_adjust_peer(
4646 peer_af_find(member
, afi
, safi
));
4647 bgp_default_originate(member
, afi
, safi
, 0);
4648 bgp_announce_route(member
, afi
, safi
);
4655 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4657 struct peer
*member
;
4658 struct listnode
*node
, *nnode
;
4660 /* Inherit configuration from peer-group if peer is member. */
4661 if (peer_group_active(peer
)) {
4662 peer_af_flag_inherit(peer
, afi
, safi
,
4663 PEER_FLAG_DEFAULT_ORIGINATE
);
4664 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4665 default_rmap
[afi
][safi
].name
,
4666 MTYPE_ROUTE_MAP_NAME
);
4667 PEER_ATTR_INHERIT(peer
, peer
->group
,
4668 default_rmap
[afi
][safi
].map
);
4670 /* Otherwise remove flag and configuration from peer. */
4671 peer_af_flag_unset(peer
, afi
, safi
,
4672 PEER_FLAG_DEFAULT_ORIGINATE
);
4673 if (peer
->default_rmap
[afi
][safi
].name
)
4674 XFREE(MTYPE_ROUTE_MAP_NAME
,
4675 peer
->default_rmap
[afi
][safi
].name
);
4676 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4677 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4680 /* Check if handling a regular peer. */
4681 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4682 /* Update peer route announcements. */
4683 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4684 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4685 bgp_default_originate(peer
, afi
, safi
, 1);
4686 bgp_announce_route(peer
, afi
, safi
);
4689 /* Skip peer-group mechanics for regular peers. */
4694 * Remove flag and configuration from all peer-group members, unless
4695 * they are explicitely overriding peer-group configuration.
4697 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4698 /* Skip peers with overridden configuration. */
4699 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4700 PEER_FLAG_DEFAULT_ORIGINATE
))
4703 /* Remove flag and configuration on peer-group member. */
4704 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4705 PEER_FLAG_DEFAULT_ORIGINATE
);
4706 if (peer
->default_rmap
[afi
][safi
].name
)
4707 XFREE(MTYPE_ROUTE_MAP_NAME
,
4708 peer
->default_rmap
[afi
][safi
].name
);
4709 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4710 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4712 /* Update peer route announcements. */
4713 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4714 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4715 bgp_default_originate(peer
, afi
, safi
, 1);
4716 bgp_announce_route(peer
, afi
, safi
);
4723 int peer_port_set(struct peer
*peer
, uint16_t port
)
4729 int peer_port_unset(struct peer
*peer
)
4731 peer
->port
= BGP_PORT_DEFAULT
;
4736 * Helper function that is called after the name of the policy
4737 * being used by a peer has changed (AF specific). Automatically
4738 * initiates inbound or outbound processing as needed.
4740 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4744 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4745 if (peer
->status
== Established
)
4746 bgp_announce_route(peer
, afi
, safi
);
4748 if (peer
->status
!= Established
)
4751 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4752 PEER_FLAG_SOFT_RECONFIG
))
4753 bgp_soft_reconfig_in(peer
, afi
, safi
);
4754 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4755 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4756 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4761 /* neighbor weight. */
4762 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4764 struct peer
*member
;
4765 struct listnode
*node
, *nnode
;
4767 /* Set flag and configuration on peer. */
4768 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4769 if (peer
->weight
[afi
][safi
] != weight
) {
4770 peer
->weight
[afi
][safi
] = weight
;
4771 peer_on_policy_change(peer
, afi
, safi
, 0);
4774 /* Skip peer-group mechanics for regular peers. */
4775 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4779 * Set flag and configuration on all peer-group members, unless they are
4780 * explicitely overriding peer-group configuration.
4782 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4783 /* Skip peers with overridden configuration. */
4784 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4788 /* Set flag and configuration on peer-group member. */
4789 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4790 if (member
->weight
[afi
][safi
] != weight
) {
4791 member
->weight
[afi
][safi
] = weight
;
4792 peer_on_policy_change(member
, afi
, safi
, 0);
4799 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4801 struct peer
*member
;
4802 struct listnode
*node
, *nnode
;
4804 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4807 /* Inherit configuration from peer-group if peer is member. */
4808 if (peer_group_active(peer
)) {
4809 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4810 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4812 peer_on_policy_change(peer
, afi
, safi
, 0);
4816 /* Remove flag and configuration from peer. */
4817 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4818 peer
->weight
[afi
][safi
] = 0;
4819 peer_on_policy_change(peer
, afi
, safi
, 0);
4821 /* Skip peer-group mechanics for regular peers. */
4822 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4826 * Remove flag and configuration from all peer-group members, unless
4827 * they are explicitely overriding peer-group configuration.
4829 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4830 /* Skip peers with overridden configuration. */
4831 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4835 /* Skip peers where flag is already disabled. */
4836 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4839 /* Remove flag and configuration on peer-group member. */
4840 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4841 member
->weight
[afi
][safi
] = 0;
4842 peer_on_policy_change(member
, afi
, safi
, 0);
4848 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4850 struct peer
*member
;
4851 struct listnode
*node
, *nnode
;
4853 if (keepalive
> 65535)
4854 return BGP_ERR_INVALID_VALUE
;
4856 if (holdtime
> 65535)
4857 return BGP_ERR_INVALID_VALUE
;
4859 if (holdtime
< 3 && holdtime
!= 0)
4860 return BGP_ERR_INVALID_VALUE
;
4862 /* Set flag and configuration on peer. */
4863 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4864 peer
->holdtime
= holdtime
;
4865 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4867 /* Skip peer-group mechanics for regular peers. */
4868 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4872 * Set flag and configuration on all peer-group members, unless they are
4873 * explicitely overriding peer-group configuration.
4875 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4876 /* Skip peers with overridden configuration. */
4877 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4880 /* Set flag and configuration on peer-group member. */
4881 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4882 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4883 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4889 int peer_timers_unset(struct peer
*peer
)
4891 struct peer
*member
;
4892 struct listnode
*node
, *nnode
;
4894 /* Inherit configuration from peer-group if peer is member. */
4895 if (peer_group_active(peer
)) {
4896 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4897 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4898 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4900 /* Otherwise remove flag and configuration from peer. */
4901 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4903 peer
->keepalive
= 0;
4906 /* Skip peer-group mechanics for regular peers. */
4907 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4911 * Remove flag and configuration from all peer-group members, unless
4912 * they are explicitely overriding peer-group configuration.
4914 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4915 /* Skip peers with overridden configuration. */
4916 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4919 /* Remove flag and configuration on peer-group member. */
4920 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4921 member
->holdtime
= 0;
4922 member
->keepalive
= 0;
4928 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4930 struct peer
*member
;
4931 struct listnode
*node
, *nnode
;
4933 if (connect
> 65535)
4934 return BGP_ERR_INVALID_VALUE
;
4936 /* Set flag and configuration on peer. */
4937 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4938 peer
->connect
= connect
;
4939 peer
->v_connect
= connect
;
4941 /* Skip peer-group mechanics for regular peers. */
4942 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4946 * Set flag and configuration on all peer-group members, unless they are
4947 * explicitely overriding peer-group configuration.
4949 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4950 /* Skip peers with overridden configuration. */
4951 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4954 /* Set flag and configuration on peer-group member. */
4955 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4956 member
->connect
= connect
;
4957 member
->v_connect
= connect
;
4963 int peer_timers_connect_unset(struct peer
*peer
)
4965 struct peer
*member
;
4966 struct listnode
*node
, *nnode
;
4968 /* Inherit configuration from peer-group if peer is member. */
4969 if (peer_group_active(peer
)) {
4970 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4971 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4973 /* Otherwise remove flag and configuration from peer. */
4974 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4978 /* Set timer with fallback to default value. */
4980 peer
->v_connect
= peer
->connect
;
4982 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4984 /* Skip peer-group mechanics for regular peers. */
4985 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4989 * Remove flag and configuration from all peer-group members, unless
4990 * they are explicitely overriding peer-group configuration.
4992 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4993 /* Skip peers with overridden configuration. */
4994 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4997 /* Remove flag and configuration on peer-group member. */
4998 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4999 member
->connect
= 0;
5000 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5006 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5008 struct peer
*member
;
5009 struct listnode
*node
, *nnode
;
5012 return BGP_ERR_INVALID_VALUE
;
5014 /* Set flag and configuration on peer. */
5015 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5016 peer
->routeadv
= routeadv
;
5017 peer
->v_routeadv
= routeadv
;
5019 /* Check if handling a regular peer. */
5020 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5021 /* Update peer route announcements. */
5022 update_group_adjust_peer_afs(peer
);
5023 if (peer
->status
== Established
)
5024 bgp_announce_route_all(peer
);
5026 /* Skip peer-group mechanics for regular peers. */
5031 * Set flag and configuration on all peer-group members, unless they are
5032 * explicitely overriding peer-group configuration.
5034 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5035 /* Skip peers with overridden configuration. */
5036 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5039 /* Set flag and configuration on peer-group member. */
5040 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5041 member
->routeadv
= routeadv
;
5042 member
->v_routeadv
= routeadv
;
5044 /* Update peer route announcements. */
5045 update_group_adjust_peer_afs(member
);
5046 if (member
->status
== Established
)
5047 bgp_announce_route_all(member
);
5053 int peer_advertise_interval_unset(struct peer
*peer
)
5055 struct peer
*member
;
5056 struct listnode
*node
, *nnode
;
5058 /* Inherit configuration from peer-group if peer is member. */
5059 if (peer_group_active(peer
)) {
5060 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5061 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5063 /* Otherwise remove flag and configuration from peer. */
5064 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5068 /* Set timer with fallback to default value. */
5070 peer
->v_routeadv
= peer
->routeadv
;
5072 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5073 ? BGP_DEFAULT_IBGP_ROUTEADV
5074 : BGP_DEFAULT_EBGP_ROUTEADV
;
5076 /* Check if handling a regular peer. */
5077 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5078 /* Update peer route announcements. */
5079 update_group_adjust_peer_afs(peer
);
5080 if (peer
->status
== Established
)
5081 bgp_announce_route_all(peer
);
5083 /* Skip peer-group mechanics for regular peers. */
5088 * Remove flag and configuration from all peer-group members, unless
5089 * they are explicitely overriding peer-group configuration.
5091 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5092 /* Skip peers with overridden configuration. */
5093 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5096 /* Remove flag and configuration on peer-group member. */
5097 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5098 member
->routeadv
= 0;
5099 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5100 ? BGP_DEFAULT_IBGP_ROUTEADV
5101 : BGP_DEFAULT_EBGP_ROUTEADV
;
5103 /* Update peer route announcements. */
5104 update_group_adjust_peer_afs(member
);
5105 if (member
->status
== Established
)
5106 bgp_announce_route_all(member
);
5112 /* neighbor interface */
5113 void peer_interface_set(struct peer
*peer
, const char *str
)
5116 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5117 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5120 void peer_interface_unset(struct peer
*peer
)
5123 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5124 peer
->ifname
= NULL
;
5128 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5129 int allow_num
, int origin
)
5131 struct peer
*member
;
5132 struct listnode
*node
, *nnode
;
5134 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5135 return BGP_ERR_INVALID_VALUE
;
5137 /* Set flag and configuration on peer. */
5138 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5140 if (peer
->allowas_in
[afi
][safi
] != 0
5141 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5142 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5143 peer_af_flag_set(peer
, afi
, safi
,
5144 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5145 peer
->allowas_in
[afi
][safi
] = 0;
5146 peer_on_policy_change(peer
, afi
, safi
, 0);
5149 if (peer
->allowas_in
[afi
][safi
] != allow_num
5150 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5151 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5153 peer_af_flag_unset(peer
, afi
, safi
,
5154 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5155 peer
->allowas_in
[afi
][safi
] = allow_num
;
5156 peer_on_policy_change(peer
, afi
, safi
, 0);
5160 /* Skip peer-group mechanics for regular peers. */
5161 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5165 * Set flag and configuration on all peer-group members, unless
5166 * they are explicitely overriding peer-group configuration.
5168 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5169 /* Skip peers with overridden configuration. */
5170 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5171 PEER_FLAG_ALLOWAS_IN
))
5174 /* Set flag and configuration on peer-group member. */
5175 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5177 if (member
->allowas_in
[afi
][safi
] != 0
5178 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5179 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5180 SET_FLAG(member
->af_flags
[afi
][safi
],
5181 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5182 member
->allowas_in
[afi
][safi
] = 0;
5183 peer_on_policy_change(peer
, afi
, safi
, 0);
5186 if (member
->allowas_in
[afi
][safi
] != allow_num
5187 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5188 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5189 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5190 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5191 member
->allowas_in
[afi
][safi
] = allow_num
;
5192 peer_on_policy_change(peer
, afi
, safi
, 0);
5200 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5202 struct peer
*member
;
5203 struct listnode
*node
, *nnode
;
5205 /* Skip peer if flag is already disabled. */
5206 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5209 /* Inherit configuration from peer-group if peer is member. */
5210 if (peer_group_active(peer
)) {
5211 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5212 peer_af_flag_inherit(peer
, afi
, safi
,
5213 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5214 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5215 peer_on_policy_change(peer
, afi
, safi
, 0);
5220 /* Remove flag and configuration from peer. */
5221 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5222 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5223 peer
->allowas_in
[afi
][safi
] = 0;
5224 peer_on_policy_change(peer
, afi
, safi
, 0);
5226 /* Skip peer-group mechanics if handling a regular peer. */
5227 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5231 * Remove flags and configuration from all peer-group members, unless
5232 * they are explicitely overriding peer-group configuration.
5234 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5235 /* Skip peers with overridden configuration. */
5236 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5237 PEER_FLAG_ALLOWAS_IN
))
5240 /* Skip peers where flag is already disabled. */
5241 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5242 PEER_FLAG_ALLOWAS_IN
))
5245 /* Remove flags and configuration on peer-group member. */
5246 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5247 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5248 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5249 member
->allowas_in
[afi
][safi
] = 0;
5250 peer_on_policy_change(member
, afi
, safi
, 0);
5256 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5259 bool old_no_prepend
, old_replace_as
;
5260 struct bgp
*bgp
= peer
->bgp
;
5261 struct peer
*member
;
5262 struct listnode
*node
, *nnode
;
5264 if (peer_sort(peer
) != BGP_PEER_EBGP
5265 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5266 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5269 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5272 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5274 /* Save previous flag states. */
5276 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5278 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5280 /* Set flag and configuration on peer. */
5281 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5282 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5283 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5285 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5286 && old_replace_as
== replace_as
)
5288 peer
->change_local_as
= as
;
5290 /* Check if handling a regular peer. */
5291 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5292 /* Send notification or reset peer depending on state. */
5293 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5294 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5295 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5296 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5298 bgp_session_reset(peer
);
5300 /* Skip peer-group mechanics for regular peers. */
5305 * Set flag and configuration on all peer-group members, unless they are
5306 * explicitely overriding peer-group configuration.
5308 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5309 /* Skip peers with overridden configuration. */
5310 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5313 /* Skip peers with the same configuration. */
5314 old_no_prepend
= CHECK_FLAG(member
->flags
,
5315 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5316 old_replace_as
= CHECK_FLAG(member
->flags
,
5317 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5318 if (member
->change_local_as
== as
5319 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5320 && old_no_prepend
== no_prepend
5321 && old_replace_as
== replace_as
)
5324 /* Set flag and configuration on peer-group member. */
5325 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5326 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5328 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5330 member
->change_local_as
= as
;
5332 /* Send notification or stop peer depending on state. */
5333 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5334 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5335 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5336 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5338 BGP_EVENT_ADD(member
, BGP_Stop
);
5344 int peer_local_as_unset(struct peer
*peer
)
5346 struct peer
*member
;
5347 struct listnode
*node
, *nnode
;
5349 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5352 /* Inherit configuration from peer-group if peer is member. */
5353 if (peer_group_active(peer
)) {
5354 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5355 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5356 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5357 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5359 /* Otherwise remove flag and configuration from peer. */
5360 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5361 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5362 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5363 peer
->change_local_as
= 0;
5366 /* Check if handling a regular peer. */
5367 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5368 /* Send notification or stop peer depending on state. */
5369 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5370 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5371 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5372 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5374 BGP_EVENT_ADD(peer
, BGP_Stop
);
5376 /* Skip peer-group mechanics for regular peers. */
5381 * Remove flag and configuration from all peer-group members, unless
5382 * they are explicitely overriding peer-group configuration.
5384 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5385 /* Skip peers with overridden configuration. */
5386 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5389 /* Remove flag and configuration on peer-group member. */
5390 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5391 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5392 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5393 member
->change_local_as
= 0;
5395 /* Send notification or stop peer depending on state. */
5396 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5397 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5398 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5399 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5401 bgp_session_reset(member
);
5407 /* Set password for authenticating with the peer. */
5408 int peer_password_set(struct peer
*peer
, const char *password
)
5410 struct peer
*member
;
5411 struct listnode
*node
, *nnode
;
5412 int len
= password
? strlen(password
) : 0;
5413 int ret
= BGP_SUCCESS
;
5415 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5416 return BGP_ERR_INVALID_VALUE
;
5418 /* Set flag and configuration on peer. */
5419 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5420 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5422 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5423 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5425 /* Check if handling a regular peer. */
5426 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5427 /* Send notification or reset peer depending on state. */
5428 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5429 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5430 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5432 bgp_session_reset(peer
);
5435 * Attempt to install password on socket and skip peer-group
5438 if (BGP_PEER_SU_UNSPEC(peer
))
5440 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5441 : BGP_ERR_TCPSIG_FAILED
;
5445 * Set flag and configuration on all peer-group members, unless they are
5446 * explicitely overriding peer-group configuration.
5448 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5449 /* Skip peers with overridden configuration. */
5450 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5453 /* Skip peers with the same password. */
5454 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5457 /* Set flag and configuration on peer-group member. */
5458 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5459 if (member
->password
)
5460 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5461 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5463 /* Send notification or reset peer depending on state. */
5464 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5465 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5466 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5468 bgp_session_reset(member
);
5470 /* Attempt to install password on socket. */
5471 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5472 ret
= BGP_ERR_TCPSIG_FAILED
;
5478 int peer_password_unset(struct peer
*peer
)
5480 struct peer
*member
;
5481 struct listnode
*node
, *nnode
;
5483 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5486 /* Inherit configuration from peer-group if peer is member. */
5487 if (peer_group_active(peer
)) {
5488 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5489 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5490 MTYPE_PEER_PASSWORD
);
5492 /* Otherwise remove flag and configuration from peer. */
5493 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5494 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5497 /* Check if handling a regular peer. */
5498 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5499 /* Send notification or reset peer depending on state. */
5500 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5501 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5502 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5504 bgp_session_reset(peer
);
5506 /* Attempt to uninstall password on socket. */
5507 if (!BGP_PEER_SU_UNSPEC(peer
))
5508 bgp_md5_unset(peer
);
5510 /* Skip peer-group mechanics for regular peers. */
5515 * Remove flag and configuration from all peer-group members, unless
5516 * they are explicitely overriding peer-group configuration.
5518 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5519 /* Skip peers with overridden configuration. */
5520 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5523 /* Remove flag and configuration on peer-group member. */
5524 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5525 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5527 /* Send notification or reset peer depending on state. */
5528 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5529 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5530 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5532 bgp_session_reset(member
);
5534 /* Attempt to uninstall password on socket. */
5535 if (!BGP_PEER_SU_UNSPEC(member
))
5536 bgp_md5_unset(member
);
5543 /* Set distribute list to the peer. */
5544 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5547 struct peer
*member
;
5548 struct bgp_filter
*filter
;
5549 struct listnode
*node
, *nnode
;
5551 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5552 return BGP_ERR_INVALID_VALUE
;
5554 /* Set configuration on peer. */
5555 filter
= &peer
->filter
[afi
][safi
];
5556 if (filter
->plist
[direct
].name
)
5557 return BGP_ERR_PEER_FILTER_CONFLICT
;
5558 if (filter
->dlist
[direct
].name
)
5559 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5560 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5561 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5563 /* Check if handling a regular peer. */
5564 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5565 /* Set override-flag and process peer route updates. */
5566 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5567 PEER_FT_DISTRIBUTE_LIST
);
5568 peer_on_policy_change(peer
, afi
, safi
,
5569 (direct
== FILTER_OUT
) ? 1 : 0);
5571 /* Skip peer-group mechanics for regular peers. */
5576 * Set configuration on all peer-group members, un less they are
5577 * explicitely overriding peer-group configuration.
5579 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5580 /* Skip peers with overridden configuration. */
5581 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5582 PEER_FT_DISTRIBUTE_LIST
))
5585 /* Set configuration on peer-group member. */
5586 filter
= &member
->filter
[afi
][safi
];
5587 if (filter
->dlist
[direct
].name
)
5588 XFREE(MTYPE_BGP_FILTER_NAME
,
5589 filter
->dlist
[direct
].name
);
5590 filter
->dlist
[direct
].name
=
5591 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5592 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5594 /* Process peer route updates. */
5595 peer_on_policy_change(member
, afi
, safi
,
5596 (direct
== FILTER_OUT
) ? 1 : 0);
5602 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5604 struct peer
*member
;
5605 struct bgp_filter
*filter
;
5606 struct listnode
*node
, *nnode
;
5608 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5609 return BGP_ERR_INVALID_VALUE
;
5611 /* Unset override-flag unconditionally. */
5612 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5613 PEER_FT_DISTRIBUTE_LIST
);
5615 /* Inherit configuration from peer-group if peer is member. */
5616 if (peer_group_active(peer
)) {
5617 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5618 filter
[afi
][safi
].dlist
[direct
].name
,
5619 MTYPE_BGP_FILTER_NAME
);
5620 PEER_ATTR_INHERIT(peer
, peer
->group
,
5621 filter
[afi
][safi
].dlist
[direct
].alist
);
5623 /* Otherwise remove configuration from peer. */
5624 filter
= &peer
->filter
[afi
][safi
];
5625 if (filter
->dlist
[direct
].name
)
5626 XFREE(MTYPE_BGP_FILTER_NAME
,
5627 filter
->dlist
[direct
].name
);
5628 filter
->dlist
[direct
].name
= NULL
;
5629 filter
->dlist
[direct
].alist
= NULL
;
5632 /* Check if handling a regular peer. */
5633 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5634 /* Process peer route updates. */
5635 peer_on_policy_change(peer
, afi
, safi
,
5636 (direct
== FILTER_OUT
) ? 1 : 0);
5638 /* Skip peer-group mechanics for regular peers. */
5643 * Remove configuration on all peer-group members, unless they are
5644 * explicitely overriding peer-group configuration.
5646 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5647 /* Skip peers with overridden configuration. */
5648 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5649 PEER_FT_DISTRIBUTE_LIST
))
5652 /* Remove configuration on peer-group member. */
5653 filter
= &member
->filter
[afi
][safi
];
5654 if (filter
->dlist
[direct
].name
)
5655 XFREE(MTYPE_BGP_FILTER_NAME
,
5656 filter
->dlist
[direct
].name
);
5657 filter
->dlist
[direct
].name
= NULL
;
5658 filter
->dlist
[direct
].alist
= NULL
;
5660 /* Process peer route updates. */
5661 peer_on_policy_change(member
, afi
, safi
,
5662 (direct
== FILTER_OUT
) ? 1 : 0);
5668 /* Update distribute list. */
5669 static void peer_distribute_update(struct access_list
*access
)
5674 struct listnode
*mnode
, *mnnode
;
5675 struct listnode
*node
, *nnode
;
5678 struct peer_group
*group
;
5679 struct bgp_filter
*filter
;
5681 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5683 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5684 access
->name
, 0, 0);
5685 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5686 FOREACH_AFI_SAFI (afi
, safi
) {
5687 filter
= &peer
->filter
[afi
][safi
];
5689 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5691 if (filter
->dlist
[direct
].name
)
5692 filter
->dlist
[direct
]
5693 .alist
= access_list_lookup(
5695 filter
->dlist
[direct
]
5698 filter
->dlist
[direct
].alist
=
5703 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5704 FOREACH_AFI_SAFI (afi
, safi
) {
5705 filter
= &group
->conf
->filter
[afi
][safi
];
5707 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5709 if (filter
->dlist
[direct
].name
)
5710 filter
->dlist
[direct
]
5711 .alist
= access_list_lookup(
5713 filter
->dlist
[direct
]
5716 filter
->dlist
[direct
].alist
=
5722 vnc_prefix_list_update(bgp
);
5727 /* Set prefix list to the peer. */
5728 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5731 struct peer
*member
;
5732 struct bgp_filter
*filter
;
5733 struct listnode
*node
, *nnode
;
5735 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5736 return BGP_ERR_INVALID_VALUE
;
5738 /* Set configuration on peer. */
5739 filter
= &peer
->filter
[afi
][safi
];
5740 if (filter
->dlist
[direct
].name
)
5741 return BGP_ERR_PEER_FILTER_CONFLICT
;
5742 if (filter
->plist
[direct
].name
)
5743 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5744 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5745 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5747 /* Check if handling a regular peer. */
5748 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5749 /* Set override-flag and process peer route updates. */
5750 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5751 PEER_FT_PREFIX_LIST
);
5752 peer_on_policy_change(peer
, afi
, safi
,
5753 (direct
== FILTER_OUT
) ? 1 : 0);
5755 /* Skip peer-group mechanics for regular peers. */
5760 * Set configuration on all peer-group members, unless they are
5761 * explicitely overriding peer-group configuration.
5763 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5764 /* Skip peers with overridden configuration. */
5765 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5766 PEER_FT_PREFIX_LIST
))
5769 /* Set configuration on peer-group member. */
5770 filter
= &member
->filter
[afi
][safi
];
5771 if (filter
->plist
[direct
].name
)
5772 XFREE(MTYPE_BGP_FILTER_NAME
,
5773 filter
->plist
[direct
].name
);
5774 filter
->plist
[direct
].name
=
5775 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5776 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5778 /* Process peer route updates. */
5779 peer_on_policy_change(member
, afi
, safi
,
5780 (direct
== FILTER_OUT
) ? 1 : 0);
5786 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5789 struct peer
*member
;
5790 struct bgp_filter
*filter
;
5791 struct listnode
*node
, *nnode
;
5793 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5794 return BGP_ERR_INVALID_VALUE
;
5796 /* Unset override-flag unconditionally. */
5797 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5798 PEER_FT_PREFIX_LIST
);
5800 /* Inherit configuration from peer-group if peer is member. */
5801 if (peer_group_active(peer
)) {
5802 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5803 filter
[afi
][safi
].plist
[direct
].name
,
5804 MTYPE_BGP_FILTER_NAME
);
5805 PEER_ATTR_INHERIT(peer
, peer
->group
,
5806 filter
[afi
][safi
].plist
[direct
].plist
);
5808 /* Otherwise remove configuration from peer. */
5809 filter
= &peer
->filter
[afi
][safi
];
5810 if (filter
->plist
[direct
].name
)
5811 XFREE(MTYPE_BGP_FILTER_NAME
,
5812 filter
->plist
[direct
].name
);
5813 filter
->plist
[direct
].name
= NULL
;
5814 filter
->plist
[direct
].plist
= NULL
;
5817 /* Check if handling a regular peer. */
5818 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5819 /* Process peer route updates. */
5820 peer_on_policy_change(peer
, afi
, safi
,
5821 (direct
== FILTER_OUT
) ? 1 : 0);
5823 /* Skip peer-group mechanics for regular peers. */
5828 * Remove configuration on all peer-group members, unless they are
5829 * explicitely overriding peer-group configuration.
5831 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5832 /* Skip peers with overridden configuration. */
5833 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5834 PEER_FT_PREFIX_LIST
))
5837 /* Remove configuration on peer-group member. */
5838 filter
= &member
->filter
[afi
][safi
];
5839 if (filter
->plist
[direct
].name
)
5840 XFREE(MTYPE_BGP_FILTER_NAME
,
5841 filter
->plist
[direct
].name
);
5842 filter
->plist
[direct
].name
= NULL
;
5843 filter
->plist
[direct
].plist
= NULL
;
5845 /* Process peer route updates. */
5846 peer_on_policy_change(member
, afi
, safi
,
5847 (direct
== FILTER_OUT
) ? 1 : 0);
5853 /* Update prefix-list list. */
5854 static void peer_prefix_list_update(struct prefix_list
*plist
)
5856 struct listnode
*mnode
, *mnnode
;
5857 struct listnode
*node
, *nnode
;
5860 struct peer_group
*group
;
5861 struct bgp_filter
*filter
;
5866 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5869 * Update the prefix-list on update groups.
5871 update_group_policy_update(
5872 bgp
, BGP_POLICY_PREFIX_LIST
,
5873 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5875 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5876 FOREACH_AFI_SAFI (afi
, safi
) {
5877 filter
= &peer
->filter
[afi
][safi
];
5879 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5881 if (filter
->plist
[direct
].name
)
5882 filter
->plist
[direct
]
5883 .plist
= prefix_list_lookup(
5885 filter
->plist
[direct
]
5888 filter
->plist
[direct
].plist
=
5893 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5894 FOREACH_AFI_SAFI (afi
, safi
) {
5895 filter
= &group
->conf
->filter
[afi
][safi
];
5897 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5899 if (filter
->plist
[direct
].name
)
5900 filter
->plist
[direct
]
5901 .plist
= prefix_list_lookup(
5903 filter
->plist
[direct
]
5906 filter
->plist
[direct
].plist
=
5914 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5917 struct peer
*member
;
5918 struct bgp_filter
*filter
;
5919 struct listnode
*node
, *nnode
;
5921 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5922 return BGP_ERR_INVALID_VALUE
;
5924 /* Set configuration on peer. */
5925 filter
= &peer
->filter
[afi
][safi
];
5926 if (filter
->aslist
[direct
].name
)
5927 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5928 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5929 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5931 /* Check if handling a regular peer. */
5932 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5933 /* Set override-flag and process peer route updates. */
5934 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5935 PEER_FT_FILTER_LIST
);
5936 peer_on_policy_change(peer
, afi
, safi
,
5937 (direct
== FILTER_OUT
) ? 1 : 0);
5939 /* Skip peer-group mechanics for regular peers. */
5944 * Set configuration on all peer-group members, unless they are
5945 * explicitely overriding peer-group configuration.
5947 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5948 /* Skip peers with overridden configuration. */
5949 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5950 PEER_FT_FILTER_LIST
))
5953 /* Set configuration on peer-group member. */
5954 filter
= &member
->filter
[afi
][safi
];
5955 if (filter
->aslist
[direct
].name
)
5956 XFREE(MTYPE_BGP_FILTER_NAME
,
5957 filter
->aslist
[direct
].name
);
5958 filter
->aslist
[direct
].name
=
5959 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5960 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5962 /* Process peer route updates. */
5963 peer_on_policy_change(member
, afi
, safi
,
5964 (direct
== FILTER_OUT
) ? 1 : 0);
5970 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5972 struct peer
*member
;
5973 struct bgp_filter
*filter
;
5974 struct listnode
*node
, *nnode
;
5976 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5977 return BGP_ERR_INVALID_VALUE
;
5979 /* Unset override-flag unconditionally. */
5980 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5981 PEER_FT_FILTER_LIST
);
5983 /* Inherit configuration from peer-group if peer is member. */
5984 if (peer_group_active(peer
)) {
5985 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5986 filter
[afi
][safi
].aslist
[direct
].name
,
5987 MTYPE_BGP_FILTER_NAME
);
5988 PEER_ATTR_INHERIT(peer
, peer
->group
,
5989 filter
[afi
][safi
].aslist
[direct
].aslist
);
5991 /* Otherwise remove configuration from peer. */
5992 filter
= &peer
->filter
[afi
][safi
];
5993 if (filter
->aslist
[direct
].name
)
5994 XFREE(MTYPE_BGP_FILTER_NAME
,
5995 filter
->aslist
[direct
].name
);
5996 filter
->aslist
[direct
].name
= NULL
;
5997 filter
->aslist
[direct
].aslist
= NULL
;
6000 /* Check if handling a regular peer. */
6001 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6002 /* Process peer route updates. */
6003 peer_on_policy_change(peer
, afi
, safi
,
6004 (direct
== FILTER_OUT
) ? 1 : 0);
6006 /* Skip peer-group mechanics for regular peers. */
6011 * Remove configuration on all peer-group members, unless they are
6012 * explicitely overriding peer-group configuration.
6014 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6015 /* Skip peers with overridden configuration. */
6016 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6017 PEER_FT_FILTER_LIST
))
6020 /* Remove configuration on peer-group member. */
6021 filter
= &member
->filter
[afi
][safi
];
6022 if (filter
->aslist
[direct
].name
)
6023 XFREE(MTYPE_BGP_FILTER_NAME
,
6024 filter
->aslist
[direct
].name
);
6025 filter
->aslist
[direct
].name
= NULL
;
6026 filter
->aslist
[direct
].aslist
= NULL
;
6028 /* Process peer route updates. */
6029 peer_on_policy_change(member
, afi
, safi
,
6030 (direct
== FILTER_OUT
) ? 1 : 0);
6036 static void peer_aslist_update(const char *aslist_name
)
6041 struct listnode
*mnode
, *mnnode
;
6042 struct listnode
*node
, *nnode
;
6045 struct peer_group
*group
;
6046 struct bgp_filter
*filter
;
6048 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6049 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6052 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6053 FOREACH_AFI_SAFI (afi
, safi
) {
6054 filter
= &peer
->filter
[afi
][safi
];
6056 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6058 if (filter
->aslist
[direct
].name
)
6059 filter
->aslist
[direct
]
6060 .aslist
= as_list_lookup(
6061 filter
->aslist
[direct
]
6064 filter
->aslist
[direct
].aslist
=
6069 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6070 FOREACH_AFI_SAFI (afi
, safi
) {
6071 filter
= &group
->conf
->filter
[afi
][safi
];
6073 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6075 if (filter
->aslist
[direct
].name
)
6076 filter
->aslist
[direct
]
6077 .aslist
= as_list_lookup(
6078 filter
->aslist
[direct
]
6081 filter
->aslist
[direct
].aslist
=
6089 static void peer_aslist_add(char *aslist_name
)
6091 peer_aslist_update(aslist_name
);
6092 route_map_notify_dependencies((char *)aslist_name
,
6093 RMAP_EVENT_ASLIST_ADDED
);
6096 static void peer_aslist_del(const char *aslist_name
)
6098 peer_aslist_update(aslist_name
);
6099 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6103 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6104 const char *name
, struct route_map
*route_map
)
6106 struct peer
*member
;
6107 struct bgp_filter
*filter
;
6108 struct listnode
*node
, *nnode
;
6110 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6111 return BGP_ERR_INVALID_VALUE
;
6113 /* Set configuration on peer. */
6114 filter
= &peer
->filter
[afi
][safi
];
6115 if (filter
->map
[direct
].name
)
6116 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6117 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6118 filter
->map
[direct
].map
= route_map
;
6120 /* Check if handling a regular peer. */
6121 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6122 /* Set override-flag and process peer route updates. */
6123 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6125 peer_on_policy_change(peer
, afi
, safi
,
6126 (direct
== RMAP_OUT
) ? 1 : 0);
6128 /* Skip peer-group mechanics for regular peers. */
6133 * Set configuration on all peer-group members, unless they are
6134 * explicitely overriding peer-group configuration.
6136 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6137 /* Skip peers with overridden configuration. */
6138 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6142 /* Set configuration on peer-group member. */
6143 filter
= &member
->filter
[afi
][safi
];
6144 if (filter
->map
[direct
].name
)
6145 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6146 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6147 filter
->map
[direct
].map
= route_map
;
6149 /* Process peer route updates. */
6150 peer_on_policy_change(member
, afi
, safi
,
6151 (direct
== RMAP_OUT
) ? 1 : 0);
6156 /* Unset route-map from the peer. */
6157 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6159 struct peer
*member
;
6160 struct bgp_filter
*filter
;
6161 struct listnode
*node
, *nnode
;
6163 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6164 return BGP_ERR_INVALID_VALUE
;
6166 /* Unset override-flag unconditionally. */
6167 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6169 /* Inherit configuration from peer-group if peer is member. */
6170 if (peer_group_active(peer
)) {
6171 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6172 filter
[afi
][safi
].map
[direct
].name
,
6173 MTYPE_BGP_FILTER_NAME
);
6174 PEER_ATTR_INHERIT(peer
, peer
->group
,
6175 filter
[afi
][safi
].map
[direct
].map
);
6177 /* Otherwise remove configuration from peer. */
6178 filter
= &peer
->filter
[afi
][safi
];
6179 if (filter
->map
[direct
].name
)
6180 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6181 filter
->map
[direct
].name
= NULL
;
6182 filter
->map
[direct
].map
= NULL
;
6185 /* Check if handling a regular peer. */
6186 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6187 /* Process peer route updates. */
6188 peer_on_policy_change(peer
, afi
, safi
,
6189 (direct
== RMAP_OUT
) ? 1 : 0);
6191 /* Skip peer-group mechanics for regular peers. */
6196 * Remove configuration on all peer-group members, unless they are
6197 * explicitely overriding peer-group configuration.
6199 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6200 /* Skip peers with overridden configuration. */
6201 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6205 /* Remove configuration on peer-group member. */
6206 filter
= &member
->filter
[afi
][safi
];
6207 if (filter
->map
[direct
].name
)
6208 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6209 filter
->map
[direct
].name
= NULL
;
6210 filter
->map
[direct
].map
= NULL
;
6212 /* Process peer route updates. */
6213 peer_on_policy_change(member
, afi
, safi
,
6214 (direct
== RMAP_OUT
) ? 1 : 0);
6220 /* Set unsuppress-map to the peer. */
6221 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6222 const char *name
, struct route_map
*route_map
)
6224 struct peer
*member
;
6225 struct bgp_filter
*filter
;
6226 struct listnode
*node
, *nnode
;
6228 /* Set configuration on peer. */
6229 filter
= &peer
->filter
[afi
][safi
];
6230 if (filter
->usmap
.name
)
6231 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6232 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6233 filter
->usmap
.map
= route_map
;
6235 /* Check if handling a regular peer. */
6236 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6237 /* Set override-flag and process peer route updates. */
6238 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6239 PEER_FT_UNSUPPRESS_MAP
);
6240 peer_on_policy_change(peer
, afi
, safi
, 1);
6242 /* Skip peer-group mechanics for regular peers. */
6247 * Set configuration on all peer-group members, unless they are
6248 * explicitely overriding peer-group configuration.
6250 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6251 /* Skip peers with overridden configuration. */
6252 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6253 PEER_FT_UNSUPPRESS_MAP
))
6256 /* Set configuration on peer-group member. */
6257 filter
= &member
->filter
[afi
][safi
];
6258 if (filter
->usmap
.name
)
6259 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6260 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6261 filter
->usmap
.map
= route_map
;
6263 /* Process peer route updates. */
6264 peer_on_policy_change(member
, afi
, safi
, 1);
6270 /* Unset route-map from the peer. */
6271 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6273 struct peer
*member
;
6274 struct bgp_filter
*filter
;
6275 struct listnode
*node
, *nnode
;
6277 /* Unset override-flag unconditionally. */
6278 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6280 /* Inherit configuration from peer-group if peer is member. */
6281 if (peer_group_active(peer
)) {
6282 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6283 filter
[afi
][safi
].usmap
.name
,
6284 MTYPE_BGP_FILTER_NAME
);
6285 PEER_ATTR_INHERIT(peer
, peer
->group
,
6286 filter
[afi
][safi
].usmap
.map
);
6288 /* Otherwise remove configuration from peer. */
6289 filter
= &peer
->filter
[afi
][safi
];
6290 if (filter
->usmap
.name
)
6291 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6292 filter
->usmap
.name
= NULL
;
6293 filter
->usmap
.map
= NULL
;
6296 /* Check if handling a regular peer. */
6297 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6298 /* Process peer route updates. */
6299 peer_on_policy_change(peer
, afi
, safi
, 1);
6301 /* Skip peer-group mechanics for regular peers. */
6306 * Remove configuration on all peer-group members, unless they are
6307 * explicitely overriding peer-group configuration.
6309 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6310 /* Skip peers with overridden configuration. */
6311 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6312 PEER_FT_UNSUPPRESS_MAP
))
6315 /* Remove configuration on peer-group member. */
6316 filter
= &member
->filter
[afi
][safi
];
6317 if (filter
->usmap
.name
)
6318 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6319 filter
->usmap
.name
= NULL
;
6320 filter
->usmap
.map
= NULL
;
6322 /* Process peer route updates. */
6323 peer_on_policy_change(member
, afi
, safi
, 1);
6329 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6330 uint32_t max
, uint8_t threshold
, int warning
,
6333 struct peer
*member
;
6334 struct listnode
*node
, *nnode
;
6336 /* Set flags and configuration on peer. */
6337 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6339 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6341 peer_af_flag_unset(peer
, afi
, safi
,
6342 PEER_FLAG_MAX_PREFIX_WARNING
);
6344 peer
->pmax
[afi
][safi
] = max
;
6345 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6346 peer
->pmax_restart
[afi
][safi
] = restart
;
6348 /* Check if handling a regular peer. */
6349 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6350 /* Re-check if peer violates maximum-prefix. */
6351 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6352 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6354 /* Skip peer-group mechanics for regular peers. */
6359 * Set flags and configuration on all peer-group members, unless they
6360 * are explicitely overriding peer-group configuration.
6362 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6363 /* Skip peers with overridden configuration. */
6364 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6365 PEER_FLAG_MAX_PREFIX
))
6368 /* Set flag and configuration on peer-group member. */
6369 member
->pmax
[afi
][safi
] = max
;
6370 member
->pmax_threshold
[afi
][safi
] = threshold
;
6371 member
->pmax_restart
[afi
][safi
] = restart
;
6373 SET_FLAG(member
->af_flags
[afi
][safi
],
6374 PEER_FLAG_MAX_PREFIX_WARNING
);
6376 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6377 PEER_FLAG_MAX_PREFIX_WARNING
);
6379 /* Re-check if peer violates maximum-prefix. */
6380 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6381 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6387 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6389 /* Inherit configuration from peer-group if peer is member. */
6390 if (peer_group_active(peer
)) {
6391 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6392 peer_af_flag_inherit(peer
, afi
, safi
,
6393 PEER_FLAG_MAX_PREFIX_WARNING
);
6394 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6395 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6396 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6401 /* Remove flags and configuration from peer. */
6402 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6403 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6404 peer
->pmax
[afi
][safi
] = 0;
6405 peer
->pmax_threshold
[afi
][safi
] = 0;
6406 peer
->pmax_restart
[afi
][safi
] = 0;
6409 * Remove flags and configuration from all peer-group members, unless
6410 * they are explicitely overriding peer-group configuration.
6412 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6413 struct peer
*member
;
6414 struct listnode
*node
;
6416 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6417 /* Skip peers with overridden configuration. */
6418 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6419 PEER_FLAG_MAX_PREFIX
))
6422 /* Remove flag and configuration on peer-group member.
6424 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6425 PEER_FLAG_MAX_PREFIX
);
6426 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6427 PEER_FLAG_MAX_PREFIX_WARNING
);
6428 member
->pmax
[afi
][safi
] = 0;
6429 member
->pmax_threshold
[afi
][safi
] = 0;
6430 member
->pmax_restart
[afi
][safi
] = 0;
6437 int is_ebgp_multihop_configured(struct peer
*peer
)
6439 struct peer_group
*group
;
6440 struct listnode
*node
, *nnode
;
6443 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6444 group
= peer
->group
;
6445 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6446 && (group
->conf
->ttl
!= 1))
6449 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6450 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6451 && (peer1
->ttl
!= 1))
6455 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6461 /* Set # of hops between us and BGP peer. */
6462 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6464 struct peer_group
*group
;
6465 struct listnode
*node
, *nnode
;
6468 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6469 gtsm_hops
, peer
->host
);
6471 /* We cannot configure ttl-security hops when ebgp-multihop is already
6472 set. For non peer-groups, the check is simple. For peer-groups,
6474 slightly messy, because we need to check both the peer-group
6476 and all peer-group members for any trace of ebgp-multihop
6478 before actually applying the ttl-security rules. Cisco really made a
6479 mess of this configuration parameter, and OpenBGPD got it right.
6482 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6483 if (is_ebgp_multihop_configured(peer
))
6484 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6486 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6487 peer
->gtsm_hops
= gtsm_hops
;
6489 /* Calling ebgp multihop also resets the session.
6490 * On restart, NHT will get setup correctly as will the
6491 * min & max ttls on the socket. The return value is
6494 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6499 group
= peer
->group
;
6500 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6502 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6504 /* Calling ebgp multihop also resets the
6506 * On restart, NHT will get setup correctly as
6508 * min & max ttls on the socket. The return
6512 peer_ebgp_multihop_set(peer
, MAXTTL
);
6516 /* Post the first gtsm setup or if its ibgp, maxttl setting
6518 * necessary, just set the minttl.
6520 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6521 peer
->gtsm_hops
= gtsm_hops
;
6524 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6525 MAXTTL
+ 1 - gtsm_hops
);
6526 if ((peer
->status
< Established
) && peer
->doppelganger
6527 && (peer
->doppelganger
->fd
>= 0))
6528 sockopt_minttl(peer
->su
.sa
.sa_family
,
6529 peer
->doppelganger
->fd
,
6530 MAXTTL
+ 1 - gtsm_hops
);
6532 group
= peer
->group
;
6533 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6535 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6537 /* Change setting of existing peer
6538 * established then change value (may break
6540 * not established yet (teardown session and
6542 * no session then do nothing (will get
6543 * handled by next connection)
6545 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6547 peer
->su
.sa
.sa_family
, peer
->fd
,
6548 MAXTTL
+ 1 - peer
->gtsm_hops
);
6549 if ((peer
->status
< Established
)
6550 && peer
->doppelganger
6551 && (peer
->doppelganger
->fd
>= 0))
6552 sockopt_minttl(peer
->su
.sa
.sa_family
,
6553 peer
->doppelganger
->fd
,
6554 MAXTTL
+ 1 - gtsm_hops
);
6562 int peer_ttl_security_hops_unset(struct peer
*peer
)
6564 struct peer_group
*group
;
6565 struct listnode
*node
, *nnode
;
6568 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6571 /* if a peer-group member, then reset to peer-group default rather than
6573 if (peer_group_active(peer
))
6574 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6576 peer
->gtsm_hops
= 0;
6578 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6579 /* Invoking ebgp_multihop_set will set the TTL back to the
6581 * value as well as restting the NHT and such. The session is
6584 if (peer
->sort
== BGP_PEER_EBGP
)
6585 ret
= peer_ebgp_multihop_unset(peer
);
6588 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6591 if ((peer
->status
< Established
) && peer
->doppelganger
6592 && (peer
->doppelganger
->fd
>= 0))
6593 sockopt_minttl(peer
->su
.sa
.sa_family
,
6594 peer
->doppelganger
->fd
, 0);
6597 group
= peer
->group
;
6598 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6599 peer
->gtsm_hops
= 0;
6600 if (peer
->sort
== BGP_PEER_EBGP
)
6601 ret
= peer_ebgp_multihop_unset(peer
);
6604 sockopt_minttl(peer
->su
.sa
.sa_family
,
6607 if ((peer
->status
< Established
)
6608 && peer
->doppelganger
6609 && (peer
->doppelganger
->fd
>= 0))
6610 sockopt_minttl(peer
->su
.sa
.sa_family
,
6611 peer
->doppelganger
->fd
,
6621 * If peer clear is invoked in a loop for all peers on the BGP instance,
6622 * it may end up freeing the doppelganger, and if this was the next node
6623 * to the current node, we would end up accessing the freed next node.
6624 * Pass along additional parameter which can be updated if next node
6625 * is freed; only required when walking the peer list on BGP instance.
6627 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6629 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6630 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6631 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6632 if (peer
->t_pmax_restart
) {
6633 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6634 if (bgp_debug_neighbor_events(peer
))
6636 "%s Maximum-prefix restart timer canceled",
6639 BGP_EVENT_ADD(peer
, BGP_Start
);
6643 peer
->v_start
= BGP_INIT_START_TIMER
;
6644 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6645 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6646 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6648 bgp_session_reset_safe(peer
, nnode
);
6653 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6654 enum bgp_clear_type stype
)
6656 struct peer_af
*paf
;
6658 if (peer
->status
!= Established
)
6661 if (!peer
->afc
[afi
][safi
])
6662 return BGP_ERR_AF_UNCONFIGURED
;
6664 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6666 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6667 /* Clear the "neighbor x.x.x.x default-originate" flag */
6668 paf
= peer_af_find(peer
, afi
, safi
);
6669 if (paf
&& paf
->subgroup
6670 && CHECK_FLAG(paf
->subgroup
->sflags
,
6671 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6672 UNSET_FLAG(paf
->subgroup
->sflags
,
6673 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6675 bgp_announce_route(peer
, afi
, safi
);
6678 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6679 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6680 PEER_CAP_ORF_PREFIX_SM_ADV
)
6681 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6682 PEER_CAP_ORF_PREFIX_RM_RCV
)
6683 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6684 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6685 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6686 uint8_t prefix_type
;
6688 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6689 PEER_CAP_ORF_PREFIX_RM_RCV
))
6690 prefix_type
= ORF_TYPE_PREFIX
;
6692 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6694 if (filter
->plist
[FILTER_IN
].plist
) {
6695 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6696 PEER_STATUS_ORF_PREFIX_SEND
))
6697 bgp_route_refresh_send(
6698 peer
, afi
, safi
, prefix_type
,
6700 bgp_route_refresh_send(peer
, afi
, safi
,
6702 REFRESH_IMMEDIATE
, 0);
6704 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6705 PEER_STATUS_ORF_PREFIX_SEND
))
6706 bgp_route_refresh_send(
6707 peer
, afi
, safi
, prefix_type
,
6708 REFRESH_IMMEDIATE
, 1);
6710 bgp_route_refresh_send(peer
, afi
, safi
,
6717 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6718 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6719 /* If neighbor has soft reconfiguration inbound flag.
6720 Use Adj-RIB-In database. */
6721 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6722 PEER_FLAG_SOFT_RECONFIG
))
6723 bgp_soft_reconfig_in(peer
, afi
, safi
);
6725 /* If neighbor has route refresh capability, send route
6727 message to the peer. */
6728 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6729 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6730 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6733 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6739 /* Display peer uptime.*/
6740 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6743 time_t uptime1
, epoch_tbuf
;
6746 /* If there is no connection has been done before print `never'. */
6749 json_object_string_add(json
, "peerUptime", "never");
6750 json_object_int_add(json
, "peerUptimeMsec", 0);
6752 snprintf(buf
, len
, "never");
6756 /* Get current time. */
6757 uptime1
= bgp_clock();
6759 tm
= gmtime(&uptime1
);
6761 if (uptime1
< ONE_DAY_SECOND
)
6762 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6764 else if (uptime1
< ONE_WEEK_SECOND
)
6765 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6767 else if (uptime1
< ONE_YEAR_SECOND
)
6768 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6769 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6771 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6773 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6776 epoch_tbuf
= time(NULL
) - uptime1
;
6777 json_object_string_add(json
, "peerUptime", buf
);
6778 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6779 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6786 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6787 afi_t afi
, safi_t safi
)
6789 struct bgp_filter
*filter
;
6793 filter
= &peer
->filter
[afi
][safi
];
6795 /* distribute-list. */
6796 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6798 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6799 filter
->dlist
[FILTER_IN
].name
);
6801 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6803 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6804 filter
->dlist
[FILTER_OUT
].name
);
6807 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6809 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6810 filter
->plist
[FILTER_IN
].name
);
6812 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6814 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6815 filter
->plist
[FILTER_OUT
].name
);
6818 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6819 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6820 filter
->map
[RMAP_IN
].name
);
6822 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6824 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6825 filter
->map
[RMAP_OUT
].name
);
6827 /* unsuppress-map */
6828 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6829 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6830 filter
->usmap
.name
);
6833 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6835 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6836 filter
->aslist
[FILTER_IN
].name
);
6838 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6840 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6841 filter
->aslist
[FILTER_OUT
].name
);
6844 /* BGP peer configuration display function. */
6845 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6848 struct peer
*g_peer
= NULL
;
6849 char buf
[SU_ADDRSTRLEN
];
6851 int if_pg_printed
= FALSE
;
6852 int if_ras_printed
= FALSE
;
6854 /* Skip dynamic neighbors. */
6855 if (peer_dynamic_neighbor(peer
))
6859 addr
= peer
->conf_if
;
6863 /************************************
6864 ****** Global to the neighbor ******
6865 ************************************/
6866 if (peer
->conf_if
) {
6867 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6868 vty_out(vty
, " neighbor %s interface v6only", addr
);
6870 vty_out(vty
, " neighbor %s interface", addr
);
6872 if (peer_group_active(peer
)) {
6873 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6874 if_pg_printed
= TRUE
;
6875 } else if (peer
->as_type
== AS_SPECIFIED
) {
6876 vty_out(vty
, " remote-as %u", peer
->as
);
6877 if_ras_printed
= TRUE
;
6878 } else if (peer
->as_type
== AS_INTERNAL
) {
6879 vty_out(vty
, " remote-as internal");
6880 if_ras_printed
= TRUE
;
6881 } else if (peer
->as_type
== AS_EXTERNAL
) {
6882 vty_out(vty
, " remote-as external");
6883 if_ras_printed
= TRUE
;
6889 /* remote-as and peer-group */
6890 /* peer is a member of a peer-group */
6891 if (peer_group_active(peer
)) {
6892 g_peer
= peer
->group
->conf
;
6894 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6895 if (peer
->as_type
== AS_SPECIFIED
) {
6896 vty_out(vty
, " neighbor %s remote-as %u\n",
6898 } else if (peer
->as_type
== AS_INTERNAL
) {
6900 " neighbor %s remote-as internal\n",
6902 } else if (peer
->as_type
== AS_EXTERNAL
) {
6904 " neighbor %s remote-as external\n",
6909 /* For swpX peers we displayed the peer-group
6910 * via 'neighbor swpX interface peer-group WORD' */
6912 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6916 /* peer is NOT a member of a peer-group */
6918 /* peer is a peer-group, declare the peer-group */
6919 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6920 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6923 if (!if_ras_printed
) {
6924 if (peer
->as_type
== AS_SPECIFIED
) {
6925 vty_out(vty
, " neighbor %s remote-as %u\n",
6927 } else if (peer
->as_type
== AS_INTERNAL
) {
6929 " neighbor %s remote-as internal\n",
6931 } else if (peer
->as_type
== AS_EXTERNAL
) {
6933 " neighbor %s remote-as external\n",
6940 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6941 vty_out(vty
, " neighbor %s local-as %u", addr
,
6942 peer
->change_local_as
);
6943 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6944 vty_out(vty
, " no-prepend");
6945 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6946 vty_out(vty
, " replace-as");
6952 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6956 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6957 if (peer
->tx_shutdown_message
)
6958 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6959 peer
->tx_shutdown_message
);
6961 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6965 if (peer
->bfd_info
) {
6966 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6967 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6972 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6973 vty_out(vty
, " neighbor %s password %s\n", addr
,
6977 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6978 if (!peer_group_active(peer
)) {
6979 vty_out(vty
, " neighbor %s solo\n", addr
);
6984 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6985 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6988 /* Local interface name */
6990 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6994 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
6995 vty_out(vty
, " neighbor %s passive\n", addr
);
6998 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6999 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
7000 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
7001 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
7006 /* ttl-security hops */
7007 if (peer
->gtsm_hops
!= 0) {
7008 if (!peer_group_active(peer
)
7009 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
7010 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
7011 addr
, peer
->gtsm_hops
);
7015 /* disable-connected-check */
7016 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
7017 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
7019 /* enforce-first-as */
7020 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
7021 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
7024 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
7025 if (peer
->update_source
)
7026 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7027 sockunion2str(peer
->update_source
, buf
,
7029 else if (peer
->update_if
)
7030 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7034 /* advertisement-interval */
7035 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7036 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7040 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7041 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7042 peer
->keepalive
, peer
->holdtime
);
7044 /* timers connect */
7045 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7046 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7049 /* capability dynamic */
7050 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7051 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7053 /* capability extended-nexthop */
7054 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7055 if (!peer
->conf_if
) {
7056 if (CHECK_FLAG(peer
->flags_invert
,
7057 PEER_FLAG_CAPABILITY_ENHE
))
7059 " no neighbor %s capability extended-nexthop\n",
7063 " neighbor %s capability extended-nexthop\n",
7068 /* dont-capability-negotiation */
7069 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7070 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7072 /* override-capability */
7073 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7074 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7076 /* strict-capability-match */
7077 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7078 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7081 /* BGP peer configuration display function. */
7082 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7083 struct peer
*peer
, afi_t afi
, safi_t safi
)
7085 struct peer
*g_peer
= NULL
;
7087 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7089 /* Skip dynamic neighbors. */
7090 if (peer_dynamic_neighbor(peer
))
7094 addr
= peer
->conf_if
;
7098 /************************************
7099 ****** Per AF to the neighbor ******
7100 ************************************/
7101 if (peer_group_active(peer
)) {
7102 g_peer
= peer
->group
->conf
;
7104 /* If the peer-group is active but peer is not, print a 'no
7106 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7107 vty_out(vty
, " no neighbor %s activate\n", addr
);
7110 /* If the peer-group is not active but peer is, print an
7112 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7113 vty_out(vty
, " neighbor %s activate\n", addr
);
7116 if (peer
->afc
[afi
][safi
]) {
7117 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7118 if (bgp_flag_check(bgp
,
7119 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7120 vty_out(vty
, " neighbor %s activate\n",
7124 vty_out(vty
, " neighbor %s activate\n", addr
);
7126 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7127 if (!bgp_flag_check(bgp
,
7128 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7130 " no neighbor %s activate\n",
7137 /* addpath TX knobs */
7138 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7139 switch (peer
->addpath_type
[afi
][safi
]) {
7140 case BGP_ADDPATH_ALL
:
7141 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7144 case BGP_ADDPATH_BEST_PER_AS
:
7146 " neighbor %s addpath-tx-bestpath-per-AS\n",
7149 case BGP_ADDPATH_MAX
:
7150 case BGP_ADDPATH_NONE
:
7155 /* ORF capability. */
7156 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7157 || peergroup_af_flag_check(peer
, afi
, safi
,
7158 PEER_FLAG_ORF_PREFIX_RM
)) {
7159 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7161 if (peergroup_af_flag_check(peer
, afi
, safi
,
7162 PEER_FLAG_ORF_PREFIX_SM
)
7163 && peergroup_af_flag_check(peer
, afi
, safi
,
7164 PEER_FLAG_ORF_PREFIX_RM
))
7165 vty_out(vty
, " both");
7166 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7167 PEER_FLAG_ORF_PREFIX_SM
))
7168 vty_out(vty
, " send");
7170 vty_out(vty
, " receive");
7174 /* Route reflector client. */
7175 if (peergroup_af_flag_check(peer
, afi
, safi
,
7176 PEER_FLAG_REFLECTOR_CLIENT
)) {
7177 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7180 /* next-hop-self force */
7181 if (peergroup_af_flag_check(peer
, afi
, safi
,
7182 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7183 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7187 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7188 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7191 /* remove-private-AS */
7192 if (peergroup_af_flag_check(peer
, afi
, safi
,
7193 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7194 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7198 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7199 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7200 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7204 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7205 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7206 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7209 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7210 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7211 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7215 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7216 vty_out(vty
, " neighbor %s as-override\n", addr
);
7219 /* send-community print. */
7220 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7221 PEER_FLAG_SEND_COMMUNITY
);
7222 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7223 PEER_FLAG_SEND_EXT_COMMUNITY
);
7224 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7225 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7227 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7228 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7229 vty_out(vty
, " no neighbor %s send-community all\n",
7234 " no neighbor %s send-community\n",
7238 " no neighbor %s send-community extended\n",
7243 " no neighbor %s send-community large\n",
7247 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7248 vty_out(vty
, " neighbor %s send-community all\n",
7250 } else if (flag_scomm
&& flag_secomm
) {
7251 vty_out(vty
, " neighbor %s send-community both\n",
7255 vty_out(vty
, " neighbor %s send-community\n",
7259 " neighbor %s send-community extended\n",
7263 " neighbor %s send-community large\n",
7268 /* Default information */
7269 if (peergroup_af_flag_check(peer
, afi
, safi
,
7270 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7271 vty_out(vty
, " neighbor %s default-originate", addr
);
7273 if (peer
->default_rmap
[afi
][safi
].name
)
7274 vty_out(vty
, " route-map %s",
7275 peer
->default_rmap
[afi
][safi
].name
);
7280 /* Soft reconfiguration inbound. */
7281 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7282 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7286 /* maximum-prefix. */
7287 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7288 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7289 peer
->pmax
[afi
][safi
]);
7291 if (peer
->pmax_threshold
[afi
][safi
]
7292 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7293 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7294 if (peer_af_flag_check(peer
, afi
, safi
,
7295 PEER_FLAG_MAX_PREFIX_WARNING
))
7296 vty_out(vty
, " warning-only");
7297 if (peer
->pmax_restart
[afi
][safi
])
7298 vty_out(vty
, " restart %u",
7299 peer
->pmax_restart
[afi
][safi
]);
7304 /* Route server client. */
7305 if (peergroup_af_flag_check(peer
, afi
, safi
,
7306 PEER_FLAG_RSERVER_CLIENT
)) {
7307 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7310 /* Nexthop-local unchanged. */
7311 if (peergroup_af_flag_check(peer
, afi
, safi
,
7312 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7313 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7316 /* allowas-in <1-10> */
7317 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7318 if (peer_af_flag_check(peer
, afi
, safi
,
7319 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7320 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7321 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7322 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7324 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7325 peer
->allowas_in
[afi
][safi
]);
7330 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7331 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7332 peer
->weight
[afi
][safi
]);
7335 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7337 /* atribute-unchanged. */
7338 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7339 || (safi
!= SAFI_EVPN
7340 && peer_af_flag_check(peer
, afi
, safi
,
7341 PEER_FLAG_NEXTHOP_UNCHANGED
))
7342 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7344 if (!peer_group_active(peer
)
7345 || peergroup_af_flag_check(peer
, afi
, safi
,
7346 PEER_FLAG_AS_PATH_UNCHANGED
)
7347 || peergroup_af_flag_check(peer
, afi
, safi
,
7348 PEER_FLAG_NEXTHOP_UNCHANGED
)
7349 || peergroup_af_flag_check(peer
, afi
, safi
,
7350 PEER_FLAG_MED_UNCHANGED
)) {
7353 " neighbor %s attribute-unchanged%s%s%s\n",
7355 peer_af_flag_check(peer
, afi
, safi
,
7356 PEER_FLAG_AS_PATH_UNCHANGED
)
7359 peer_af_flag_check(peer
, afi
, safi
,
7360 PEER_FLAG_NEXTHOP_UNCHANGED
)
7363 peer_af_flag_check(peer
, afi
, safi
,
7364 PEER_FLAG_MED_UNCHANGED
)
7371 /* Address family based peer configuration display. */
7372 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7376 struct peer_group
*group
;
7377 struct listnode
*node
, *nnode
;
7380 vty_frame(vty
, " !\n address-family ");
7381 if (afi
== AFI_IP
) {
7382 if (safi
== SAFI_UNICAST
)
7383 vty_frame(vty
, "ipv4 unicast");
7384 else if (safi
== SAFI_LABELED_UNICAST
)
7385 vty_frame(vty
, "ipv4 labeled-unicast");
7386 else if (safi
== SAFI_MULTICAST
)
7387 vty_frame(vty
, "ipv4 multicast");
7388 else if (safi
== SAFI_MPLS_VPN
)
7389 vty_frame(vty
, "ipv4 vpn");
7390 else if (safi
== SAFI_ENCAP
)
7391 vty_frame(vty
, "ipv4 encap");
7392 else if (safi
== SAFI_FLOWSPEC
)
7393 vty_frame(vty
, "ipv4 flowspec");
7394 } else if (afi
== AFI_IP6
) {
7395 if (safi
== SAFI_UNICAST
)
7396 vty_frame(vty
, "ipv6 unicast");
7397 else if (safi
== SAFI_LABELED_UNICAST
)
7398 vty_frame(vty
, "ipv6 labeled-unicast");
7399 else if (safi
== SAFI_MULTICAST
)
7400 vty_frame(vty
, "ipv6 multicast");
7401 else if (safi
== SAFI_MPLS_VPN
)
7402 vty_frame(vty
, "ipv6 vpn");
7403 else if (safi
== SAFI_ENCAP
)
7404 vty_frame(vty
, "ipv6 encap");
7405 else if (safi
== SAFI_FLOWSPEC
)
7406 vty_frame(vty
, "ipv6 flowspec");
7407 } else if (afi
== AFI_L2VPN
) {
7408 if (safi
== SAFI_EVPN
)
7409 vty_frame(vty
, "l2vpn evpn");
7411 vty_frame(vty
, "\n");
7413 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7415 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7417 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7419 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7420 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7422 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7423 /* Skip dynamic neighbors. */
7424 if (peer_dynamic_neighbor(peer
))
7427 /* Do not display doppelganger peers */
7428 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7429 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7432 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7433 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7435 if (safi
== SAFI_EVPN
)
7436 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7438 if (safi
== SAFI_FLOWSPEC
)
7439 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7441 if (safi
== SAFI_UNICAST
) {
7442 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7443 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7444 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7446 vty_out(vty
, " export vpn\n");
7448 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7449 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7451 vty_out(vty
, " import vpn\n");
7453 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7454 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7457 for (ALL_LIST_ELEMENTS_RO(
7458 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7460 vty_out(vty
, " import vrf %s\n", name
);
7464 vty_endframe(vty
, " exit-address-family\n");
7467 /* clang-format off */
7468 #if CONFDATE > 20190517
7469 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7471 /* clang-format on */
7473 int bgp_config_write(struct vty
*vty
)
7477 struct peer_group
*group
;
7479 struct listnode
*node
, *nnode
;
7480 struct listnode
*mnode
, *mnnode
;
7482 /* BGP Multiple instance. */
7483 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7484 vty_out(vty
, "no bgp multiple-instance\n");
7488 /* BGP Config type. */
7489 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7490 vty_out(vty
, "bgp config-type cisco\n");
7494 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7495 vty_out(vty
, "bgp route-map delay-timer %u\n",
7496 bm
->rmap_update_timer
);
7499 vty_out(vty
, "!\n");
7501 /* BGP configuration. */
7502 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7504 /* skip all auto created vrf as they dont have user config */
7505 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7508 /* Migrate deprecated 'bgp enforce-first-as'
7509 * config to 'neighbor * enforce-first-as' configs
7511 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7512 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7513 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7514 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7517 /* Router bgp ASN */
7518 vty_out(vty
, "router bgp %u", bgp
->as
);
7520 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7522 vty_out(vty
, " %s %s",
7524 == BGP_INSTANCE_TYPE_VIEW
)
7531 /* No Synchronization */
7532 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7533 vty_out(vty
, " no synchronization\n");
7535 /* BGP fast-external-failover. */
7536 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7537 vty_out(vty
, " no bgp fast-external-failover\n");
7539 /* BGP router ID. */
7540 if (bgp
->router_id_static
.s_addr
!= 0)
7541 vty_out(vty
, " bgp router-id %s\n",
7542 inet_ntoa(bgp
->router_id_static
));
7544 /* BGP log-neighbor-changes. */
7545 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7546 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7547 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7549 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7553 /* BGP configuration. */
7554 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7555 vty_out(vty
, " bgp always-compare-med\n");
7557 /* BGP default ipv4-unicast. */
7558 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7559 vty_out(vty
, " no bgp default ipv4-unicast\n");
7561 /* BGP default local-preference. */
7562 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7563 vty_out(vty
, " bgp default local-preference %u\n",
7564 bgp
->default_local_pref
);
7566 /* BGP default show-hostname */
7567 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7568 != DFLT_BGP_SHOW_HOSTNAME
)
7569 vty_out(vty
, " %sbgp default show-hostname\n",
7570 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7574 /* BGP default subgroup-pkt-queue-max. */
7575 if (bgp
->default_subgroup_pkt_queue_max
7576 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7577 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7578 bgp
->default_subgroup_pkt_queue_max
);
7580 /* BGP client-to-client reflection. */
7581 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7582 vty_out(vty
, " no bgp client-to-client reflection\n");
7584 /* BGP cluster ID. */
7585 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7586 vty_out(vty
, " bgp cluster-id %s\n",
7587 inet_ntoa(bgp
->cluster_id
));
7589 /* Disable ebgp connected nexthop check */
7590 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7592 " bgp disable-ebgp-connected-route-check\n");
7594 /* Confederation identifier*/
7595 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7596 vty_out(vty
, " bgp confederation identifier %u\n",
7599 /* Confederation peer */
7600 if (bgp
->confed_peers_cnt
> 0) {
7603 vty_out(vty
, " bgp confederation peers");
7605 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7606 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7611 /* BGP deterministic-med. */
7612 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7613 != DFLT_BGP_DETERMINISTIC_MED
)
7614 vty_out(vty
, " %sbgp deterministic-med\n",
7615 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7619 /* BGP update-delay. */
7620 bgp_config_write_update_delay(vty
, bgp
);
7622 if (bgp
->v_maxmed_onstartup
7623 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7624 vty_out(vty
, " bgp max-med on-startup %u",
7625 bgp
->v_maxmed_onstartup
);
7626 if (bgp
->maxmed_onstartup_value
7627 != BGP_MAXMED_VALUE_DEFAULT
)
7629 bgp
->maxmed_onstartup_value
);
7632 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7633 vty_out(vty
, " bgp max-med administrative");
7634 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7635 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7640 bgp_config_write_wpkt_quanta(vty
, bgp
);
7642 bgp_config_write_rpkt_quanta(vty
, bgp
);
7645 bgp_config_write_coalesce_time(vty
, bgp
);
7647 /* BGP graceful-restart. */
7648 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7650 " bgp graceful-restart stalepath-time %u\n",
7651 bgp
->stalepath_time
);
7652 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7653 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7655 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7656 vty_out(vty
, " bgp graceful-restart\n");
7658 /* BGP graceful-shutdown */
7659 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7660 vty_out(vty
, " bgp graceful-shutdown\n");
7662 /* BGP graceful-restart Preserve State F bit. */
7663 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7665 " bgp graceful-restart preserve-fw-state\n");
7667 /* BGP bestpath method. */
7668 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7669 vty_out(vty
, " bgp bestpath as-path ignore\n");
7670 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7671 vty_out(vty
, " bgp bestpath as-path confed\n");
7673 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7674 if (bgp_flag_check(bgp
,
7675 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7677 " bgp bestpath as-path multipath-relax as-set\n");
7680 " bgp bestpath as-path multipath-relax\n");
7684 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7686 " bgp route-reflector allow-outbound-policy\n");
7688 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7689 vty_out(vty
, " bgp bestpath compare-routerid\n");
7690 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7691 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7692 vty_out(vty
, " bgp bestpath med");
7693 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7694 vty_out(vty
, " confed");
7695 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7696 vty_out(vty
, " missing-as-worst");
7700 /* BGP network import check. */
7701 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7702 != DFLT_BGP_IMPORT_CHECK
)
7703 vty_out(vty
, " %sbgp network import-check\n",
7704 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7708 /* BGP flag dampening. */
7709 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7710 BGP_CONFIG_DAMPENING
))
7711 bgp_config_write_damp(vty
);
7713 /* BGP timers configuration. */
7714 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7715 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7716 vty_out(vty
, " timers bgp %u %u\n",
7717 bgp
->default_keepalive
, bgp
->default_holdtime
);
7720 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7721 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7724 /* Normal neighbor configuration. */
7725 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7726 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7727 bgp_config_write_peer_global(vty
, bgp
, peer
);
7730 /* listen range and limit for dynamic BGP neighbors */
7731 bgp_config_write_listen(vty
, bgp
);
7734 * BGP default autoshutdown neighbors
7736 * This must be placed after any peer and peer-group
7737 * configuration, to avoid setting all peers to shutdown after
7738 * a daemon restart, which is undesired behavior. (see #2286)
7740 if (bgp
->autoshutdown
)
7741 vty_out(vty
, " bgp default shutdown\n");
7743 /* No auto-summary */
7744 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7745 vty_out(vty
, " no auto-summary\n");
7747 /* IPv4 unicast configuration. */
7748 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7750 /* IPv4 multicast configuration. */
7751 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7753 /* IPv4 labeled-unicast configuration. */
7754 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7756 /* IPv4 VPN configuration. */
7757 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7759 /* ENCAPv4 configuration. */
7760 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7762 /* FLOWSPEC v4 configuration. */
7763 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7765 /* IPv6 unicast configuration. */
7766 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7768 /* IPv6 multicast configuration. */
7769 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7771 /* IPv6 labeled-unicast configuration. */
7772 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7773 SAFI_LABELED_UNICAST
);
7775 /* IPv6 VPN configuration. */
7776 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7778 /* ENCAPv6 configuration. */
7779 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7781 /* FLOWSPEC v6 configuration. */
7782 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7784 /* EVPN configuration. */
7785 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7788 bgp_rfapi_cfg_write(vty
, bgp
);
7791 vty_out(vty
, "!\n");
7796 void bgp_master_init(struct thread_master
*master
)
7800 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7803 bm
->bgp
= list_new();
7804 bm
->listen_sockets
= list_new();
7805 bm
->port
= BGP_PORT_DEFAULT
;
7806 bm
->master
= master
;
7807 bm
->start_time
= bgp_clock();
7808 bm
->t_rmap_update
= NULL
;
7809 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7810 bm
->terminating
= false;
7812 bgp_process_queue_init();
7815 /* init the rd id space.
7816 assign 0th index in the bitfield,
7817 so that we start with id 1
7819 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7820 bf_assign_zero_index(bm
->rd_idspace
);
7822 /* Enable multiple instances by default. */
7823 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7825 /* mpls label dynamic allocation pool */
7826 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7828 QOBJ_REG(bm
, bgp_master
);
7832 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7833 * instance delete (non-default only) or BGP exit.
7835 static void bgp_if_finish(struct bgp
*bgp
)
7837 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7838 struct interface
*ifp
;
7840 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7843 FOR_ALL_INTERFACES (vrf
, ifp
) {
7844 struct listnode
*c_node
, *c_nnode
;
7845 struct connected
*c
;
7847 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7848 bgp_connected_delete(bgp
, c
);
7852 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7854 struct vrf
*vrf
= NULL
;
7855 struct listnode
*next
;
7858 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7859 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7861 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7862 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7865 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7869 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7870 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7871 {.completions
= NULL
},
7874 struct frr_pthread
*bgp_pth_io
;
7875 struct frr_pthread
*bgp_pth_ka
;
7877 static void bgp_pthreads_init(void)
7879 assert(!bgp_pth_io
);
7880 assert(!bgp_pth_ka
);
7884 struct frr_pthread_attr io
= {
7885 .start
= frr_pthread_attr_default
.start
,
7886 .stop
= frr_pthread_attr_default
.stop
,
7888 struct frr_pthread_attr ka
= {
7889 .start
= bgp_keepalives_start
,
7890 .stop
= bgp_keepalives_stop
,
7892 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7893 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7896 void bgp_pthreads_run(void)
7898 frr_pthread_run(bgp_pth_io
, NULL
);
7899 frr_pthread_run(bgp_pth_ka
, NULL
);
7901 /* Wait until threads are ready. */
7902 frr_pthread_wait_running(bgp_pth_io
);
7903 frr_pthread_wait_running(bgp_pth_ka
);
7906 void bgp_pthreads_finish(void)
7908 frr_pthread_stop_all();
7909 frr_pthread_finish();
7912 void bgp_init(unsigned short instance
)
7915 /* allocates some vital data structures used by peer commands in
7918 /* pre-init pthreads */
7919 bgp_pthreads_init();
7922 bgp_zebra_init(bm
->master
, instance
);
7925 vnc_zebra_init(bm
->master
);
7928 /* BGP VTY commands installation. */
7936 bgp_route_map_init();
7937 bgp_scan_vty_init();
7942 bgp_ethernetvpn_init();
7943 bgp_flowspec_vty_init();
7945 /* Access list initialize. */
7947 access_list_add_hook(peer_distribute_update
);
7948 access_list_delete_hook(peer_distribute_update
);
7950 /* Filter list initialize. */
7952 as_list_add_hook(peer_aslist_add
);
7953 as_list_delete_hook(peer_aslist_del
);
7955 /* Prefix list initialize.*/
7957 prefix_list_add_hook(peer_prefix_list_update
);
7958 prefix_list_delete_hook(peer_prefix_list_update
);
7960 /* Community list initialize. */
7961 bgp_clist
= community_list_init();
7966 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7969 void bgp_terminate(void)
7973 struct listnode
*node
, *nnode
;
7974 struct listnode
*mnode
, *mnnode
;
7978 /* Close the listener sockets first as this prevents peers from
7980 * to reconnect on receiving the peer unconfig message. In the presence
7981 * of a large number of peers this will ensure that no peer is left with
7982 * a dangling connection
7984 /* reverse bgp_master_init */
7987 if (bm
->listen_sockets
)
7988 list_delete(&bm
->listen_sockets
);
7990 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7991 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7992 if (peer
->status
== Established
7993 || peer
->status
== OpenSent
7994 || peer
->status
== OpenConfirm
)
7995 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7996 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7998 if (bm
->process_main_queue
)
7999 work_queue_free_and_null(&bm
->process_main_queue
);
8001 if (bm
->t_rmap_update
)
8002 BGP_TIMER_OFF(bm
->t_rmap_update
);