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
;
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 bgp
->ebgp_requires_policy
= DEFAULT_EBGP_POLICY_DISABLED
;
2940 #if DFLT_BGP_IMPORT_CHECK
2941 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2943 #if DFLT_BGP_SHOW_HOSTNAME
2944 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2946 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2947 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2949 #if DFLT_BGP_DETERMINISTIC_MED
2950 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2952 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2957 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2958 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2960 assert(bgp
->rfapi_cfg
);
2962 #endif /* ENABLE_BGP_VNC */
2964 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2965 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2966 bgp
->vpn_policy
[afi
].afi
= afi
;
2967 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2968 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2971 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2972 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2973 bgp_vrf_string_name_delete
;
2974 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2975 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2976 bgp_vrf_string_name_delete
;
2979 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2981 /* TODO - The startup timer needs to be run for the whole of BGP
2983 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2984 bgp
->restart_time
, &bgp
->t_startup
);
2987 /* printable name we can use in debug messages */
2988 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2989 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2999 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3001 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3002 snprintf(bgp
->name_pretty
, len
, "%s %s",
3003 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3009 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3010 memory_order_relaxed
);
3011 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3012 memory_order_relaxed
);
3013 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3017 update_bgp_group_init(bgp
);
3019 /* assign a unique rd id for auto derivation of vrf's RD */
3020 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3022 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3023 sizeof(struct bgp_evpn_info
));
3030 /* Return the "default VRF" instance of BGP. */
3031 struct bgp
*bgp_get_default(void)
3034 struct listnode
*node
, *nnode
;
3036 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3037 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3042 /* Lookup BGP entry. */
3043 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3046 struct listnode
*node
, *nnode
;
3048 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3050 && ((bgp
->name
== NULL
&& name
== NULL
)
3051 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3056 /* Lookup BGP structure by view name. */
3057 struct bgp
*bgp_lookup_by_name(const char *name
)
3060 struct listnode
*node
, *nnode
;
3062 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3063 if ((bgp
->name
== NULL
&& name
== NULL
)
3064 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3069 /* Lookup BGP instance based on VRF id. */
3070 /* Note: Only to be used for incoming messages from Zebra. */
3071 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3075 /* Lookup VRF (in tree) and follow link. */
3076 vrf
= vrf_lookup_by_id(vrf_id
);
3079 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3082 /* handle socket creation or deletion, if necessary
3083 * this is called for all new BGP instances
3085 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3090 /* Create BGP server socket, if listen mode not disabled */
3091 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3093 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3095 * suppress vrf socket
3097 if (create
== FALSE
) {
3098 bgp_close_vrf_socket(bgp
);
3102 return BGP_ERR_INVALID_VALUE
;
3104 * if vrf_id did not change
3106 if (vrf
->vrf_id
== old_vrf_id
)
3108 if (old_vrf_id
!= VRF_UNKNOWN
) {
3109 /* look for old socket. close it. */
3110 bgp_close_vrf_socket(bgp
);
3112 /* if backend is not yet identified ( VRF_UNKNOWN) then
3113 * creation will be done later
3115 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3117 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3119 return BGP_ERR_INVALID_VALUE
;
3122 return bgp_check_main_socket(create
, bgp
);
3125 /* Called from VTY commands. */
3126 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3127 enum bgp_instance_type inst_type
)
3130 struct vrf
*vrf
= NULL
;
3132 /* Multiple instance check. */
3133 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3135 bgp
= bgp_lookup_by_name(name
);
3137 bgp
= bgp_get_default();
3139 /* Already exists. */
3141 if (bgp
->as
!= *as
) {
3143 return BGP_ERR_INSTANCE_MISMATCH
;
3145 if (bgp
->inst_type
!= inst_type
)
3146 return BGP_ERR_INSTANCE_MISMATCH
;
3151 /* BGP instance name can not be specified for single instance.
3154 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3156 /* Get default BGP structure if exists. */
3157 bgp
= bgp_get_default();
3160 if (bgp
->as
!= *as
) {
3162 return BGP_ERR_AS_MISMATCH
;
3169 bgp
= bgp_create(as
, name
, inst_type
);
3170 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3171 bgp
->vrf_id
= vrf_generate_id();
3172 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3173 bgp_address_init(bgp
);
3174 bgp_tip_hash_init(bgp
);
3178 bgp
->t_rmap_def_originate_eval
= NULL
;
3180 /* If Default instance or VRF, link to the VRF structure, if present. */
3181 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3182 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3183 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3185 bgp_vrf_link(bgp
, vrf
);
3187 /* BGP server socket already processed if BGP instance
3188 * already part of the list
3190 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3191 listnode_add(bm
->bgp
, bgp
);
3193 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3194 if (BGP_DEBUG(zebra
, ZEBRA
))
3195 zlog_debug("%s: Registering BGP instance %s to zebra",
3196 __PRETTY_FUNCTION__
, name
);
3197 bgp_zebra_instance_register(bgp
);
3204 * Make BGP instance "up". Applies only to VRFs (non-default) and
3205 * implies the VRF has been learnt from Zebra.
3207 void bgp_instance_up(struct bgp
*bgp
)
3210 struct listnode
*node
, *next
;
3212 /* Register with zebra. */
3213 bgp_zebra_instance_register(bgp
);
3215 /* Kick off any peers that may have been configured. */
3216 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3217 if (!BGP_PEER_START_SUPPRESSED(peer
))
3218 BGP_EVENT_ADD(peer
, BGP_Start
);
3221 /* Process any networks that have been configured. */
3222 bgp_static_add(bgp
);
3226 * Make BGP instance "down". Applies only to VRFs (non-default) and
3227 * implies the VRF has been deleted by Zebra.
3229 void bgp_instance_down(struct bgp
*bgp
)
3232 struct listnode
*node
;
3233 struct listnode
*next
;
3236 if (bgp
->t_rmap_def_originate_eval
) {
3237 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3238 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3242 /* Bring down peers, so corresponding routes are purged. */
3243 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3244 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3245 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3246 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3248 bgp_session_reset(peer
);
3251 /* Purge network and redistributed routes. */
3252 bgp_purge_static_redist_routes(bgp
);
3254 /* Cleanup registered nexthops (flags) */
3255 bgp_cleanup_nexthops(bgp
);
3258 /* Delete BGP instance. */
3259 int bgp_delete(struct bgp
*bgp
)
3262 struct peer_group
*group
;
3263 struct listnode
*node
, *next
;
3269 THREAD_OFF(bgp
->t_startup
);
3270 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3271 THREAD_OFF(bgp
->t_update_delay
);
3272 THREAD_OFF(bgp
->t_establish_wait
);
3274 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3275 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3276 zlog_debug("Deleting Default VRF");
3278 zlog_debug("Deleting %s %s",
3279 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3285 /* unmap from RT list */
3286 bgp_evpn_vrf_delete(bgp
);
3288 /* unmap bgp vrf label */
3289 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3290 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3293 if (bgp
->t_rmap_def_originate_eval
) {
3294 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3295 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3299 /* Inform peers we're going down. */
3300 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3301 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3302 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3303 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3306 /* Delete static routes (networks). */
3307 bgp_static_delete(bgp
);
3309 /* Unset redistribution. */
3310 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3311 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3312 if (i
!= ZEBRA_ROUTE_BGP
)
3313 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3315 /* Free peers and peer-groups. */
3316 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3317 peer_group_delete(group
);
3319 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3322 if (bgp
->peer_self
) {
3323 peer_delete(bgp
->peer_self
);
3324 bgp
->peer_self
= NULL
;
3327 update_bgp_group_free(bgp
);
3329 /* TODO - Other memory may need to be freed - e.g., NHT */
3334 bgp_cleanup_routes(bgp
);
3336 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3337 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3340 &bgp
->vpn_policy
[afi
]
3341 .import_redirect_rtlist
);
3342 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3345 /* Deregister from Zebra, if needed */
3346 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3347 if (BGP_DEBUG(zebra
, ZEBRA
))
3348 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3349 __PRETTY_FUNCTION__
, bgp
->name
);
3350 bgp_zebra_instance_deregister(bgp
);
3353 /* Remove visibility via the master list - there may however still be
3354 * routes to be processed still referencing the struct bgp.
3356 listnode_delete(bm
->bgp
, bgp
);
3358 /* Free interfaces in this instance. */
3361 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3362 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3364 bgp_vrf_unlink(bgp
, vrf
);
3366 thread_master_free_unused(bm
->master
);
3367 bgp_unlock(bgp
); /* initial reference */
3372 void bgp_free(struct bgp
*bgp
)
3376 struct bgp_table
*table
;
3377 struct bgp_node
*rn
;
3378 struct bgp_rmap
*rmap
;
3382 list_delete(&bgp
->group
);
3383 list_delete(&bgp
->peer
);
3385 if (bgp
->peerhash
) {
3386 hash_free(bgp
->peerhash
);
3387 bgp
->peerhash
= NULL
;
3390 FOREACH_AFI_SAFI (afi
, safi
) {
3391 /* Special handling for 2-level routing tables. */
3392 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3393 || safi
== SAFI_EVPN
) {
3394 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3395 rn
= bgp_route_next(rn
)) {
3396 table
= bgp_node_get_bgp_table_info(rn
);
3397 bgp_table_finish(&table
);
3400 if (bgp
->route
[afi
][safi
])
3401 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3402 if (bgp
->aggregate
[afi
][safi
])
3403 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3404 if (bgp
->rib
[afi
][safi
])
3405 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3406 rmap
= &bgp
->table_map
[afi
][safi
];
3408 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3411 bgp_scan_finish(bgp
);
3412 bgp_address_destroy(bgp
);
3413 bgp_tip_hash_destroy(bgp
);
3415 /* release the auto RD id */
3416 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3418 bgp_evpn_cleanup(bgp
);
3419 bgp_pbr_cleanup(bgp
);
3420 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3422 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3423 vpn_policy_direction_t dir
;
3425 if (bgp
->vpn_policy
[afi
].import_vrf
)
3426 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3427 if (bgp
->vpn_policy
[afi
].export_vrf
)
3428 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3430 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3431 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3432 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3433 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3434 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3435 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3439 XFREE(MTYPE_BGP
, bgp
->name
);
3440 if (bgp
->name_pretty
)
3441 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3443 XFREE(MTYPE_BGP
, bgp
);
3446 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3449 struct listnode
*node
, *nnode
;
3455 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3456 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3457 && !CHECK_FLAG(peer
->sflags
,
3458 PEER_STATUS_ACCEPT_PEER
))
3460 } else if (bm
->bgp
!= NULL
) {
3461 struct listnode
*bgpnode
, *nbgpnode
;
3463 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3464 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3466 && !strcmp(peer
->conf_if
, conf_if
)
3467 && !CHECK_FLAG(peer
->sflags
,
3468 PEER_STATUS_ACCEPT_PEER
))
3474 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3477 struct listnode
*node
, *nnode
;
3483 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3484 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3485 && !CHECK_FLAG(peer
->sflags
,
3486 PEER_STATUS_ACCEPT_PEER
))
3488 } else if (bm
->bgp
!= NULL
) {
3489 struct listnode
*bgpnode
, *nbgpnode
;
3491 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3492 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3494 && !strcmp(peer
->hostname
, hostname
)
3495 && !CHECK_FLAG(peer
->sflags
,
3496 PEER_STATUS_ACCEPT_PEER
))
3502 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3504 struct peer
*peer
= NULL
;
3505 struct peer tmp_peer
;
3507 memset(&tmp_peer
, 0, sizeof(struct peer
));
3510 * We do not want to find the doppelganger peer so search for the peer
3512 * the hash that has PEER_FLAG_CONFIG_NODE
3514 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3519 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3520 } else if (bm
->bgp
!= NULL
) {
3521 struct listnode
*bgpnode
, *nbgpnode
;
3523 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3524 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3533 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3534 union sockunion
*su
,
3535 struct peer_group
*group
)
3541 /* Create peer first; we've already checked group config is valid. */
3542 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3543 group
->conf
->as_type
, 0, 0, group
);
3548 peer
= peer_lock(peer
);
3549 listnode_add(group
->peer
, peer
);
3551 peer_group2peer_config_copy(group
, peer
);
3554 * Bind peer for all AFs configured for the group. We don't call
3555 * peer_group_bind as that is sub-optimal and does some stuff we don't
3558 FOREACH_AFI_SAFI (afi
, safi
) {
3559 if (!group
->conf
->afc
[afi
][safi
])
3561 peer
->afc
[afi
][safi
] = 1;
3563 if (!peer_af_find(peer
, afi
, safi
))
3564 peer_af_create(peer
, afi
, safi
);
3566 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3569 /* Mark as dynamic, but also as a "config node" for other things to
3571 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3572 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3578 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3579 struct prefix
*prefix
)
3581 struct listnode
*node
, *nnode
;
3582 struct prefix
*range
;
3585 afi
= family2afi(prefix
->family
);
3587 if (group
->listen_range
[afi
])
3588 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3590 if (prefix_match(range
, prefix
))
3597 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3598 struct prefix
**listen_range
)
3600 struct prefix
*range
= NULL
;
3601 struct peer_group
*group
= NULL
;
3602 struct listnode
*node
, *nnode
;
3604 *listen_range
= NULL
;
3606 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3607 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3610 } else if (bm
->bgp
!= NULL
) {
3611 struct listnode
*bgpnode
, *nbgpnode
;
3613 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3614 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3615 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3621 *listen_range
= range
;
3622 return (group
&& range
) ? group
: NULL
;
3625 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3627 struct peer_group
*group
;
3630 struct prefix prefix
;
3631 struct prefix
*listen_range
;
3633 char buf
[PREFIX2STR_BUFFER
];
3634 char buf1
[PREFIX2STR_BUFFER
];
3636 sockunion2hostprefix(su
, &prefix
);
3638 /* See if incoming connection matches a configured listen range. */
3639 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3650 prefix2str(&prefix
, buf
, sizeof(buf
));
3651 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3653 if (bgp_debug_neighbor_events(NULL
))
3655 "Dynamic Neighbor %s matches group %s listen range %s",
3656 buf
, group
->name
, buf1
);
3658 /* Are we within the listen limit? */
3659 dncount
= gbgp
->dynamic_neighbors_count
;
3661 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3662 if (bgp_debug_neighbor_events(NULL
))
3663 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3664 inet_sutop(su
, buf
),
3665 gbgp
->dynamic_neighbors_limit
);
3669 /* Ensure group is not disabled. */
3670 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3671 if (bgp_debug_neighbor_events(NULL
))
3673 "Dynamic Neighbor %s rejected - group %s disabled",
3678 /* Check that at least one AF is activated for the group. */
3679 if (!peer_group_af_configured(group
)) {
3680 if (bgp_debug_neighbor_events(NULL
))
3682 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3687 /* Create dynamic peer and bind to associated group. */
3688 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3691 gbgp
->dynamic_neighbors_count
= ++dncount
;
3693 if (bgp_debug_neighbor_events(peer
))
3694 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3695 peer
->host
, group
->name
, dncount
);
3700 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3703 if (peer
->group
->bgp
) {
3704 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3706 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3708 if (bgp_debug_neighbor_events(peer
))
3709 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3710 peer
->group
->name
, dncount
);
3713 /* If peer is configured at least one address family return 1. */
3714 int peer_active(struct peer
*peer
)
3716 if (BGP_PEER_SU_UNSPEC(peer
))
3718 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3719 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3720 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3721 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3722 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3723 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3724 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3725 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3726 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3727 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3728 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3733 /* If peer is negotiated at least one address family return 1. */
3734 int peer_active_nego(struct peer
*peer
)
3736 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3737 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3738 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3739 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3740 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3741 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3742 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3743 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3744 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3745 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3746 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3747 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3748 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3753 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3754 enum peer_change_type type
)
3756 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3759 if (peer
->status
!= Established
)
3762 if (type
== peer_change_reset
) {
3763 /* If we're resetting session, we've to delete both peer struct
3765 if ((peer
->doppelganger
)
3766 && (peer
->doppelganger
->status
!= Deleted
)
3767 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3768 PEER_FLAG_CONFIG_NODE
)))
3769 peer_delete(peer
->doppelganger
);
3771 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3772 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3773 } else if (type
== peer_change_reset_in
) {
3774 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3775 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3776 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3778 if ((peer
->doppelganger
)
3779 && (peer
->doppelganger
->status
!= Deleted
)
3780 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3781 PEER_FLAG_CONFIG_NODE
)))
3782 peer_delete(peer
->doppelganger
);
3784 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3785 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3787 } else if (type
== peer_change_reset_out
) {
3788 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3789 bgp_announce_route(peer
, afi
, safi
);
3793 struct peer_flag_action
{
3797 /* This flag can be set for peer-group member. */
3798 uint8_t not_for_member
;
3800 /* Action when the flag is changed. */
3801 enum peer_change_type type
;
3804 static const struct peer_flag_action peer_flag_action_list
[] = {
3805 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3806 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3807 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3808 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3809 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3810 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3811 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3812 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3813 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3814 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3815 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3816 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3817 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3818 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3819 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3820 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3821 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3824 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3825 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3826 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3827 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3828 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3829 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3830 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3831 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3832 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3833 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3834 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3835 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3836 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3837 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3838 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3839 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3840 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3841 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3842 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3843 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3844 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3845 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3846 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3847 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3848 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3849 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3852 /* Proper action set. */
3853 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3854 int size
, struct peer_flag_action
*action
,
3861 const struct peer_flag_action
*match
= NULL
;
3863 /* Check peer's frag action. */
3864 for (i
= 0; i
< size
; i
++) {
3865 match
= &action_list
[i
];
3867 if (match
->flag
== 0)
3870 if (match
->flag
& flag
) {
3873 if (match
->type
== peer_change_reset_in
)
3875 if (match
->type
== peer_change_reset_out
)
3877 if (match
->type
== peer_change_reset
) {
3881 if (match
->not_for_member
)
3882 action
->not_for_member
= 1;
3886 /* Set peer clear type. */
3887 if (reset_in
&& reset_out
)
3888 action
->type
= peer_change_reset
;
3890 action
->type
= peer_change_reset_in
;
3892 action
->type
= peer_change_reset_out
;
3894 action
->type
= peer_change_none
;
3899 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3901 if (flag
== PEER_FLAG_SHUTDOWN
) {
3902 if (CHECK_FLAG(peer
->flags
, flag
)) {
3903 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3904 peer_nsf_stop(peer
);
3906 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3907 if (peer
->t_pmax_restart
) {
3908 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3909 if (bgp_debug_neighbor_events(peer
))
3911 "%s Maximum-prefix restart timer canceled",
3915 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3916 peer_nsf_stop(peer
);
3918 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3919 char *msg
= peer
->tx_shutdown_message
;
3922 if (!msg
&& peer_group_active(peer
))
3923 msg
= peer
->group
->conf
3924 ->tx_shutdown_message
;
3925 msglen
= msg
? strlen(msg
) : 0;
3930 uint8_t msgbuf
[129];
3933 memcpy(msgbuf
+ 1, msg
, msglen
);
3935 bgp_notify_send_with_data(
3936 peer
, BGP_NOTIFY_CEASE
,
3937 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3938 msgbuf
, msglen
+ 1);
3941 peer
, BGP_NOTIFY_CEASE
,
3942 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3944 bgp_session_reset(peer
);
3946 peer
->v_start
= BGP_INIT_START_TIMER
;
3947 BGP_EVENT_ADD(peer
, BGP_Stop
);
3949 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3950 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3951 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3952 else if (flag
== PEER_FLAG_PASSIVE
)
3953 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3954 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3955 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3957 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3958 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3960 bgp_session_reset(peer
);
3963 /* Change specified peer flag. */
3964 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3968 bool invert
, member_invert
;
3969 struct peer
*member
;
3970 struct listnode
*node
, *nnode
;
3971 struct peer_flag_action action
;
3973 memset(&action
, 0, sizeof(struct peer_flag_action
));
3974 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3976 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3977 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3980 /* Abort if no flag action exists. */
3982 return BGP_ERR_INVALID_FLAG
;
3984 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3985 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3986 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3987 return BGP_ERR_PEER_FLAG_CONFLICT
;
3989 /* Handle flag updates where desired state matches current state. */
3990 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3991 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3992 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3996 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3997 COND_FLAG(peer
->flags_override
, flag
, invert
);
4002 /* Inherit from peer-group or set/unset flags accordingly. */
4003 if (peer_group_active(peer
) && set
== invert
)
4004 peer_flag_inherit(peer
, flag
);
4006 COND_FLAG(peer
->flags
, flag
, set
);
4008 /* Check if handling a regular peer. */
4009 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4010 /* Update flag override state accordingly. */
4011 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4013 /* Execute flag action on peer. */
4014 if (action
.type
== peer_change_reset
)
4015 peer_flag_modify_action(peer
, flag
);
4017 /* Skip peer-group mechanics for regular peers. */
4021 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4022 bgp_nht_register_enhe_capability_interfaces(peer
);
4025 * Update peer-group members, unless they are explicitely overriding
4026 * peer-group configuration.
4028 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4029 /* Skip peers with overridden configuration. */
4030 if (CHECK_FLAG(member
->flags_override
, flag
))
4033 /* Check if only member without group is inverted. */
4035 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4037 /* Skip peers with equivalent configuration. */
4038 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4041 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4044 /* Update flag on peer-group member. */
4045 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4047 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4048 bgp_nht_register_enhe_capability_interfaces(member
);
4050 /* Execute flag action on peer-group member. */
4051 if (action
.type
== peer_change_reset
)
4052 peer_flag_modify_action(member
, flag
);
4058 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4060 return peer_flag_modify(peer
, flag
, 1);
4063 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4065 return peer_flag_modify(peer
, flag
, 0);
4068 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4069 uint32_t flag
, bool set
)
4073 bool invert
, member_invert
;
4074 struct peer
*member
;
4075 struct listnode
*node
, *nnode
;
4076 struct peer_flag_action action
;
4078 memset(&action
, 0, sizeof(struct peer_flag_action
));
4079 size
= sizeof peer_af_flag_action_list
4080 / sizeof(struct peer_flag_action
);
4082 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4083 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4086 /* Abort if flag action exists. */
4088 return BGP_ERR_INVALID_FLAG
;
4090 /* Special check for reflector client. */
4091 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4092 && peer_sort(peer
) != BGP_PEER_IBGP
)
4093 return BGP_ERR_NOT_INTERNAL_PEER
;
4095 /* Special check for remove-private-AS. */
4096 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4097 && peer_sort(peer
) == BGP_PEER_IBGP
)
4098 return BGP_ERR_REMOVE_PRIVATE_AS
;
4100 /* as-override is not allowed for IBGP peers */
4101 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4102 return BGP_ERR_AS_OVERRIDE
;
4104 /* Handle flag updates where desired state matches current state. */
4105 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4106 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4107 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4112 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4113 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4120 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4121 * if we are setting/unsetting flags which conflict with this flag
4122 * handle accordingly
4124 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4128 * if we are setting NEXTHOP_SELF, we need to unset the
4129 * NEXTHOP_UNCHANGED flag
4131 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4132 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4133 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4134 PEER_FLAG_NEXTHOP_UNCHANGED
);
4138 * if we are unsetting NEXTHOP_SELF, we need to set the
4139 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4141 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4142 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4143 SET_FLAG(peer
->af_flags
[afi
][safi
],
4144 PEER_FLAG_NEXTHOP_UNCHANGED
);
4148 /* Inherit from peer-group or set/unset flags accordingly. */
4149 if (peer_group_active(peer
) && set
== invert
)
4150 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4152 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4154 /* Execute action when peer is established. */
4155 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4156 && peer
->status
== Established
) {
4157 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4158 bgp_clear_adj_in(peer
, afi
, safi
);
4160 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4161 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4162 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4163 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4164 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4165 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4166 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4167 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4169 peer_change_action(peer
, afi
, safi
, action
.type
);
4173 /* Check if handling a regular peer. */
4174 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4175 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4179 * Update peer-group members, unless they are explicitely
4180 * overriding peer-group configuration.
4182 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4184 /* Skip peers with overridden configuration. */
4185 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4189 /* Check if only member without group is inverted. */
4191 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4195 /* Skip peers with equivalent configuration. */
4196 if (set
!= member_invert
4197 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4200 if (set
== member_invert
4201 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4204 /* Update flag on peer-group member. */
4205 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4206 set
!= member_invert
);
4208 /* Execute flag action on peer-group member. */
4209 if (member
->status
== Established
) {
4210 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4211 bgp_clear_adj_in(member
, afi
, safi
);
4213 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4214 member
->last_reset
=
4215 PEER_DOWN_RR_CLIENT_CHANGE
;
4217 == PEER_FLAG_RSERVER_CLIENT
)
4218 member
->last_reset
=
4219 PEER_DOWN_RS_CLIENT_CHANGE
;
4221 == PEER_FLAG_ORF_PREFIX_SM
)
4222 member
->last_reset
=
4223 PEER_DOWN_CAPABILITY_CHANGE
;
4225 == PEER_FLAG_ORF_PREFIX_RM
)
4226 member
->last_reset
=
4227 PEER_DOWN_CAPABILITY_CHANGE
;
4229 peer_change_action(member
, afi
, safi
,
4239 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4241 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4244 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4246 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4250 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4252 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4253 peer
->tx_shutdown_message
=
4254 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4258 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4260 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4265 /* EBGP multihop configuration. */
4266 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4268 struct peer_group
*group
;
4269 struct listnode
*node
, *nnode
;
4272 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4275 /* see comment in peer_ttl_security_hops_set() */
4276 if (ttl
!= MAXTTL
) {
4277 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4278 group
= peer
->group
;
4279 if (group
->conf
->gtsm_hops
!= 0)
4280 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4282 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4284 if (peer1
->sort
== BGP_PEER_IBGP
)
4287 if (peer1
->gtsm_hops
!= 0)
4288 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4291 if (peer
->gtsm_hops
!= 0)
4292 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4298 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4299 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4300 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4301 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4302 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4304 bgp_session_reset(peer
);
4307 group
= peer
->group
;
4308 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4309 if (peer
->sort
== BGP_PEER_IBGP
)
4312 peer
->ttl
= group
->conf
->ttl
;
4314 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4315 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4316 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4318 bgp_session_reset(peer
);
4324 int peer_ebgp_multihop_unset(struct peer
*peer
)
4326 struct peer_group
*group
;
4327 struct listnode
*node
, *nnode
;
4329 if (peer
->sort
== BGP_PEER_IBGP
)
4332 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4333 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4335 if (peer_group_active(peer
))
4336 peer
->ttl
= peer
->group
->conf
->ttl
;
4340 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4341 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4342 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4343 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4345 bgp_session_reset(peer
);
4347 group
= peer
->group
;
4348 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4349 if (peer
->sort
== BGP_PEER_IBGP
)
4354 if (peer
->fd
>= 0) {
4355 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4357 peer
, BGP_NOTIFY_CEASE
,
4358 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4360 bgp_session_reset(peer
);
4367 /* Neighbor description. */
4368 int peer_description_set(struct peer
*peer
, const char *desc
)
4371 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4373 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4378 int peer_description_unset(struct peer
*peer
)
4381 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4388 /* Neighbor update-source. */
4389 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4391 struct peer
*member
;
4392 struct listnode
*node
, *nnode
;
4394 /* Set flag and configuration on peer. */
4395 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4396 if (peer
->update_if
) {
4397 if (strcmp(peer
->update_if
, ifname
) == 0)
4399 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4401 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4402 sockunion_free(peer
->update_source
);
4403 peer
->update_source
= NULL
;
4405 /* Check if handling a regular peer. */
4406 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4407 /* Send notification or reset peer depending on state. */
4408 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4409 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4410 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4411 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4413 bgp_session_reset(peer
);
4415 /* Skip peer-group mechanics for regular peers. */
4420 * Set flag and configuration on all peer-group members, unless they are
4421 * explicitely overriding peer-group configuration.
4423 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4424 /* Skip peers with overridden configuration. */
4425 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4428 /* Skip peers with the same configuration. */
4429 if (member
->update_if
) {
4430 if (strcmp(member
->update_if
, ifname
) == 0)
4432 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4435 /* Set flag and configuration on peer-group member. */
4436 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4437 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4438 sockunion_free(member
->update_source
);
4439 member
->update_source
= NULL
;
4441 /* Send notification or reset peer depending on state. */
4442 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4443 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4444 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4445 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4447 bgp_session_reset(member
);
4453 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4455 struct peer
*member
;
4456 struct listnode
*node
, *nnode
;
4458 /* Set flag and configuration on peer. */
4459 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4460 if (peer
->update_source
) {
4461 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4463 sockunion_free(peer
->update_source
);
4465 peer
->update_source
= sockunion_dup(su
);
4466 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4468 /* Check if handling a regular peer. */
4469 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4470 /* Send notification or reset peer depending on state. */
4471 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4472 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4473 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4474 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4476 bgp_session_reset(peer
);
4478 /* Skip peer-group mechanics for regular peers. */
4483 * Set flag and configuration on all peer-group members, unless they are
4484 * explicitely overriding peer-group configuration.
4486 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4487 /* Skip peers with overridden configuration. */
4488 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4491 /* Skip peers with the same configuration. */
4492 if (member
->update_source
) {
4493 if (sockunion_cmp(member
->update_source
, su
) == 0)
4495 sockunion_free(member
->update_source
);
4498 /* Set flag and configuration on peer-group member. */
4499 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4500 member
->update_source
= sockunion_dup(su
);
4501 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4503 /* Send notification or reset peer depending on state. */
4504 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4505 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4506 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4507 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4509 bgp_session_reset(member
);
4515 int peer_update_source_unset(struct peer
*peer
)
4517 struct peer
*member
;
4518 struct listnode
*node
, *nnode
;
4520 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4523 /* Inherit configuration from peer-group if peer is member. */
4524 if (peer_group_active(peer
)) {
4525 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4526 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4527 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4528 MTYPE_PEER_UPDATE_SOURCE
);
4530 /* Otherwise remove flag and configuration from peer. */
4531 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4532 sockunion_free(peer
->update_source
);
4533 peer
->update_source
= NULL
;
4534 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4537 /* Check if handling a regular peer. */
4538 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4539 /* Send notification or reset peer depending on state. */
4540 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4541 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4542 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4543 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4545 bgp_session_reset(peer
);
4547 /* Skip peer-group mechanics for regular peers. */
4552 * Set flag and configuration on all peer-group members, unless they are
4553 * explicitely overriding peer-group configuration.
4555 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4556 /* Skip peers with overridden configuration. */
4557 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4560 /* Skip peers with the same configuration. */
4561 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4562 && !member
->update_source
&& !member
->update_if
)
4565 /* Remove flag and configuration on peer-group member. */
4566 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4567 sockunion_free(member
->update_source
);
4568 member
->update_source
= NULL
;
4569 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4571 /* Send notification or reset peer depending on state. */
4572 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4573 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4574 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4575 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4577 bgp_session_reset(member
);
4583 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4584 const char *rmap
, struct route_map
*route_map
)
4586 struct peer
*member
;
4587 struct listnode
*node
, *nnode
;
4589 /* Set flag and configuration on peer. */
4590 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4592 if (!peer
->default_rmap
[afi
][safi
].name
4593 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4594 if (peer
->default_rmap
[afi
][safi
].name
)
4595 XFREE(MTYPE_ROUTE_MAP_NAME
,
4596 peer
->default_rmap
[afi
][safi
].name
);
4598 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4599 peer
->default_rmap
[afi
][safi
].name
=
4600 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4601 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4602 route_map_counter_increment(route_map
);
4605 if (peer
->default_rmap
[afi
][safi
].name
)
4606 XFREE(MTYPE_ROUTE_MAP_NAME
,
4607 peer
->default_rmap
[afi
][safi
].name
);
4609 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4610 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4611 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4614 /* Check if handling a regular peer. */
4615 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4616 /* Update peer route announcements. */
4617 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4618 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4619 bgp_default_originate(peer
, afi
, safi
, 0);
4620 bgp_announce_route(peer
, afi
, safi
);
4623 /* Skip peer-group mechanics for regular peers. */
4628 * Set flag and configuration on all peer-group members, unless they are
4629 * explicitely overriding peer-group configuration.
4631 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4632 /* Skip peers with overridden configuration. */
4633 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4634 PEER_FLAG_DEFAULT_ORIGINATE
))
4637 /* Set flag and configuration on peer-group member. */
4638 SET_FLAG(member
->af_flags
[afi
][safi
],
4639 PEER_FLAG_DEFAULT_ORIGINATE
);
4641 if (member
->default_rmap
[afi
][safi
].name
)
4642 XFREE(MTYPE_ROUTE_MAP_NAME
,
4643 member
->default_rmap
[afi
][safi
].name
);
4644 route_map_counter_decrement(
4645 member
->default_rmap
[afi
][safi
].map
);
4646 member
->default_rmap
[afi
][safi
].name
=
4647 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4648 member
->default_rmap
[afi
][safi
].map
= route_map
;
4649 route_map_counter_increment(route_map
);
4652 /* Update peer route announcements. */
4653 if (member
->status
== Established
4654 && member
->afc_nego
[afi
][safi
]) {
4655 update_group_adjust_peer(
4656 peer_af_find(member
, afi
, safi
));
4657 bgp_default_originate(member
, afi
, safi
, 0);
4658 bgp_announce_route(member
, afi
, safi
);
4665 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4667 struct peer
*member
;
4668 struct listnode
*node
, *nnode
;
4670 /* Inherit configuration from peer-group if peer is member. */
4671 if (peer_group_active(peer
)) {
4672 peer_af_flag_inherit(peer
, afi
, safi
,
4673 PEER_FLAG_DEFAULT_ORIGINATE
);
4674 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4675 default_rmap
[afi
][safi
].name
,
4676 MTYPE_ROUTE_MAP_NAME
);
4677 PEER_ATTR_INHERIT(peer
, peer
->group
,
4678 default_rmap
[afi
][safi
].map
);
4680 /* Otherwise remove flag and configuration from peer. */
4681 peer_af_flag_unset(peer
, afi
, safi
,
4682 PEER_FLAG_DEFAULT_ORIGINATE
);
4683 if (peer
->default_rmap
[afi
][safi
].name
)
4684 XFREE(MTYPE_ROUTE_MAP_NAME
,
4685 peer
->default_rmap
[afi
][safi
].name
);
4686 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4687 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4688 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4691 /* Check if handling a regular peer. */
4692 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4693 /* Update peer route announcements. */
4694 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4695 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4696 bgp_default_originate(peer
, afi
, safi
, 1);
4697 bgp_announce_route(peer
, afi
, safi
);
4700 /* Skip peer-group mechanics for regular peers. */
4705 * Remove flag and configuration from all peer-group members, unless
4706 * they are explicitely overriding peer-group configuration.
4708 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4709 /* Skip peers with overridden configuration. */
4710 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4711 PEER_FLAG_DEFAULT_ORIGINATE
))
4714 /* Remove flag and configuration on peer-group member. */
4715 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4716 PEER_FLAG_DEFAULT_ORIGINATE
);
4717 if (peer
->default_rmap
[afi
][safi
].name
)
4718 XFREE(MTYPE_ROUTE_MAP_NAME
,
4719 peer
->default_rmap
[afi
][safi
].name
);
4720 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4721 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4722 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4724 /* Update peer route announcements. */
4725 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4726 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4727 bgp_default_originate(peer
, afi
, safi
, 1);
4728 bgp_announce_route(peer
, afi
, safi
);
4735 int peer_port_set(struct peer
*peer
, uint16_t port
)
4741 int peer_port_unset(struct peer
*peer
)
4743 peer
->port
= BGP_PORT_DEFAULT
;
4748 * Helper function that is called after the name of the policy
4749 * being used by a peer has changed (AF specific). Automatically
4750 * initiates inbound or outbound processing as needed.
4752 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4756 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4757 if (peer
->status
== Established
)
4758 bgp_announce_route(peer
, afi
, safi
);
4760 if (peer
->status
!= Established
)
4763 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4764 PEER_FLAG_SOFT_RECONFIG
))
4765 bgp_soft_reconfig_in(peer
, afi
, safi
);
4766 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4767 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4768 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4773 /* neighbor weight. */
4774 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4776 struct peer
*member
;
4777 struct listnode
*node
, *nnode
;
4779 /* Set flag and configuration on peer. */
4780 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4781 if (peer
->weight
[afi
][safi
] != weight
) {
4782 peer
->weight
[afi
][safi
] = weight
;
4783 peer_on_policy_change(peer
, afi
, safi
, 0);
4786 /* Skip peer-group mechanics for regular peers. */
4787 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4791 * Set flag and configuration on all peer-group members, unless they are
4792 * explicitely overriding peer-group configuration.
4794 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4795 /* Skip peers with overridden configuration. */
4796 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4800 /* Set flag and configuration on peer-group member. */
4801 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4802 if (member
->weight
[afi
][safi
] != weight
) {
4803 member
->weight
[afi
][safi
] = weight
;
4804 peer_on_policy_change(member
, afi
, safi
, 0);
4811 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4813 struct peer
*member
;
4814 struct listnode
*node
, *nnode
;
4816 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4819 /* Inherit configuration from peer-group if peer is member. */
4820 if (peer_group_active(peer
)) {
4821 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4822 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4824 peer_on_policy_change(peer
, afi
, safi
, 0);
4828 /* Remove flag and configuration from peer. */
4829 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4830 peer
->weight
[afi
][safi
] = 0;
4831 peer_on_policy_change(peer
, afi
, safi
, 0);
4833 /* Skip peer-group mechanics for regular peers. */
4834 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4838 * Remove flag and configuration from all peer-group members, unless
4839 * they are explicitely overriding peer-group configuration.
4841 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4842 /* Skip peers with overridden configuration. */
4843 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4847 /* Skip peers where flag is already disabled. */
4848 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4851 /* Remove flag and configuration on peer-group member. */
4852 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4853 member
->weight
[afi
][safi
] = 0;
4854 peer_on_policy_change(member
, afi
, safi
, 0);
4860 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4862 struct peer
*member
;
4863 struct listnode
*node
, *nnode
;
4865 if (keepalive
> 65535)
4866 return BGP_ERR_INVALID_VALUE
;
4868 if (holdtime
> 65535)
4869 return BGP_ERR_INVALID_VALUE
;
4871 if (holdtime
< 3 && holdtime
!= 0)
4872 return BGP_ERR_INVALID_VALUE
;
4874 /* Set flag and configuration on peer. */
4875 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4876 peer
->holdtime
= holdtime
;
4877 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4879 /* Skip peer-group mechanics for regular peers. */
4880 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4884 * Set flag and configuration on all peer-group members, unless they are
4885 * explicitely overriding peer-group configuration.
4887 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4888 /* Skip peers with overridden configuration. */
4889 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4892 /* Set flag and configuration on peer-group member. */
4893 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4894 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4895 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4901 int peer_timers_unset(struct peer
*peer
)
4903 struct peer
*member
;
4904 struct listnode
*node
, *nnode
;
4906 /* Inherit configuration from peer-group if peer is member. */
4907 if (peer_group_active(peer
)) {
4908 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4909 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4910 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4912 /* Otherwise remove flag and configuration from peer. */
4913 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4915 peer
->keepalive
= 0;
4918 /* Skip peer-group mechanics for regular peers. */
4919 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4923 * Remove flag and configuration from all peer-group members, unless
4924 * they are explicitely overriding peer-group configuration.
4926 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4927 /* Skip peers with overridden configuration. */
4928 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4931 /* Remove flag and configuration on peer-group member. */
4932 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4933 member
->holdtime
= 0;
4934 member
->keepalive
= 0;
4940 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4942 struct peer
*member
;
4943 struct listnode
*node
, *nnode
;
4945 if (connect
> 65535)
4946 return BGP_ERR_INVALID_VALUE
;
4948 /* Set flag and configuration on peer. */
4949 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4950 peer
->connect
= connect
;
4951 peer
->v_connect
= connect
;
4953 /* Skip peer-group mechanics for regular peers. */
4954 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4958 * Set flag and configuration on all peer-group members, unless they are
4959 * explicitely overriding peer-group configuration.
4961 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4962 /* Skip peers with overridden configuration. */
4963 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4966 /* Set flag and configuration on peer-group member. */
4967 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4968 member
->connect
= connect
;
4969 member
->v_connect
= connect
;
4975 int peer_timers_connect_unset(struct peer
*peer
)
4977 struct peer
*member
;
4978 struct listnode
*node
, *nnode
;
4980 /* Inherit configuration from peer-group if peer is member. */
4981 if (peer_group_active(peer
)) {
4982 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4983 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4985 /* Otherwise remove flag and configuration from peer. */
4986 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4990 /* Set timer with fallback to default value. */
4992 peer
->v_connect
= peer
->connect
;
4994 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4996 /* Skip peer-group mechanics for regular peers. */
4997 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5001 * Remove flag and configuration from all peer-group members, unless
5002 * they are explicitely overriding peer-group configuration.
5004 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5005 /* Skip peers with overridden configuration. */
5006 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5009 /* Remove flag and configuration on peer-group member. */
5010 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5011 member
->connect
= 0;
5012 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5018 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5020 struct peer
*member
;
5021 struct listnode
*node
, *nnode
;
5024 return BGP_ERR_INVALID_VALUE
;
5026 /* Set flag and configuration on peer. */
5027 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5028 peer
->routeadv
= routeadv
;
5029 peer
->v_routeadv
= routeadv
;
5031 /* Check if handling a regular peer. */
5032 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5033 /* Update peer route announcements. */
5034 update_group_adjust_peer_afs(peer
);
5035 if (peer
->status
== Established
)
5036 bgp_announce_route_all(peer
);
5038 /* Skip peer-group mechanics for regular peers. */
5043 * Set flag and configuration on all peer-group members, unless they are
5044 * explicitely overriding peer-group configuration.
5046 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5047 /* Skip peers with overridden configuration. */
5048 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5051 /* Set flag and configuration on peer-group member. */
5052 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5053 member
->routeadv
= routeadv
;
5054 member
->v_routeadv
= routeadv
;
5056 /* Update peer route announcements. */
5057 update_group_adjust_peer_afs(member
);
5058 if (member
->status
== Established
)
5059 bgp_announce_route_all(member
);
5065 int peer_advertise_interval_unset(struct peer
*peer
)
5067 struct peer
*member
;
5068 struct listnode
*node
, *nnode
;
5070 /* Inherit configuration from peer-group if peer is member. */
5071 if (peer_group_active(peer
)) {
5072 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5073 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5075 /* Otherwise remove flag and configuration from peer. */
5076 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5080 /* Set timer with fallback to default value. */
5082 peer
->v_routeadv
= peer
->routeadv
;
5084 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5085 ? BGP_DEFAULT_IBGP_ROUTEADV
5086 : BGP_DEFAULT_EBGP_ROUTEADV
;
5088 /* Check if handling a regular peer. */
5089 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5090 /* Update peer route announcements. */
5091 update_group_adjust_peer_afs(peer
);
5092 if (peer
->status
== Established
)
5093 bgp_announce_route_all(peer
);
5095 /* Skip peer-group mechanics for regular peers. */
5100 * Remove flag and configuration from all peer-group members, unless
5101 * they are explicitely overriding peer-group configuration.
5103 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5104 /* Skip peers with overridden configuration. */
5105 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5108 /* Remove flag and configuration on peer-group member. */
5109 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5110 member
->routeadv
= 0;
5111 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5112 ? BGP_DEFAULT_IBGP_ROUTEADV
5113 : BGP_DEFAULT_EBGP_ROUTEADV
;
5115 /* Update peer route announcements. */
5116 update_group_adjust_peer_afs(member
);
5117 if (member
->status
== Established
)
5118 bgp_announce_route_all(member
);
5124 /* neighbor interface */
5125 void peer_interface_set(struct peer
*peer
, const char *str
)
5128 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5129 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5132 void peer_interface_unset(struct peer
*peer
)
5135 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5136 peer
->ifname
= NULL
;
5140 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5141 int allow_num
, int origin
)
5143 struct peer
*member
;
5144 struct listnode
*node
, *nnode
;
5146 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5147 return BGP_ERR_INVALID_VALUE
;
5149 /* Set flag and configuration on peer. */
5150 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5152 if (peer
->allowas_in
[afi
][safi
] != 0
5153 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5154 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5155 peer_af_flag_set(peer
, afi
, safi
,
5156 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5157 peer
->allowas_in
[afi
][safi
] = 0;
5158 peer_on_policy_change(peer
, afi
, safi
, 0);
5161 if (peer
->allowas_in
[afi
][safi
] != allow_num
5162 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5163 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5165 peer_af_flag_unset(peer
, afi
, safi
,
5166 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5167 peer
->allowas_in
[afi
][safi
] = allow_num
;
5168 peer_on_policy_change(peer
, afi
, safi
, 0);
5172 /* Skip peer-group mechanics for regular peers. */
5173 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5177 * Set flag and configuration on all peer-group members, unless
5178 * they are explicitely overriding peer-group configuration.
5180 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5181 /* Skip peers with overridden configuration. */
5182 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5183 PEER_FLAG_ALLOWAS_IN
))
5186 /* Set flag and configuration on peer-group member. */
5187 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5189 if (member
->allowas_in
[afi
][safi
] != 0
5190 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5191 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5192 SET_FLAG(member
->af_flags
[afi
][safi
],
5193 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5194 member
->allowas_in
[afi
][safi
] = 0;
5195 peer_on_policy_change(peer
, afi
, safi
, 0);
5198 if (member
->allowas_in
[afi
][safi
] != allow_num
5199 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5200 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5201 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5202 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5203 member
->allowas_in
[afi
][safi
] = allow_num
;
5204 peer_on_policy_change(peer
, afi
, safi
, 0);
5212 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5214 struct peer
*member
;
5215 struct listnode
*node
, *nnode
;
5217 /* Skip peer if flag is already disabled. */
5218 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5221 /* Inherit configuration from peer-group if peer is member. */
5222 if (peer_group_active(peer
)) {
5223 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5224 peer_af_flag_inherit(peer
, afi
, safi
,
5225 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5226 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5227 peer_on_policy_change(peer
, afi
, safi
, 0);
5232 /* Remove flag and configuration from peer. */
5233 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5234 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5235 peer
->allowas_in
[afi
][safi
] = 0;
5236 peer_on_policy_change(peer
, afi
, safi
, 0);
5238 /* Skip peer-group mechanics if handling a regular peer. */
5239 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5243 * Remove flags and configuration from all peer-group members, unless
5244 * they are explicitely overriding peer-group configuration.
5246 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5247 /* Skip peers with overridden configuration. */
5248 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5249 PEER_FLAG_ALLOWAS_IN
))
5252 /* Skip peers where flag is already disabled. */
5253 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5254 PEER_FLAG_ALLOWAS_IN
))
5257 /* Remove flags and configuration on peer-group member. */
5258 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5259 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5260 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5261 member
->allowas_in
[afi
][safi
] = 0;
5262 peer_on_policy_change(member
, afi
, safi
, 0);
5268 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5271 bool old_no_prepend
, old_replace_as
;
5272 struct bgp
*bgp
= peer
->bgp
;
5273 struct peer
*member
;
5274 struct listnode
*node
, *nnode
;
5276 if (peer_sort(peer
) != BGP_PEER_EBGP
5277 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5278 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5281 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5284 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5286 /* Save previous flag states. */
5288 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5290 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5292 /* Set flag and configuration on peer. */
5293 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5294 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5295 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5297 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5298 && old_replace_as
== replace_as
)
5300 peer
->change_local_as
= as
;
5302 /* Check if handling a regular peer. */
5303 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5304 /* Send notification or reset peer depending on state. */
5305 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5306 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5307 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5308 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5310 bgp_session_reset(peer
);
5312 /* Skip peer-group mechanics for regular peers. */
5317 * Set flag and configuration on all peer-group members, unless they are
5318 * explicitely overriding peer-group configuration.
5320 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5321 /* Skip peers with overridden configuration. */
5322 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5325 /* Skip peers with the same configuration. */
5326 old_no_prepend
= CHECK_FLAG(member
->flags
,
5327 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5328 old_replace_as
= CHECK_FLAG(member
->flags
,
5329 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5330 if (member
->change_local_as
== as
5331 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5332 && old_no_prepend
== no_prepend
5333 && old_replace_as
== replace_as
)
5336 /* Set flag and configuration on peer-group member. */
5337 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5338 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5340 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5342 member
->change_local_as
= as
;
5344 /* Send notification or stop peer depending on state. */
5345 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5346 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5347 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5348 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5350 BGP_EVENT_ADD(member
, BGP_Stop
);
5356 int peer_local_as_unset(struct peer
*peer
)
5358 struct peer
*member
;
5359 struct listnode
*node
, *nnode
;
5361 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5364 /* Inherit configuration from peer-group if peer is member. */
5365 if (peer_group_active(peer
)) {
5366 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5367 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5368 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5369 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5371 /* Otherwise remove flag and configuration from peer. */
5372 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5373 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5374 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5375 peer
->change_local_as
= 0;
5378 /* Check if handling a regular peer. */
5379 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5380 /* Send notification or stop peer depending on state. */
5381 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5382 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5383 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5384 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5386 BGP_EVENT_ADD(peer
, BGP_Stop
);
5388 /* Skip peer-group mechanics for regular peers. */
5393 * Remove flag and configuration from all peer-group members, unless
5394 * they are explicitely overriding peer-group configuration.
5396 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5397 /* Skip peers with overridden configuration. */
5398 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5401 /* Remove flag and configuration on peer-group member. */
5402 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5403 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5404 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5405 member
->change_local_as
= 0;
5407 /* Send notification or stop peer depending on state. */
5408 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5409 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5410 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5411 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5413 bgp_session_reset(member
);
5419 /* Set password for authenticating with the peer. */
5420 int peer_password_set(struct peer
*peer
, const char *password
)
5422 struct peer
*member
;
5423 struct listnode
*node
, *nnode
;
5424 int len
= password
? strlen(password
) : 0;
5425 int ret
= BGP_SUCCESS
;
5427 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5428 return BGP_ERR_INVALID_VALUE
;
5430 /* Set flag and configuration on peer. */
5431 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5432 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5434 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5435 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5437 /* Check if handling a regular peer. */
5438 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5439 /* Send notification or reset peer depending on state. */
5440 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5441 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5442 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5444 bgp_session_reset(peer
);
5447 * Attempt to install password on socket and skip peer-group
5450 if (BGP_PEER_SU_UNSPEC(peer
))
5452 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5453 : BGP_ERR_TCPSIG_FAILED
;
5457 * Set flag and configuration on all peer-group members, unless they are
5458 * explicitely overriding peer-group configuration.
5460 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5461 /* Skip peers with overridden configuration. */
5462 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5465 /* Skip peers with the same password. */
5466 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5469 /* Set flag and configuration on peer-group member. */
5470 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5471 if (member
->password
)
5472 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5473 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5475 /* Send notification or reset peer depending on state. */
5476 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5477 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5478 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5480 bgp_session_reset(member
);
5482 /* Attempt to install password on socket. */
5483 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5484 ret
= BGP_ERR_TCPSIG_FAILED
;
5490 int peer_password_unset(struct peer
*peer
)
5492 struct peer
*member
;
5493 struct listnode
*node
, *nnode
;
5495 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5498 /* Inherit configuration from peer-group if peer is member. */
5499 if (peer_group_active(peer
)) {
5500 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5501 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5502 MTYPE_PEER_PASSWORD
);
5504 /* Otherwise remove flag and configuration from peer. */
5505 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5506 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5509 /* Check if handling a regular peer. */
5510 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5511 /* Send notification or reset peer depending on state. */
5512 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5513 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5514 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5516 bgp_session_reset(peer
);
5518 /* Attempt to uninstall password on socket. */
5519 if (!BGP_PEER_SU_UNSPEC(peer
))
5520 bgp_md5_unset(peer
);
5522 /* Skip peer-group mechanics for regular peers. */
5527 * Remove flag and configuration from all peer-group members, unless
5528 * they are explicitely overriding peer-group configuration.
5530 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5531 /* Skip peers with overridden configuration. */
5532 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5535 /* Remove flag and configuration on peer-group member. */
5536 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5537 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5539 /* Send notification or reset peer depending on state. */
5540 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5541 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5542 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5544 bgp_session_reset(member
);
5546 /* Attempt to uninstall password on socket. */
5547 if (!BGP_PEER_SU_UNSPEC(member
))
5548 bgp_md5_unset(member
);
5555 /* Set distribute list to the peer. */
5556 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5559 struct peer
*member
;
5560 struct bgp_filter
*filter
;
5561 struct listnode
*node
, *nnode
;
5563 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5564 return BGP_ERR_INVALID_VALUE
;
5566 /* Set configuration on peer. */
5567 filter
= &peer
->filter
[afi
][safi
];
5568 if (filter
->plist
[direct
].name
)
5569 return BGP_ERR_PEER_FILTER_CONFLICT
;
5570 if (filter
->dlist
[direct
].name
)
5571 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5572 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5573 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5575 /* Check if handling a regular peer. */
5576 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5577 /* Set override-flag and process peer route updates. */
5578 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5579 PEER_FT_DISTRIBUTE_LIST
);
5580 peer_on_policy_change(peer
, afi
, safi
,
5581 (direct
== FILTER_OUT
) ? 1 : 0);
5583 /* Skip peer-group mechanics for regular peers. */
5588 * Set configuration on all peer-group members, un less they are
5589 * explicitely overriding peer-group configuration.
5591 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5592 /* Skip peers with overridden configuration. */
5593 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5594 PEER_FT_DISTRIBUTE_LIST
))
5597 /* Set configuration on peer-group member. */
5598 filter
= &member
->filter
[afi
][safi
];
5599 if (filter
->dlist
[direct
].name
)
5600 XFREE(MTYPE_BGP_FILTER_NAME
,
5601 filter
->dlist
[direct
].name
);
5602 filter
->dlist
[direct
].name
=
5603 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5604 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5606 /* Process peer route updates. */
5607 peer_on_policy_change(member
, afi
, safi
,
5608 (direct
== FILTER_OUT
) ? 1 : 0);
5614 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5616 struct peer
*member
;
5617 struct bgp_filter
*filter
;
5618 struct listnode
*node
, *nnode
;
5620 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5621 return BGP_ERR_INVALID_VALUE
;
5623 /* Unset override-flag unconditionally. */
5624 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5625 PEER_FT_DISTRIBUTE_LIST
);
5627 /* Inherit configuration from peer-group if peer is member. */
5628 if (peer_group_active(peer
)) {
5629 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5630 filter
[afi
][safi
].dlist
[direct
].name
,
5631 MTYPE_BGP_FILTER_NAME
);
5632 PEER_ATTR_INHERIT(peer
, peer
->group
,
5633 filter
[afi
][safi
].dlist
[direct
].alist
);
5635 /* Otherwise remove configuration from peer. */
5636 filter
= &peer
->filter
[afi
][safi
];
5637 if (filter
->dlist
[direct
].name
)
5638 XFREE(MTYPE_BGP_FILTER_NAME
,
5639 filter
->dlist
[direct
].name
);
5640 filter
->dlist
[direct
].name
= NULL
;
5641 filter
->dlist
[direct
].alist
= NULL
;
5644 /* Check if handling a regular peer. */
5645 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5646 /* Process peer route updates. */
5647 peer_on_policy_change(peer
, afi
, safi
,
5648 (direct
== FILTER_OUT
) ? 1 : 0);
5650 /* Skip peer-group mechanics for regular peers. */
5655 * Remove configuration on all peer-group members, unless they are
5656 * explicitely overriding peer-group configuration.
5658 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5659 /* Skip peers with overridden configuration. */
5660 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5661 PEER_FT_DISTRIBUTE_LIST
))
5664 /* Remove configuration on peer-group member. */
5665 filter
= &member
->filter
[afi
][safi
];
5666 if (filter
->dlist
[direct
].name
)
5667 XFREE(MTYPE_BGP_FILTER_NAME
,
5668 filter
->dlist
[direct
].name
);
5669 filter
->dlist
[direct
].name
= NULL
;
5670 filter
->dlist
[direct
].alist
= NULL
;
5672 /* Process peer route updates. */
5673 peer_on_policy_change(member
, afi
, safi
,
5674 (direct
== FILTER_OUT
) ? 1 : 0);
5680 /* Update distribute list. */
5681 static void peer_distribute_update(struct access_list
*access
)
5686 struct listnode
*mnode
, *mnnode
;
5687 struct listnode
*node
, *nnode
;
5690 struct peer_group
*group
;
5691 struct bgp_filter
*filter
;
5693 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5695 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5696 access
->name
, 0, 0);
5697 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5698 FOREACH_AFI_SAFI (afi
, safi
) {
5699 filter
= &peer
->filter
[afi
][safi
];
5701 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5703 if (filter
->dlist
[direct
].name
)
5704 filter
->dlist
[direct
]
5705 .alist
= access_list_lookup(
5707 filter
->dlist
[direct
]
5710 filter
->dlist
[direct
].alist
=
5715 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5716 FOREACH_AFI_SAFI (afi
, safi
) {
5717 filter
= &group
->conf
->filter
[afi
][safi
];
5719 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5721 if (filter
->dlist
[direct
].name
)
5722 filter
->dlist
[direct
]
5723 .alist
= access_list_lookup(
5725 filter
->dlist
[direct
]
5728 filter
->dlist
[direct
].alist
=
5734 vnc_prefix_list_update(bgp
);
5739 /* Set prefix list to the peer. */
5740 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5743 struct peer
*member
;
5744 struct bgp_filter
*filter
;
5745 struct listnode
*node
, *nnode
;
5747 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5748 return BGP_ERR_INVALID_VALUE
;
5750 /* Set configuration on peer. */
5751 filter
= &peer
->filter
[afi
][safi
];
5752 if (filter
->dlist
[direct
].name
)
5753 return BGP_ERR_PEER_FILTER_CONFLICT
;
5754 if (filter
->plist
[direct
].name
)
5755 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5756 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5757 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5759 /* Check if handling a regular peer. */
5760 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5761 /* Set override-flag and process peer route updates. */
5762 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5763 PEER_FT_PREFIX_LIST
);
5764 peer_on_policy_change(peer
, afi
, safi
,
5765 (direct
== FILTER_OUT
) ? 1 : 0);
5767 /* Skip peer-group mechanics for regular peers. */
5772 * Set configuration on all peer-group members, unless they are
5773 * explicitely overriding peer-group configuration.
5775 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5776 /* Skip peers with overridden configuration. */
5777 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5778 PEER_FT_PREFIX_LIST
))
5781 /* Set configuration on peer-group member. */
5782 filter
= &member
->filter
[afi
][safi
];
5783 if (filter
->plist
[direct
].name
)
5784 XFREE(MTYPE_BGP_FILTER_NAME
,
5785 filter
->plist
[direct
].name
);
5786 filter
->plist
[direct
].name
=
5787 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5788 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5790 /* Process peer route updates. */
5791 peer_on_policy_change(member
, afi
, safi
,
5792 (direct
== FILTER_OUT
) ? 1 : 0);
5798 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5801 struct peer
*member
;
5802 struct bgp_filter
*filter
;
5803 struct listnode
*node
, *nnode
;
5805 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5806 return BGP_ERR_INVALID_VALUE
;
5808 /* Unset override-flag unconditionally. */
5809 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5810 PEER_FT_PREFIX_LIST
);
5812 /* Inherit configuration from peer-group if peer is member. */
5813 if (peer_group_active(peer
)) {
5814 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5815 filter
[afi
][safi
].plist
[direct
].name
,
5816 MTYPE_BGP_FILTER_NAME
);
5817 PEER_ATTR_INHERIT(peer
, peer
->group
,
5818 filter
[afi
][safi
].plist
[direct
].plist
);
5820 /* Otherwise remove configuration from peer. */
5821 filter
= &peer
->filter
[afi
][safi
];
5822 if (filter
->plist
[direct
].name
)
5823 XFREE(MTYPE_BGP_FILTER_NAME
,
5824 filter
->plist
[direct
].name
);
5825 filter
->plist
[direct
].name
= NULL
;
5826 filter
->plist
[direct
].plist
= NULL
;
5829 /* Check if handling a regular peer. */
5830 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5831 /* Process peer route updates. */
5832 peer_on_policy_change(peer
, afi
, safi
,
5833 (direct
== FILTER_OUT
) ? 1 : 0);
5835 /* Skip peer-group mechanics for regular peers. */
5840 * Remove configuration on all peer-group members, unless they are
5841 * explicitely overriding peer-group configuration.
5843 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5844 /* Skip peers with overridden configuration. */
5845 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5846 PEER_FT_PREFIX_LIST
))
5849 /* Remove configuration on peer-group member. */
5850 filter
= &member
->filter
[afi
][safi
];
5851 if (filter
->plist
[direct
].name
)
5852 XFREE(MTYPE_BGP_FILTER_NAME
,
5853 filter
->plist
[direct
].name
);
5854 filter
->plist
[direct
].name
= NULL
;
5855 filter
->plist
[direct
].plist
= NULL
;
5857 /* Process peer route updates. */
5858 peer_on_policy_change(member
, afi
, safi
,
5859 (direct
== FILTER_OUT
) ? 1 : 0);
5865 /* Update prefix-list list. */
5866 static void peer_prefix_list_update(struct prefix_list
*plist
)
5868 struct listnode
*mnode
, *mnnode
;
5869 struct listnode
*node
, *nnode
;
5872 struct peer_group
*group
;
5873 struct bgp_filter
*filter
;
5878 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5881 * Update the prefix-list on update groups.
5883 update_group_policy_update(
5884 bgp
, BGP_POLICY_PREFIX_LIST
,
5885 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5887 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5888 FOREACH_AFI_SAFI (afi
, safi
) {
5889 filter
= &peer
->filter
[afi
][safi
];
5891 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5893 if (filter
->plist
[direct
].name
)
5894 filter
->plist
[direct
]
5895 .plist
= prefix_list_lookup(
5897 filter
->plist
[direct
]
5900 filter
->plist
[direct
].plist
=
5905 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5906 FOREACH_AFI_SAFI (afi
, safi
) {
5907 filter
= &group
->conf
->filter
[afi
][safi
];
5909 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5911 if (filter
->plist
[direct
].name
)
5912 filter
->plist
[direct
]
5913 .plist
= prefix_list_lookup(
5915 filter
->plist
[direct
]
5918 filter
->plist
[direct
].plist
=
5926 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5929 struct peer
*member
;
5930 struct bgp_filter
*filter
;
5931 struct listnode
*node
, *nnode
;
5933 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5934 return BGP_ERR_INVALID_VALUE
;
5936 /* Set configuration on peer. */
5937 filter
= &peer
->filter
[afi
][safi
];
5938 if (filter
->aslist
[direct
].name
)
5939 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5940 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5941 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5943 /* Check if handling a regular peer. */
5944 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5945 /* Set override-flag and process peer route updates. */
5946 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5947 PEER_FT_FILTER_LIST
);
5948 peer_on_policy_change(peer
, afi
, safi
,
5949 (direct
== FILTER_OUT
) ? 1 : 0);
5951 /* Skip peer-group mechanics for regular peers. */
5956 * Set configuration on all peer-group members, unless they are
5957 * explicitely overriding peer-group configuration.
5959 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5960 /* Skip peers with overridden configuration. */
5961 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5962 PEER_FT_FILTER_LIST
))
5965 /* Set configuration on peer-group member. */
5966 filter
= &member
->filter
[afi
][safi
];
5967 if (filter
->aslist
[direct
].name
)
5968 XFREE(MTYPE_BGP_FILTER_NAME
,
5969 filter
->aslist
[direct
].name
);
5970 filter
->aslist
[direct
].name
=
5971 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5972 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5974 /* Process peer route updates. */
5975 peer_on_policy_change(member
, afi
, safi
,
5976 (direct
== FILTER_OUT
) ? 1 : 0);
5982 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5984 struct peer
*member
;
5985 struct bgp_filter
*filter
;
5986 struct listnode
*node
, *nnode
;
5988 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5989 return BGP_ERR_INVALID_VALUE
;
5991 /* Unset override-flag unconditionally. */
5992 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5993 PEER_FT_FILTER_LIST
);
5995 /* Inherit configuration from peer-group if peer is member. */
5996 if (peer_group_active(peer
)) {
5997 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5998 filter
[afi
][safi
].aslist
[direct
].name
,
5999 MTYPE_BGP_FILTER_NAME
);
6000 PEER_ATTR_INHERIT(peer
, peer
->group
,
6001 filter
[afi
][safi
].aslist
[direct
].aslist
);
6003 /* Otherwise remove configuration from peer. */
6004 filter
= &peer
->filter
[afi
][safi
];
6005 if (filter
->aslist
[direct
].name
)
6006 XFREE(MTYPE_BGP_FILTER_NAME
,
6007 filter
->aslist
[direct
].name
);
6008 filter
->aslist
[direct
].name
= NULL
;
6009 filter
->aslist
[direct
].aslist
= NULL
;
6012 /* Check if handling a regular peer. */
6013 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6014 /* Process peer route updates. */
6015 peer_on_policy_change(peer
, afi
, safi
,
6016 (direct
== FILTER_OUT
) ? 1 : 0);
6018 /* Skip peer-group mechanics for regular peers. */
6023 * Remove configuration on all peer-group members, unless they are
6024 * explicitely overriding peer-group configuration.
6026 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6027 /* Skip peers with overridden configuration. */
6028 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6029 PEER_FT_FILTER_LIST
))
6032 /* Remove configuration on peer-group member. */
6033 filter
= &member
->filter
[afi
][safi
];
6034 if (filter
->aslist
[direct
].name
)
6035 XFREE(MTYPE_BGP_FILTER_NAME
,
6036 filter
->aslist
[direct
].name
);
6037 filter
->aslist
[direct
].name
= NULL
;
6038 filter
->aslist
[direct
].aslist
= NULL
;
6040 /* Process peer route updates. */
6041 peer_on_policy_change(member
, afi
, safi
,
6042 (direct
== FILTER_OUT
) ? 1 : 0);
6048 static void peer_aslist_update(const char *aslist_name
)
6053 struct listnode
*mnode
, *mnnode
;
6054 struct listnode
*node
, *nnode
;
6057 struct peer_group
*group
;
6058 struct bgp_filter
*filter
;
6060 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6061 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6064 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6065 FOREACH_AFI_SAFI (afi
, safi
) {
6066 filter
= &peer
->filter
[afi
][safi
];
6068 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6070 if (filter
->aslist
[direct
].name
)
6071 filter
->aslist
[direct
]
6072 .aslist
= as_list_lookup(
6073 filter
->aslist
[direct
]
6076 filter
->aslist
[direct
].aslist
=
6081 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6082 FOREACH_AFI_SAFI (afi
, safi
) {
6083 filter
= &group
->conf
->filter
[afi
][safi
];
6085 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6087 if (filter
->aslist
[direct
].name
)
6088 filter
->aslist
[direct
]
6089 .aslist
= as_list_lookup(
6090 filter
->aslist
[direct
]
6093 filter
->aslist
[direct
].aslist
=
6101 static void peer_aslist_add(char *aslist_name
)
6103 peer_aslist_update(aslist_name
);
6104 route_map_notify_dependencies((char *)aslist_name
,
6105 RMAP_EVENT_ASLIST_ADDED
);
6108 static void peer_aslist_del(const char *aslist_name
)
6110 peer_aslist_update(aslist_name
);
6111 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6115 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6116 const char *name
, struct route_map
*route_map
)
6118 struct peer
*member
;
6119 struct bgp_filter
*filter
;
6120 struct listnode
*node
, *nnode
;
6122 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6123 return BGP_ERR_INVALID_VALUE
;
6125 /* Set configuration on peer. */
6126 filter
= &peer
->filter
[afi
][safi
];
6127 if (filter
->map
[direct
].name
)
6128 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6129 route_map_counter_decrement(filter
->map
[direct
].map
);
6130 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6131 filter
->map
[direct
].map
= route_map
;
6132 route_map_counter_increment(route_map
);
6134 /* Check if handling a regular peer. */
6135 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6136 /* Set override-flag and process peer route updates. */
6137 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6139 peer_on_policy_change(peer
, afi
, safi
,
6140 (direct
== RMAP_OUT
) ? 1 : 0);
6142 /* Skip peer-group mechanics for regular peers. */
6147 * Set configuration on all peer-group members, unless they are
6148 * explicitely overriding peer-group configuration.
6150 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6151 /* Skip peers with overridden configuration. */
6152 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6156 /* Set configuration on peer-group member. */
6157 filter
= &member
->filter
[afi
][safi
];
6158 if (filter
->map
[direct
].name
)
6159 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6160 route_map_counter_decrement(filter
->map
[direct
].map
);
6161 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6162 filter
->map
[direct
].map
= route_map
;
6163 route_map_counter_increment(route_map
);
6165 /* Process peer route updates. */
6166 peer_on_policy_change(member
, afi
, safi
,
6167 (direct
== RMAP_OUT
) ? 1 : 0);
6172 /* Unset route-map from the peer. */
6173 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6175 struct peer
*member
;
6176 struct bgp_filter
*filter
;
6177 struct listnode
*node
, *nnode
;
6179 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6180 return BGP_ERR_INVALID_VALUE
;
6182 /* Unset override-flag unconditionally. */
6183 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6185 /* Inherit configuration from peer-group if peer is member. */
6186 if (peer_group_active(peer
)) {
6187 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6188 filter
[afi
][safi
].map
[direct
].name
,
6189 MTYPE_BGP_FILTER_NAME
);
6190 PEER_ATTR_INHERIT(peer
, peer
->group
,
6191 filter
[afi
][safi
].map
[direct
].map
);
6193 /* Otherwise remove configuration from peer. */
6194 filter
= &peer
->filter
[afi
][safi
];
6195 if (filter
->map
[direct
].name
)
6196 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6197 route_map_counter_decrement(filter
->map
[direct
].map
);
6198 filter
->map
[direct
].name
= NULL
;
6199 filter
->map
[direct
].map
= NULL
;
6202 /* Check if handling a regular peer. */
6203 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6204 /* Process peer route updates. */
6205 peer_on_policy_change(peer
, afi
, safi
,
6206 (direct
== RMAP_OUT
) ? 1 : 0);
6208 /* Skip peer-group mechanics for regular peers. */
6213 * Remove configuration on all peer-group members, unless they are
6214 * explicitely overriding peer-group configuration.
6216 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6217 /* Skip peers with overridden configuration. */
6218 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6222 /* Remove configuration on peer-group member. */
6223 filter
= &member
->filter
[afi
][safi
];
6224 if (filter
->map
[direct
].name
)
6225 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6226 route_map_counter_decrement(filter
->map
[direct
].map
);
6227 filter
->map
[direct
].name
= NULL
;
6228 filter
->map
[direct
].map
= NULL
;
6230 /* Process peer route updates. */
6231 peer_on_policy_change(member
, afi
, safi
,
6232 (direct
== RMAP_OUT
) ? 1 : 0);
6238 /* Set unsuppress-map to the peer. */
6239 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6240 const char *name
, struct route_map
*route_map
)
6242 struct peer
*member
;
6243 struct bgp_filter
*filter
;
6244 struct listnode
*node
, *nnode
;
6246 /* Set configuration on peer. */
6247 filter
= &peer
->filter
[afi
][safi
];
6248 if (filter
->usmap
.name
)
6249 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6250 route_map_counter_decrement(filter
->usmap
.map
);
6251 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6252 filter
->usmap
.map
= route_map
;
6253 route_map_counter_increment(route_map
);
6255 /* Check if handling a regular peer. */
6256 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6257 /* Set override-flag and process peer route updates. */
6258 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6259 PEER_FT_UNSUPPRESS_MAP
);
6260 peer_on_policy_change(peer
, afi
, safi
, 1);
6262 /* Skip peer-group mechanics for regular peers. */
6267 * Set configuration on all peer-group members, unless they are
6268 * explicitely overriding peer-group configuration.
6270 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6271 /* Skip peers with overridden configuration. */
6272 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6273 PEER_FT_UNSUPPRESS_MAP
))
6276 /* Set configuration on peer-group member. */
6277 filter
= &member
->filter
[afi
][safi
];
6278 if (filter
->usmap
.name
)
6279 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6280 route_map_counter_decrement(filter
->usmap
.map
);
6281 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6282 filter
->usmap
.map
= route_map
;
6283 route_map_counter_increment(route_map
);
6285 /* Process peer route updates. */
6286 peer_on_policy_change(member
, afi
, safi
, 1);
6292 /* Unset route-map from the peer. */
6293 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6295 struct peer
*member
;
6296 struct bgp_filter
*filter
;
6297 struct listnode
*node
, *nnode
;
6299 /* Unset override-flag unconditionally. */
6300 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6302 /* Inherit configuration from peer-group if peer is member. */
6303 if (peer_group_active(peer
)) {
6304 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6305 filter
[afi
][safi
].usmap
.name
,
6306 MTYPE_BGP_FILTER_NAME
);
6307 PEER_ATTR_INHERIT(peer
, peer
->group
,
6308 filter
[afi
][safi
].usmap
.map
);
6310 /* Otherwise remove configuration from peer. */
6311 filter
= &peer
->filter
[afi
][safi
];
6312 if (filter
->usmap
.name
)
6313 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6314 route_map_counter_decrement(filter
->usmap
.map
);
6315 filter
->usmap
.name
= NULL
;
6316 filter
->usmap
.map
= NULL
;
6319 /* Check if handling a regular peer. */
6320 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6321 /* Process peer route updates. */
6322 peer_on_policy_change(peer
, afi
, safi
, 1);
6324 /* Skip peer-group mechanics for regular peers. */
6329 * Remove configuration on all peer-group members, unless they are
6330 * explicitely overriding peer-group configuration.
6332 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6333 /* Skip peers with overridden configuration. */
6334 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6335 PEER_FT_UNSUPPRESS_MAP
))
6338 /* Remove configuration on peer-group member. */
6339 filter
= &member
->filter
[afi
][safi
];
6340 if (filter
->usmap
.name
)
6341 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6342 route_map_counter_decrement(filter
->usmap
.map
);
6343 filter
->usmap
.name
= NULL
;
6344 filter
->usmap
.map
= NULL
;
6346 /* Process peer route updates. */
6347 peer_on_policy_change(member
, afi
, safi
, 1);
6353 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6354 uint32_t max
, uint8_t threshold
, int warning
,
6357 struct peer
*member
;
6358 struct listnode
*node
, *nnode
;
6360 /* Set flags and configuration on peer. */
6361 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6363 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6365 peer_af_flag_unset(peer
, afi
, safi
,
6366 PEER_FLAG_MAX_PREFIX_WARNING
);
6368 peer
->pmax
[afi
][safi
] = max
;
6369 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6370 peer
->pmax_restart
[afi
][safi
] = restart
;
6372 /* Check if handling a regular peer. */
6373 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6374 /* Re-check if peer violates maximum-prefix. */
6375 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6376 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6378 /* Skip peer-group mechanics for regular peers. */
6383 * Set flags and configuration on all peer-group members, unless they
6384 * are explicitely overriding peer-group configuration.
6386 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6387 /* Skip peers with overridden configuration. */
6388 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6389 PEER_FLAG_MAX_PREFIX
))
6392 /* Set flag and configuration on peer-group member. */
6393 member
->pmax
[afi
][safi
] = max
;
6394 member
->pmax_threshold
[afi
][safi
] = threshold
;
6395 member
->pmax_restart
[afi
][safi
] = restart
;
6397 SET_FLAG(member
->af_flags
[afi
][safi
],
6398 PEER_FLAG_MAX_PREFIX_WARNING
);
6400 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6401 PEER_FLAG_MAX_PREFIX_WARNING
);
6403 /* Re-check if peer violates maximum-prefix. */
6404 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6405 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6411 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6413 /* Inherit configuration from peer-group if peer is member. */
6414 if (peer_group_active(peer
)) {
6415 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6416 peer_af_flag_inherit(peer
, afi
, safi
,
6417 PEER_FLAG_MAX_PREFIX_WARNING
);
6418 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6419 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6420 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6425 /* Remove flags and configuration from peer. */
6426 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6427 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6428 peer
->pmax
[afi
][safi
] = 0;
6429 peer
->pmax_threshold
[afi
][safi
] = 0;
6430 peer
->pmax_restart
[afi
][safi
] = 0;
6433 * Remove flags and configuration from all peer-group members, unless
6434 * they are explicitely overriding peer-group configuration.
6436 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6437 struct peer
*member
;
6438 struct listnode
*node
;
6440 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6441 /* Skip peers with overridden configuration. */
6442 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6443 PEER_FLAG_MAX_PREFIX
))
6446 /* Remove flag and configuration on peer-group member.
6448 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6449 PEER_FLAG_MAX_PREFIX
);
6450 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6451 PEER_FLAG_MAX_PREFIX_WARNING
);
6452 member
->pmax
[afi
][safi
] = 0;
6453 member
->pmax_threshold
[afi
][safi
] = 0;
6454 member
->pmax_restart
[afi
][safi
] = 0;
6461 int is_ebgp_multihop_configured(struct peer
*peer
)
6463 struct peer_group
*group
;
6464 struct listnode
*node
, *nnode
;
6467 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6468 group
= peer
->group
;
6469 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6470 && (group
->conf
->ttl
!= 1))
6473 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6474 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6475 && (peer1
->ttl
!= 1))
6479 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6485 /* Set # of hops between us and BGP peer. */
6486 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6488 struct peer_group
*group
;
6489 struct listnode
*node
, *nnode
;
6492 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6493 gtsm_hops
, peer
->host
);
6495 /* We cannot configure ttl-security hops when ebgp-multihop is already
6496 set. For non peer-groups, the check is simple. For peer-groups,
6498 slightly messy, because we need to check both the peer-group
6500 and all peer-group members for any trace of ebgp-multihop
6502 before actually applying the ttl-security rules. Cisco really made a
6503 mess of this configuration parameter, and OpenBGPD got it right.
6506 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6507 if (is_ebgp_multihop_configured(peer
))
6508 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6510 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6511 peer
->gtsm_hops
= gtsm_hops
;
6513 /* Calling ebgp multihop also resets the session.
6514 * On restart, NHT will get setup correctly as will the
6515 * min & max ttls on the socket. The return value is
6518 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6523 group
= peer
->group
;
6524 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6526 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6528 /* Calling ebgp multihop also resets the
6530 * On restart, NHT will get setup correctly as
6532 * min & max ttls on the socket. The return
6536 peer_ebgp_multihop_set(peer
, MAXTTL
);
6540 /* Post the first gtsm setup or if its ibgp, maxttl setting
6542 * necessary, just set the minttl.
6544 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6545 peer
->gtsm_hops
= gtsm_hops
;
6548 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6549 MAXTTL
+ 1 - gtsm_hops
);
6550 if ((peer
->status
< Established
) && peer
->doppelganger
6551 && (peer
->doppelganger
->fd
>= 0))
6552 sockopt_minttl(peer
->su
.sa
.sa_family
,
6553 peer
->doppelganger
->fd
,
6554 MAXTTL
+ 1 - gtsm_hops
);
6556 group
= peer
->group
;
6557 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6559 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6561 /* Change setting of existing peer
6562 * established then change value (may break
6564 * not established yet (teardown session and
6566 * no session then do nothing (will get
6567 * handled by next connection)
6569 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6571 peer
->su
.sa
.sa_family
, peer
->fd
,
6572 MAXTTL
+ 1 - peer
->gtsm_hops
);
6573 if ((peer
->status
< Established
)
6574 && peer
->doppelganger
6575 && (peer
->doppelganger
->fd
>= 0))
6576 sockopt_minttl(peer
->su
.sa
.sa_family
,
6577 peer
->doppelganger
->fd
,
6578 MAXTTL
+ 1 - gtsm_hops
);
6586 int peer_ttl_security_hops_unset(struct peer
*peer
)
6588 struct peer_group
*group
;
6589 struct listnode
*node
, *nnode
;
6592 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6595 /* if a peer-group member, then reset to peer-group default rather than
6597 if (peer_group_active(peer
))
6598 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6600 peer
->gtsm_hops
= 0;
6602 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6603 /* Invoking ebgp_multihop_set will set the TTL back to the
6605 * value as well as restting the NHT and such. The session is
6608 if (peer
->sort
== BGP_PEER_EBGP
)
6609 ret
= peer_ebgp_multihop_unset(peer
);
6612 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6615 if ((peer
->status
< Established
) && peer
->doppelganger
6616 && (peer
->doppelganger
->fd
>= 0))
6617 sockopt_minttl(peer
->su
.sa
.sa_family
,
6618 peer
->doppelganger
->fd
, 0);
6621 group
= peer
->group
;
6622 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6623 peer
->gtsm_hops
= 0;
6624 if (peer
->sort
== BGP_PEER_EBGP
)
6625 ret
= peer_ebgp_multihop_unset(peer
);
6628 sockopt_minttl(peer
->su
.sa
.sa_family
,
6631 if ((peer
->status
< Established
)
6632 && peer
->doppelganger
6633 && (peer
->doppelganger
->fd
>= 0))
6634 sockopt_minttl(peer
->su
.sa
.sa_family
,
6635 peer
->doppelganger
->fd
,
6645 * If peer clear is invoked in a loop for all peers on the BGP instance,
6646 * it may end up freeing the doppelganger, and if this was the next node
6647 * to the current node, we would end up accessing the freed next node.
6648 * Pass along additional parameter which can be updated if next node
6649 * is freed; only required when walking the peer list on BGP instance.
6651 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6653 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6654 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6655 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6656 if (peer
->t_pmax_restart
) {
6657 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6658 if (bgp_debug_neighbor_events(peer
))
6660 "%s Maximum-prefix restart timer canceled",
6663 BGP_EVENT_ADD(peer
, BGP_Start
);
6667 peer
->v_start
= BGP_INIT_START_TIMER
;
6668 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6669 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6670 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6672 bgp_session_reset_safe(peer
, nnode
);
6677 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6678 enum bgp_clear_type stype
)
6680 struct peer_af
*paf
;
6682 if (peer
->status
!= Established
)
6685 if (!peer
->afc
[afi
][safi
])
6686 return BGP_ERR_AF_UNCONFIGURED
;
6688 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6690 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6691 /* Clear the "neighbor x.x.x.x default-originate" flag */
6692 paf
= peer_af_find(peer
, afi
, safi
);
6693 if (paf
&& paf
->subgroup
6694 && CHECK_FLAG(paf
->subgroup
->sflags
,
6695 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6696 UNSET_FLAG(paf
->subgroup
->sflags
,
6697 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6699 bgp_announce_route(peer
, afi
, safi
);
6702 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6703 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6704 PEER_CAP_ORF_PREFIX_SM_ADV
)
6705 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6706 PEER_CAP_ORF_PREFIX_RM_RCV
)
6707 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6708 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6709 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6710 uint8_t prefix_type
;
6712 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6713 PEER_CAP_ORF_PREFIX_RM_RCV
))
6714 prefix_type
= ORF_TYPE_PREFIX
;
6716 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6718 if (filter
->plist
[FILTER_IN
].plist
) {
6719 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6720 PEER_STATUS_ORF_PREFIX_SEND
))
6721 bgp_route_refresh_send(
6722 peer
, afi
, safi
, prefix_type
,
6724 bgp_route_refresh_send(peer
, afi
, safi
,
6726 REFRESH_IMMEDIATE
, 0);
6728 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6729 PEER_STATUS_ORF_PREFIX_SEND
))
6730 bgp_route_refresh_send(
6731 peer
, afi
, safi
, prefix_type
,
6732 REFRESH_IMMEDIATE
, 1);
6734 bgp_route_refresh_send(peer
, afi
, safi
,
6741 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6742 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6743 /* If neighbor has soft reconfiguration inbound flag.
6744 Use Adj-RIB-In database. */
6745 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6746 PEER_FLAG_SOFT_RECONFIG
))
6747 bgp_soft_reconfig_in(peer
, afi
, safi
);
6749 /* If neighbor has route refresh capability, send route
6751 message to the peer. */
6752 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6753 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6754 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6757 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6763 /* Display peer uptime.*/
6764 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6767 time_t uptime1
, epoch_tbuf
;
6770 /* If there is no connection has been done before print `never'. */
6773 json_object_string_add(json
, "peerUptime", "never");
6774 json_object_int_add(json
, "peerUptimeMsec", 0);
6776 snprintf(buf
, len
, "never");
6780 /* Get current time. */
6781 uptime1
= bgp_clock();
6783 tm
= gmtime(&uptime1
);
6785 if (uptime1
< ONE_DAY_SECOND
)
6786 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6788 else if (uptime1
< ONE_WEEK_SECOND
)
6789 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6791 else if (uptime1
< ONE_YEAR_SECOND
)
6792 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6793 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6795 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6797 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6800 epoch_tbuf
= time(NULL
) - uptime1
;
6801 json_object_string_add(json
, "peerUptime", buf
);
6802 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6803 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6810 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6811 afi_t afi
, safi_t safi
)
6813 struct bgp_filter
*filter
;
6817 filter
= &peer
->filter
[afi
][safi
];
6819 /* distribute-list. */
6820 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6822 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6823 filter
->dlist
[FILTER_IN
].name
);
6825 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6827 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6828 filter
->dlist
[FILTER_OUT
].name
);
6831 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6833 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6834 filter
->plist
[FILTER_IN
].name
);
6836 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6838 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6839 filter
->plist
[FILTER_OUT
].name
);
6842 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6843 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6844 filter
->map
[RMAP_IN
].name
);
6846 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6848 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6849 filter
->map
[RMAP_OUT
].name
);
6851 /* unsuppress-map */
6852 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6853 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6854 filter
->usmap
.name
);
6857 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6859 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6860 filter
->aslist
[FILTER_IN
].name
);
6862 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6864 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6865 filter
->aslist
[FILTER_OUT
].name
);
6868 /* BGP peer configuration display function. */
6869 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6872 struct peer
*g_peer
= NULL
;
6873 char buf
[SU_ADDRSTRLEN
];
6875 int if_pg_printed
= FALSE
;
6876 int if_ras_printed
= FALSE
;
6878 /* Skip dynamic neighbors. */
6879 if (peer_dynamic_neighbor(peer
))
6883 addr
= peer
->conf_if
;
6887 /************************************
6888 ****** Global to the neighbor ******
6889 ************************************/
6890 if (peer
->conf_if
) {
6891 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6892 vty_out(vty
, " neighbor %s interface v6only", addr
);
6894 vty_out(vty
, " neighbor %s interface", addr
);
6896 if (peer_group_active(peer
)) {
6897 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6898 if_pg_printed
= TRUE
;
6899 } else if (peer
->as_type
== AS_SPECIFIED
) {
6900 vty_out(vty
, " remote-as %u", peer
->as
);
6901 if_ras_printed
= TRUE
;
6902 } else if (peer
->as_type
== AS_INTERNAL
) {
6903 vty_out(vty
, " remote-as internal");
6904 if_ras_printed
= TRUE
;
6905 } else if (peer
->as_type
== AS_EXTERNAL
) {
6906 vty_out(vty
, " remote-as external");
6907 if_ras_printed
= TRUE
;
6913 /* remote-as and peer-group */
6914 /* peer is a member of a peer-group */
6915 if (peer_group_active(peer
)) {
6916 g_peer
= peer
->group
->conf
;
6918 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6919 if (peer
->as_type
== AS_SPECIFIED
) {
6920 vty_out(vty
, " neighbor %s remote-as %u\n",
6922 } else if (peer
->as_type
== AS_INTERNAL
) {
6924 " neighbor %s remote-as internal\n",
6926 } else if (peer
->as_type
== AS_EXTERNAL
) {
6928 " neighbor %s remote-as external\n",
6933 /* For swpX peers we displayed the peer-group
6934 * via 'neighbor swpX interface peer-group WORD' */
6936 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6940 /* peer is NOT a member of a peer-group */
6942 /* peer is a peer-group, declare the peer-group */
6943 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6944 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6947 if (!if_ras_printed
) {
6948 if (peer
->as_type
== AS_SPECIFIED
) {
6949 vty_out(vty
, " neighbor %s remote-as %u\n",
6951 } else if (peer
->as_type
== AS_INTERNAL
) {
6953 " neighbor %s remote-as internal\n",
6955 } else if (peer
->as_type
== AS_EXTERNAL
) {
6957 " neighbor %s remote-as external\n",
6964 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
6965 vty_out(vty
, " neighbor %s local-as %u", addr
,
6966 peer
->change_local_as
);
6967 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6968 vty_out(vty
, " no-prepend");
6969 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
6970 vty_out(vty
, " replace-as");
6976 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6980 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
6981 if (peer
->tx_shutdown_message
)
6982 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
6983 peer
->tx_shutdown_message
);
6985 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6989 if (peer
->bfd_info
) {
6990 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6991 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6996 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
6997 vty_out(vty
, " neighbor %s password %s\n", addr
,
7001 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
7002 if (!peer_group_active(peer
)) {
7003 vty_out(vty
, " neighbor %s solo\n", addr
);
7008 if (peer
->port
!= BGP_PORT_DEFAULT
) {
7009 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
7012 /* Local interface name */
7014 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
7018 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
7019 vty_out(vty
, " neighbor %s passive\n", addr
);
7022 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
7023 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
7024 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
7025 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
7030 /* ttl-security hops */
7031 if (peer
->gtsm_hops
!= 0) {
7032 if (!peer_group_active(peer
)
7033 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
7034 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
7035 addr
, peer
->gtsm_hops
);
7039 /* disable-connected-check */
7040 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
7041 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
7043 /* enforce-first-as */
7044 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
7045 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
7048 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
7049 if (peer
->update_source
)
7050 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7051 sockunion2str(peer
->update_source
, buf
,
7053 else if (peer
->update_if
)
7054 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7058 /* advertisement-interval */
7059 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7060 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7064 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7065 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7066 peer
->keepalive
, peer
->holdtime
);
7068 /* timers connect */
7069 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7070 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7073 /* capability dynamic */
7074 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7075 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7077 /* capability extended-nexthop */
7078 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7079 if (!peer
->conf_if
) {
7080 if (CHECK_FLAG(peer
->flags_invert
,
7081 PEER_FLAG_CAPABILITY_ENHE
))
7083 " no neighbor %s capability extended-nexthop\n",
7087 " neighbor %s capability extended-nexthop\n",
7092 /* dont-capability-negotiation */
7093 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7094 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7096 /* override-capability */
7097 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7098 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7100 /* strict-capability-match */
7101 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7102 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7105 /* BGP peer configuration display function. */
7106 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7107 struct peer
*peer
, afi_t afi
, safi_t safi
)
7109 struct peer
*g_peer
= NULL
;
7111 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7113 /* Skip dynamic neighbors. */
7114 if (peer_dynamic_neighbor(peer
))
7118 addr
= peer
->conf_if
;
7122 /************************************
7123 ****** Per AF to the neighbor ******
7124 ************************************/
7125 if (peer_group_active(peer
)) {
7126 g_peer
= peer
->group
->conf
;
7128 /* If the peer-group is active but peer is not, print a 'no
7130 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7131 vty_out(vty
, " no neighbor %s activate\n", addr
);
7134 /* If the peer-group is not active but peer is, print an
7136 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7137 vty_out(vty
, " neighbor %s activate\n", addr
);
7140 if (peer
->afc
[afi
][safi
]) {
7141 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7142 if (bgp_flag_check(bgp
,
7143 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7144 vty_out(vty
, " neighbor %s activate\n",
7148 vty_out(vty
, " neighbor %s activate\n", addr
);
7150 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7151 if (!bgp_flag_check(bgp
,
7152 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7154 " no neighbor %s activate\n",
7161 /* addpath TX knobs */
7162 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7163 switch (peer
->addpath_type
[afi
][safi
]) {
7164 case BGP_ADDPATH_ALL
:
7165 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7168 case BGP_ADDPATH_BEST_PER_AS
:
7170 " neighbor %s addpath-tx-bestpath-per-AS\n",
7173 case BGP_ADDPATH_MAX
:
7174 case BGP_ADDPATH_NONE
:
7179 /* ORF capability. */
7180 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7181 || peergroup_af_flag_check(peer
, afi
, safi
,
7182 PEER_FLAG_ORF_PREFIX_RM
)) {
7183 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7185 if (peergroup_af_flag_check(peer
, afi
, safi
,
7186 PEER_FLAG_ORF_PREFIX_SM
)
7187 && peergroup_af_flag_check(peer
, afi
, safi
,
7188 PEER_FLAG_ORF_PREFIX_RM
))
7189 vty_out(vty
, " both");
7190 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7191 PEER_FLAG_ORF_PREFIX_SM
))
7192 vty_out(vty
, " send");
7194 vty_out(vty
, " receive");
7198 /* Route reflector client. */
7199 if (peergroup_af_flag_check(peer
, afi
, safi
,
7200 PEER_FLAG_REFLECTOR_CLIENT
)) {
7201 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7204 /* next-hop-self force */
7205 if (peergroup_af_flag_check(peer
, afi
, safi
,
7206 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7207 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7211 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7212 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7215 /* remove-private-AS */
7216 if (peergroup_af_flag_check(peer
, afi
, safi
,
7217 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7218 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7222 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7223 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7224 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7228 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7229 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7230 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7233 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7234 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7235 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7239 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7240 vty_out(vty
, " neighbor %s as-override\n", addr
);
7243 /* send-community print. */
7244 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7245 PEER_FLAG_SEND_COMMUNITY
);
7246 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7247 PEER_FLAG_SEND_EXT_COMMUNITY
);
7248 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7249 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7251 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7252 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7253 vty_out(vty
, " no neighbor %s send-community all\n",
7258 " no neighbor %s send-community\n",
7262 " no neighbor %s send-community extended\n",
7267 " no neighbor %s send-community large\n",
7271 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7272 vty_out(vty
, " neighbor %s send-community all\n",
7274 } else if (flag_scomm
&& flag_secomm
) {
7275 vty_out(vty
, " neighbor %s send-community both\n",
7279 vty_out(vty
, " neighbor %s send-community\n",
7283 " neighbor %s send-community extended\n",
7287 " neighbor %s send-community large\n",
7292 /* Default information */
7293 if (peergroup_af_flag_check(peer
, afi
, safi
,
7294 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7295 vty_out(vty
, " neighbor %s default-originate", addr
);
7297 if (peer
->default_rmap
[afi
][safi
].name
)
7298 vty_out(vty
, " route-map %s",
7299 peer
->default_rmap
[afi
][safi
].name
);
7304 /* Soft reconfiguration inbound. */
7305 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7306 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7310 /* maximum-prefix. */
7311 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7312 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7313 peer
->pmax
[afi
][safi
]);
7315 if (peer
->pmax_threshold
[afi
][safi
]
7316 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7317 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7318 if (peer_af_flag_check(peer
, afi
, safi
,
7319 PEER_FLAG_MAX_PREFIX_WARNING
))
7320 vty_out(vty
, " warning-only");
7321 if (peer
->pmax_restart
[afi
][safi
])
7322 vty_out(vty
, " restart %u",
7323 peer
->pmax_restart
[afi
][safi
]);
7328 /* Route server client. */
7329 if (peergroup_af_flag_check(peer
, afi
, safi
,
7330 PEER_FLAG_RSERVER_CLIENT
)) {
7331 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7334 /* Nexthop-local unchanged. */
7335 if (peergroup_af_flag_check(peer
, afi
, safi
,
7336 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7337 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7340 /* allowas-in <1-10> */
7341 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7342 if (peer_af_flag_check(peer
, afi
, safi
,
7343 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7344 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7345 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7346 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7348 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7349 peer
->allowas_in
[afi
][safi
]);
7354 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7355 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7356 peer
->weight
[afi
][safi
]);
7359 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7361 /* atribute-unchanged. */
7362 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7363 || (safi
!= SAFI_EVPN
7364 && peer_af_flag_check(peer
, afi
, safi
,
7365 PEER_FLAG_NEXTHOP_UNCHANGED
))
7366 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7368 if (!peer_group_active(peer
)
7369 || peergroup_af_flag_check(peer
, afi
, safi
,
7370 PEER_FLAG_AS_PATH_UNCHANGED
)
7371 || peergroup_af_flag_check(peer
, afi
, safi
,
7372 PEER_FLAG_NEXTHOP_UNCHANGED
)
7373 || peergroup_af_flag_check(peer
, afi
, safi
,
7374 PEER_FLAG_MED_UNCHANGED
)) {
7377 " neighbor %s attribute-unchanged%s%s%s\n",
7379 peer_af_flag_check(peer
, afi
, safi
,
7380 PEER_FLAG_AS_PATH_UNCHANGED
)
7383 peer_af_flag_check(peer
, afi
, safi
,
7384 PEER_FLAG_NEXTHOP_UNCHANGED
)
7387 peer_af_flag_check(peer
, afi
, safi
,
7388 PEER_FLAG_MED_UNCHANGED
)
7395 /* Address family based peer configuration display. */
7396 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7400 struct peer_group
*group
;
7401 struct listnode
*node
, *nnode
;
7404 vty_frame(vty
, " !\n address-family ");
7405 if (afi
== AFI_IP
) {
7406 if (safi
== SAFI_UNICAST
)
7407 vty_frame(vty
, "ipv4 unicast");
7408 else if (safi
== SAFI_LABELED_UNICAST
)
7409 vty_frame(vty
, "ipv4 labeled-unicast");
7410 else if (safi
== SAFI_MULTICAST
)
7411 vty_frame(vty
, "ipv4 multicast");
7412 else if (safi
== SAFI_MPLS_VPN
)
7413 vty_frame(vty
, "ipv4 vpn");
7414 else if (safi
== SAFI_ENCAP
)
7415 vty_frame(vty
, "ipv4 encap");
7416 else if (safi
== SAFI_FLOWSPEC
)
7417 vty_frame(vty
, "ipv4 flowspec");
7418 } else if (afi
== AFI_IP6
) {
7419 if (safi
== SAFI_UNICAST
)
7420 vty_frame(vty
, "ipv6 unicast");
7421 else if (safi
== SAFI_LABELED_UNICAST
)
7422 vty_frame(vty
, "ipv6 labeled-unicast");
7423 else if (safi
== SAFI_MULTICAST
)
7424 vty_frame(vty
, "ipv6 multicast");
7425 else if (safi
== SAFI_MPLS_VPN
)
7426 vty_frame(vty
, "ipv6 vpn");
7427 else if (safi
== SAFI_ENCAP
)
7428 vty_frame(vty
, "ipv6 encap");
7429 else if (safi
== SAFI_FLOWSPEC
)
7430 vty_frame(vty
, "ipv6 flowspec");
7431 } else if (afi
== AFI_L2VPN
) {
7432 if (safi
== SAFI_EVPN
)
7433 vty_frame(vty
, "l2vpn evpn");
7435 vty_frame(vty
, "\n");
7437 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7439 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7441 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7443 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7444 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7446 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7447 /* Skip dynamic neighbors. */
7448 if (peer_dynamic_neighbor(peer
))
7451 /* Do not display doppelganger peers */
7452 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7453 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7456 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7457 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7459 if (safi
== SAFI_EVPN
)
7460 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7462 if (safi
== SAFI_FLOWSPEC
)
7463 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7465 if (safi
== SAFI_UNICAST
) {
7466 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7467 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7468 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7470 vty_out(vty
, " export vpn\n");
7472 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7473 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7475 vty_out(vty
, " import vpn\n");
7477 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7478 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7481 for (ALL_LIST_ELEMENTS_RO(
7482 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7484 vty_out(vty
, " import vrf %s\n", name
);
7488 vty_endframe(vty
, " exit-address-family\n");
7491 /* clang-format off */
7492 #if CONFDATE > 20190517
7493 CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
7495 /* clang-format on */
7497 int bgp_config_write(struct vty
*vty
)
7501 struct peer_group
*group
;
7503 struct listnode
*node
, *nnode
;
7504 struct listnode
*mnode
, *mnnode
;
7506 /* BGP Multiple instance. */
7507 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7508 vty_out(vty
, "no bgp multiple-instance\n");
7512 /* BGP Config type. */
7513 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7514 vty_out(vty
, "bgp config-type cisco\n");
7518 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7519 vty_out(vty
, "bgp route-map delay-timer %u\n",
7520 bm
->rmap_update_timer
);
7523 vty_out(vty
, "!\n");
7525 /* BGP configuration. */
7526 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7528 /* skip all auto created vrf as they dont have user config */
7529 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7532 /* Migrate deprecated 'bgp enforce-first-as'
7533 * config to 'neighbor * enforce-first-as' configs
7535 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
)) {
7536 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7537 peer_flag_set(peer
, PEER_FLAG_ENFORCE_FIRST_AS
);
7538 bgp_flag_unset(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
);
7541 /* Router bgp ASN */
7542 vty_out(vty
, "router bgp %u", bgp
->as
);
7544 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7546 vty_out(vty
, " %s %s",
7548 == BGP_INSTANCE_TYPE_VIEW
)
7555 /* No Synchronization */
7556 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7557 vty_out(vty
, " no synchronization\n");
7559 /* BGP fast-external-failover. */
7560 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7561 vty_out(vty
, " no bgp fast-external-failover\n");
7563 /* BGP router ID. */
7564 if (bgp
->router_id_static
.s_addr
!= 0)
7565 vty_out(vty
, " bgp router-id %s\n",
7566 inet_ntoa(bgp
->router_id_static
));
7568 /* BGP log-neighbor-changes. */
7569 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7570 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7571 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7573 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7577 /* BGP configuration. */
7578 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7579 vty_out(vty
, " bgp always-compare-med\n");
7581 /* RFC8212 default eBGP policy. */
7582 if (bgp
->ebgp_requires_policy
7583 == DEFAULT_EBGP_POLICY_ENABLED
)
7584 vty_out(vty
, " bgp ebgp-requires-policy\n");
7586 /* BGP default ipv4-unicast. */
7587 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7588 vty_out(vty
, " no bgp default ipv4-unicast\n");
7590 /* BGP default local-preference. */
7591 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7592 vty_out(vty
, " bgp default local-preference %u\n",
7593 bgp
->default_local_pref
);
7595 /* BGP default show-hostname */
7596 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7597 != DFLT_BGP_SHOW_HOSTNAME
)
7598 vty_out(vty
, " %sbgp default show-hostname\n",
7599 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7603 /* BGP default subgroup-pkt-queue-max. */
7604 if (bgp
->default_subgroup_pkt_queue_max
7605 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7606 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7607 bgp
->default_subgroup_pkt_queue_max
);
7609 /* BGP client-to-client reflection. */
7610 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7611 vty_out(vty
, " no bgp client-to-client reflection\n");
7613 /* BGP cluster ID. */
7614 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7615 vty_out(vty
, " bgp cluster-id %s\n",
7616 inet_ntoa(bgp
->cluster_id
));
7618 /* Disable ebgp connected nexthop check */
7619 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7621 " bgp disable-ebgp-connected-route-check\n");
7623 /* Confederation identifier*/
7624 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7625 vty_out(vty
, " bgp confederation identifier %u\n",
7628 /* Confederation peer */
7629 if (bgp
->confed_peers_cnt
> 0) {
7632 vty_out(vty
, " bgp confederation peers");
7634 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7635 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7640 /* BGP deterministic-med. */
7641 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7642 != DFLT_BGP_DETERMINISTIC_MED
)
7643 vty_out(vty
, " %sbgp deterministic-med\n",
7644 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7648 /* BGP update-delay. */
7649 bgp_config_write_update_delay(vty
, bgp
);
7651 if (bgp
->v_maxmed_onstartup
7652 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7653 vty_out(vty
, " bgp max-med on-startup %u",
7654 bgp
->v_maxmed_onstartup
);
7655 if (bgp
->maxmed_onstartup_value
7656 != BGP_MAXMED_VALUE_DEFAULT
)
7658 bgp
->maxmed_onstartup_value
);
7661 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7662 vty_out(vty
, " bgp max-med administrative");
7663 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7664 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7669 bgp_config_write_wpkt_quanta(vty
, bgp
);
7671 bgp_config_write_rpkt_quanta(vty
, bgp
);
7674 bgp_config_write_coalesce_time(vty
, bgp
);
7676 /* BGP graceful-restart. */
7677 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7679 " bgp graceful-restart stalepath-time %u\n",
7680 bgp
->stalepath_time
);
7681 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7682 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7684 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7685 vty_out(vty
, " bgp graceful-restart\n");
7687 /* BGP graceful-shutdown */
7688 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7689 vty_out(vty
, " bgp graceful-shutdown\n");
7691 /* BGP graceful-restart Preserve State F bit. */
7692 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7694 " bgp graceful-restart preserve-fw-state\n");
7696 /* BGP bestpath method. */
7697 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7698 vty_out(vty
, " bgp bestpath as-path ignore\n");
7699 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7700 vty_out(vty
, " bgp bestpath as-path confed\n");
7702 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7703 if (bgp_flag_check(bgp
,
7704 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7706 " bgp bestpath as-path multipath-relax as-set\n");
7709 " bgp bestpath as-path multipath-relax\n");
7713 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7715 " bgp route-reflector allow-outbound-policy\n");
7717 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7718 vty_out(vty
, " bgp bestpath compare-routerid\n");
7719 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7720 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7721 vty_out(vty
, " bgp bestpath med");
7722 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7723 vty_out(vty
, " confed");
7724 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7725 vty_out(vty
, " missing-as-worst");
7729 /* BGP network import check. */
7730 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7731 != DFLT_BGP_IMPORT_CHECK
)
7732 vty_out(vty
, " %sbgp network import-check\n",
7733 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7737 /* BGP flag dampening. */
7738 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7739 BGP_CONFIG_DAMPENING
))
7740 bgp_config_write_damp(vty
);
7742 /* BGP timers configuration. */
7743 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7744 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7745 vty_out(vty
, " timers bgp %u %u\n",
7746 bgp
->default_keepalive
, bgp
->default_holdtime
);
7749 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7750 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7753 /* Normal neighbor configuration. */
7754 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7755 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7756 bgp_config_write_peer_global(vty
, bgp
, peer
);
7759 /* listen range and limit for dynamic BGP neighbors */
7760 bgp_config_write_listen(vty
, bgp
);
7763 * BGP default autoshutdown neighbors
7765 * This must be placed after any peer and peer-group
7766 * configuration, to avoid setting all peers to shutdown after
7767 * a daemon restart, which is undesired behavior. (see #2286)
7769 if (bgp
->autoshutdown
)
7770 vty_out(vty
, " bgp default shutdown\n");
7772 /* No auto-summary */
7773 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7774 vty_out(vty
, " no auto-summary\n");
7776 /* IPv4 unicast configuration. */
7777 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7779 /* IPv4 multicast configuration. */
7780 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7782 /* IPv4 labeled-unicast configuration. */
7783 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7785 /* IPv4 VPN configuration. */
7786 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7788 /* ENCAPv4 configuration. */
7789 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7791 /* FLOWSPEC v4 configuration. */
7792 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7794 /* IPv6 unicast configuration. */
7795 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7797 /* IPv6 multicast configuration. */
7798 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7800 /* IPv6 labeled-unicast configuration. */
7801 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7802 SAFI_LABELED_UNICAST
);
7804 /* IPv6 VPN configuration. */
7805 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7807 /* ENCAPv6 configuration. */
7808 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7810 /* FLOWSPEC v6 configuration. */
7811 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7813 /* EVPN configuration. */
7814 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7817 bgp_rfapi_cfg_write(vty
, bgp
);
7820 vty_out(vty
, "!\n");
7825 void bgp_master_init(struct thread_master
*master
)
7829 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7832 bm
->bgp
= list_new();
7833 bm
->listen_sockets
= list_new();
7834 bm
->port
= BGP_PORT_DEFAULT
;
7835 bm
->master
= master
;
7836 bm
->start_time
= bgp_clock();
7837 bm
->t_rmap_update
= NULL
;
7838 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7839 bm
->terminating
= false;
7841 bgp_process_queue_init();
7844 /* init the rd id space.
7845 assign 0th index in the bitfield,
7846 so that we start with id 1
7848 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7849 bf_assign_zero_index(bm
->rd_idspace
);
7851 /* Enable multiple instances by default. */
7852 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7854 /* mpls label dynamic allocation pool */
7855 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7857 QOBJ_REG(bm
, bgp_master
);
7861 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7862 * instance delete (non-default only) or BGP exit.
7864 static void bgp_if_finish(struct bgp
*bgp
)
7867 struct interface
*ifp
;
7869 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
7871 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7874 FOR_ALL_INTERFACES (vrf
, ifp
) {
7875 struct listnode
*c_node
, *c_nnode
;
7876 struct connected
*c
;
7878 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7879 bgp_connected_delete(bgp
, c
);
7883 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7885 struct vrf
*vrf
= NULL
;
7886 struct listnode
*next
;
7889 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7890 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7892 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7893 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7896 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7900 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7901 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7902 {.completions
= NULL
},
7905 struct frr_pthread
*bgp_pth_io
;
7906 struct frr_pthread
*bgp_pth_ka
;
7908 static void bgp_pthreads_init(void)
7910 assert(!bgp_pth_io
);
7911 assert(!bgp_pth_ka
);
7915 struct frr_pthread_attr io
= {
7916 .start
= frr_pthread_attr_default
.start
,
7917 .stop
= frr_pthread_attr_default
.stop
,
7919 struct frr_pthread_attr ka
= {
7920 .start
= bgp_keepalives_start
,
7921 .stop
= bgp_keepalives_stop
,
7923 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7924 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7927 void bgp_pthreads_run(void)
7929 frr_pthread_run(bgp_pth_io
, NULL
);
7930 frr_pthread_run(bgp_pth_ka
, NULL
);
7932 /* Wait until threads are ready. */
7933 frr_pthread_wait_running(bgp_pth_io
);
7934 frr_pthread_wait_running(bgp_pth_ka
);
7937 void bgp_pthreads_finish(void)
7939 frr_pthread_stop_all();
7940 frr_pthread_finish();
7943 void bgp_init(unsigned short instance
)
7946 /* allocates some vital data structures used by peer commands in
7949 /* pre-init pthreads */
7950 bgp_pthreads_init();
7953 bgp_zebra_init(bm
->master
, instance
);
7956 vnc_zebra_init(bm
->master
);
7959 /* BGP VTY commands installation. */
7967 bgp_route_map_init();
7968 bgp_scan_vty_init();
7973 bgp_ethernetvpn_init();
7974 bgp_flowspec_vty_init();
7976 /* Access list initialize. */
7978 access_list_add_hook(peer_distribute_update
);
7979 access_list_delete_hook(peer_distribute_update
);
7981 /* Filter list initialize. */
7983 as_list_add_hook(peer_aslist_add
);
7984 as_list_delete_hook(peer_aslist_del
);
7986 /* Prefix list initialize.*/
7988 prefix_list_add_hook(peer_prefix_list_update
);
7989 prefix_list_delete_hook(peer_prefix_list_update
);
7991 /* Community list initialize. */
7992 bgp_clist
= community_list_init();
7997 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
8000 void bgp_terminate(void)
8004 struct listnode
*node
, *nnode
;
8005 struct listnode
*mnode
, *mnnode
;
8009 /* Close the listener sockets first as this prevents peers from
8011 * to reconnect on receiving the peer unconfig message. In the presence
8012 * of a large number of peers this will ensure that no peer is left with
8013 * a dangling connection
8015 /* reverse bgp_master_init */
8018 if (bm
->listen_sockets
)
8019 list_delete(&bm
->listen_sockets
);
8021 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
8022 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
8023 if (peer
->status
== Established
8024 || peer
->status
== OpenSent
8025 || peer
->status
== OpenConfirm
)
8026 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
8027 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
8029 if (bm
->process_main_queue
)
8030 work_queue_free_and_null(&bm
->process_main_queue
);
8032 if (bm
->t_rmap_update
)
8033 BGP_TIMER_OFF(bm
->t_rmap_update
);