1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
49 #include "bgpd/bgpd.h"
50 #include "bgpd/bgp_table.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_route.h"
53 #include "bgpd/bgp_dump.h"
54 #include "bgpd/bgp_debug.h"
55 #include "bgpd/bgp_errors.h"
56 #include "bgpd/bgp_community.h"
57 #include "bgpd/bgp_attr.h"
58 #include "bgpd/bgp_regex.h"
59 #include "bgpd/bgp_clist.h"
60 #include "bgpd/bgp_fsm.h"
61 #include "bgpd/bgp_packet.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_open.h"
64 #include "bgpd/bgp_filter.h"
65 #include "bgpd/bgp_nexthop.h"
66 #include "bgpd/bgp_damp.h"
67 #include "bgpd/bgp_mplsvpn.h"
69 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/bgp_evpn.h"
73 #include "bgpd/bgp_advertise.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_vty.h"
76 #include "bgpd/bgp_mpath.h"
77 #include "bgpd/bgp_nht.h"
78 #include "bgpd/bgp_updgrp.h"
79 #include "bgpd/bgp_bfd.h"
80 #include "bgpd/bgp_memory.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_keepalives.h"
83 #include "bgpd/bgp_io.h"
84 #include "bgpd/bgp_ecommunity.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_labelpool.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "bgpd/bgp_addpath.h"
89 #include "bgpd/bgp_evpn_private.h"
90 #include "bgpd/bgp_mac.h"
92 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
93 DEFINE_MTYPE_STATIC(BGPD
, BGP_EVPN_INFO
, "BGP EVPN instance information");
94 DEFINE_QOBJ_TYPE(bgp_master
)
96 DEFINE_QOBJ_TYPE(peer
)
97 DEFINE_HOOK(bgp_inst_delete
, (struct bgp
*bgp
), (bgp
))
98 DEFINE_HOOK(bgp_inst_config_write
,
99 (struct bgp
*bgp
, struct vty
*vty
),
102 /* BGP process wide configuration. */
103 static struct bgp_master bgp_master
;
105 /* BGP process wide configuration pointer to export. */
106 struct bgp_master
*bm
;
108 /* BGP community-list. */
109 struct community_list_handler
*bgp_clist
;
111 unsigned int multipath_num
= MULTIPATH_NUM
;
113 static void bgp_if_finish(struct bgp
*bgp
);
114 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
116 extern struct zclient
*zclient
;
118 /* handle main socket creation or deletion */
119 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
121 static int bgp_server_main_created
;
124 if (bgp_server_main_created
)
126 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
127 return BGP_ERR_INVALID_VALUE
;
128 bgp_server_main_created
= 1;
131 if (!bgp_server_main_created
)
134 bgp_server_main_created
= 0;
138 void bgp_session_reset(struct peer
*peer
)
140 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
141 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
142 peer_delete(peer
->doppelganger
);
144 BGP_EVENT_ADD(peer
, BGP_Stop
);
148 * During session reset, we may delete the doppelganger peer, which would
149 * be the next node to the current node. If the session reset was invoked
150 * during walk of peer list, we would end up accessing the freed next
151 * node. This function moves the next node along.
153 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
158 n
= (nnode
) ? *nnode
: NULL
;
159 npeer
= (n
) ? listgetdata(n
) : NULL
;
161 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
162 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
163 PEER_FLAG_CONFIG_NODE
))) {
164 if (peer
->doppelganger
== npeer
)
165 /* nnode and *nnode are confirmed to be non-NULL here */
166 *nnode
= (*nnode
)->next
;
167 peer_delete(peer
->doppelganger
);
170 BGP_EVENT_ADD(peer
, BGP_Stop
);
173 /* BGP global flag manipulation. */
174 int bgp_option_set(int flag
)
178 case BGP_OPT_NO_LISTEN
:
179 case BGP_OPT_NO_ZEBRA
:
180 SET_FLAG(bm
->options
, flag
);
183 return BGP_ERR_INVALID_FLAG
;
188 int bgp_option_unset(int flag
)
192 case BGP_OPT_NO_ZEBRA
:
194 UNSET_FLAG(bm
->options
, flag
);
197 return BGP_ERR_INVALID_FLAG
;
202 int bgp_option_check(int flag
)
204 return CHECK_FLAG(bm
->options
, flag
);
207 /* BGP flag manipulation. */
208 int bgp_flag_set(struct bgp
*bgp
, int flag
)
210 SET_FLAG(bgp
->flags
, flag
);
214 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
216 UNSET_FLAG(bgp
->flags
, flag
);
220 int bgp_flag_check(struct bgp
*bgp
, int flag
)
222 return CHECK_FLAG(bgp
->flags
, flag
);
225 /* Internal function to set BGP structure configureation flag. */
226 static void bgp_config_set(struct bgp
*bgp
, int config
)
228 SET_FLAG(bgp
->config
, config
);
231 static void bgp_config_unset(struct bgp
*bgp
, int config
)
233 UNSET_FLAG(bgp
->config
, config
);
236 static int bgp_config_check(struct bgp
*bgp
, int config
)
238 return CHECK_FLAG(bgp
->config
, config
);
241 /* Set BGP router identifier; distinguish between explicit config and other
244 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
,
248 struct listnode
*node
, *nnode
;
250 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
253 /* EVPN uses router id in RD, withdraw them */
254 if (is_evpn_enabled())
255 bgp_evpn_handle_router_id_update(bgp
, true);
257 vpn_handle_router_id_update(bgp
, true, is_config
);
259 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
261 /* Set all peer's local identifier with this value. */
262 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
263 IPV4_ADDR_COPY(&peer
->local_id
, id
);
265 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
266 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
267 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
268 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
272 /* EVPN uses router id in RD, update them */
273 if (is_evpn_enabled())
274 bgp_evpn_handle_router_id_update(bgp
, false);
276 vpn_handle_router_id_update(bgp
, false, is_config
);
281 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
283 struct listnode
*node
, *nnode
;
285 struct in_addr
*addr
= NULL
;
287 if (router_id
!= NULL
)
288 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
290 if (vrf_id
== VRF_DEFAULT
) {
291 /* Router-id change for default VRF has to also update all
293 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
294 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
298 bgp
->router_id_zebra
= *addr
;
300 addr
= &bgp
->router_id_zebra
;
302 if (!bgp
->router_id_static
.s_addr
) {
303 /* Router ID is updated if there are no active
306 if (bgp
->established_peers
== 0) {
307 if (BGP_DEBUG(zebra
, ZEBRA
))
308 zlog_debug("RID change : vrf %u, RTR ID %s",
309 bgp
->vrf_id
, inet_ntoa(*addr
));
310 bgp_router_id_set(bgp
, addr
, false);
315 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
318 bgp
->router_id_zebra
= *addr
;
320 addr
= &bgp
->router_id_zebra
;
322 if (!bgp
->router_id_static
.s_addr
) {
323 /* Router ID is updated if there are no active
326 if (bgp
->established_peers
== 0) {
327 if (BGP_DEBUG(zebra
, ZEBRA
))
328 zlog_debug("RID change : vrf %u, RTR ID %s",
329 bgp
->vrf_id
, inet_ntoa(*addr
));
330 bgp_router_id_set(bgp
, addr
, false);
338 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
340 bgp
->router_id_static
= id
;
341 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
,
342 true /* is config */);
346 /* BGP's cluster-id control. */
347 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
350 struct listnode
*node
, *nnode
;
352 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
353 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
356 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
357 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
359 /* Clear all IBGP peer. */
360 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
361 if (peer
->sort
!= BGP_PEER_IBGP
)
364 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
365 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
366 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
367 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
373 int bgp_cluster_id_unset(struct bgp
*bgp
)
376 struct listnode
*node
, *nnode
;
378 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
381 bgp
->cluster_id
.s_addr
= 0;
382 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
384 /* Clear all IBGP peer. */
385 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
386 if (peer
->sort
!= BGP_PEER_IBGP
)
389 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
390 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
391 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
392 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
398 /* time_t value that is monotonicly increasing
399 * and uneffected by adjustments to system clock
401 time_t bgp_clock(void)
409 /* BGP timer configuration. */
410 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
412 bgp
->default_keepalive
=
413 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
414 bgp
->default_holdtime
= holdtime
;
419 int bgp_timers_unset(struct bgp
*bgp
)
421 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
422 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
427 /* BGP confederation configuration. */
428 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
431 struct listnode
*node
, *nnode
;
435 return BGP_ERR_INVALID_AS
;
437 /* Remember - were we doing confederation before? */
438 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
440 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
442 /* If we were doing confederation already, this is just an external
443 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
444 were not doing confederation before, reset all EBGP sessions. */
445 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
446 /* We're looking for peers who's AS is not local or part of our
448 if (already_confed
) {
449 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
451 if (BGP_IS_VALID_STATE_FOR_NOTIF(
454 PEER_DOWN_CONFED_ID_CHANGE
;
456 peer
, BGP_NOTIFY_CEASE
,
457 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
459 bgp_session_reset_safe(peer
, &nnode
);
462 /* Not doign confederation before, so reset every
465 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
466 /* Reset the local_as to be our EBGP one */
467 if (peer_sort(peer
) == BGP_PEER_EBGP
)
469 if (BGP_IS_VALID_STATE_FOR_NOTIF(
472 PEER_DOWN_CONFED_ID_CHANGE
;
474 peer
, BGP_NOTIFY_CEASE
,
475 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
477 bgp_session_reset_safe(peer
, &nnode
);
484 int bgp_confederation_id_unset(struct bgp
*bgp
)
487 struct listnode
*node
, *nnode
;
490 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
492 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
493 /* We're looking for peers who's AS is not local */
494 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
495 peer
->local_as
= bgp
->as
;
496 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
497 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
498 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
499 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
503 bgp_session_reset_safe(peer
, &nnode
);
509 /* Is an AS part of the confed or not? */
510 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
517 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
518 if (bgp
->confed_peers
[i
] == as
)
524 /* Add an AS to the confederation set. */
525 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
528 struct listnode
*node
, *nnode
;
531 return BGP_ERR_INVALID_BGP
;
534 return BGP_ERR_INVALID_AS
;
536 if (bgp_confederation_peers_check(bgp
, as
))
539 if (bgp
->confed_peers
)
541 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
542 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
545 XMALLOC(MTYPE_BGP_CONFED_LIST
,
546 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
548 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
549 bgp
->confed_peers_cnt
++;
551 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
552 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
553 if (peer
->as
== as
) {
554 peer
->local_as
= bgp
->as
;
555 if (BGP_IS_VALID_STATE_FOR_NOTIF(
558 PEER_DOWN_CONFED_PEER_CHANGE
;
560 peer
, BGP_NOTIFY_CEASE
,
561 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
563 bgp_session_reset_safe(peer
, &nnode
);
570 /* Delete an AS from the confederation set. */
571 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
576 struct listnode
*node
, *nnode
;
581 if (!bgp_confederation_peers_check(bgp
, as
))
584 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
585 if (bgp
->confed_peers
[i
] == as
)
586 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
587 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
589 bgp
->confed_peers_cnt
--;
591 if (bgp
->confed_peers_cnt
== 0) {
592 if (bgp
->confed_peers
)
593 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
594 bgp
->confed_peers
= NULL
;
597 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
598 bgp
->confed_peers_cnt
* sizeof(as_t
));
600 /* Now reset any peer who's remote AS has just been removed from the
602 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
603 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
604 if (peer
->as
== as
) {
605 peer
->local_as
= bgp
->confed_id
;
606 if (BGP_IS_VALID_STATE_FOR_NOTIF(
609 PEER_DOWN_CONFED_PEER_CHANGE
;
611 peer
, BGP_NOTIFY_CEASE
,
612 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
614 bgp_session_reset_safe(peer
, &nnode
);
622 /* Local preference configuration. */
623 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
628 bgp
->default_local_pref
= local_pref
;
633 int bgp_default_local_preference_unset(struct bgp
*bgp
)
638 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
643 /* Local preference configuration. */
644 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
649 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
654 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
658 bgp
->default_subgroup_pkt_queue_max
=
659 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
664 /* Listen limit configuration. */
665 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
670 bgp
->dynamic_neighbors_limit
= listen_limit
;
675 int bgp_listen_limit_unset(struct bgp
*bgp
)
680 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
685 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
686 afi_t
*afi
, safi_t
*safi
)
688 /* Map from IANA values to internal values, return error if
689 * values are unrecognized.
691 *afi
= afi_iana2int(pkt_afi
);
692 *safi
= safi_iana2int(pkt_safi
);
693 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
699 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
700 iana_safi_t
*pkt_safi
)
702 /* Map from internal values to IANA values, return error if
703 * internal values are bad (unexpected).
705 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
707 *pkt_afi
= afi_int2iana(afi
);
708 *pkt_safi
= safi_int2iana(safi
);
712 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
721 afid
= afindex(afi
, safi
);
722 if (afid
>= BGP_AF_MAX
)
726 assert(peer
->peer_af_array
[afid
] == NULL
);
728 /* Allocate new peer af */
729 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
731 peer
->peer_af_array
[afid
] = af
;
736 bgp
->af_peer_count
[afi
][safi
]++;
741 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
748 afid
= afindex(afi
, safi
);
749 if (afid
>= BGP_AF_MAX
)
752 return peer
->peer_af_array
[afid
];
755 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
764 afid
= afindex(afi
, safi
);
765 if (afid
>= BGP_AF_MAX
)
768 af
= peer
->peer_af_array
[afid
];
773 bgp_stop_announce_route_timer(af
);
775 if (PAF_SUBGRP(af
)) {
776 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
777 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
778 af
->subgroup
->update_group
->id
,
779 af
->subgroup
->id
, peer
->host
);
783 update_subgroup_remove_peer(af
->subgroup
, af
);
785 if (bgp
->af_peer_count
[afi
][safi
])
786 bgp
->af_peer_count
[afi
][safi
]--;
788 peer
->peer_af_array
[afid
] = NULL
;
789 XFREE(MTYPE_BGP_PEER_AF
, af
);
793 /* Peer comparison function for sorting. */
794 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
796 if (p1
->group
&& !p2
->group
)
799 if (!p1
->group
&& p2
->group
)
802 if (p1
->group
== p2
->group
) {
803 if (p1
->conf_if
&& !p2
->conf_if
)
806 if (!p1
->conf_if
&& p2
->conf_if
)
809 if (p1
->conf_if
&& p2
->conf_if
)
810 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
812 return strcmp(p1
->group
->name
, p2
->group
->name
);
814 return sockunion_cmp(&p1
->su
, &p2
->su
);
817 static unsigned int peer_hash_key_make(const void *p
)
819 const struct peer
*peer
= p
;
820 return sockunion_hash(&peer
->su
);
823 static bool peer_hash_same(const void *p1
, const void *p2
)
825 const struct peer
*peer1
= p1
;
826 const struct peer
*peer2
= p2
;
827 return (sockunion_same(&peer1
->su
, &peer2
->su
)
828 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
829 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
832 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
836 /* Skip if peer is not a peer-group member. */
837 if (!peer_group_active(peer
))
840 /* Unset override flag to signal inheritance from peer-group. */
841 UNSET_FLAG(peer
->flags_override
, flag
);
844 * Inherit flag state from peer-group. If the flag of the peer-group is
845 * not being inverted, the peer must inherit the inverse of the current
846 * peer-group flag state.
848 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
849 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
850 && CHECK_FLAG(peer
->flags_invert
, flag
))
851 COND_FLAG(peer
->flags
, flag
, !group_val
);
853 COND_FLAG(peer
->flags
, flag
, group_val
);
856 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
858 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
861 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
866 /* Skip if peer is not a peer-group member. */
867 if (!peer_group_active(peer
))
870 /* Unset override flag to signal inheritance from peer-group. */
871 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
874 * Inherit flag state from peer-group. If the flag of the peer-group is
875 * not being inverted, the peer must inherit the inverse of the current
876 * peer-group flag state.
878 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
879 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
880 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
881 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
883 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
886 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
888 if (!peer_group_active(peer
)) {
889 if (CHECK_FLAG(peer
->flags_invert
, flag
))
890 return !CHECK_FLAG(peer
->flags
, flag
);
892 return !!CHECK_FLAG(peer
->flags
, flag
);
895 return !!CHECK_FLAG(peer
->flags_override
, flag
);
898 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
901 if (!peer_group_active(peer
)) {
902 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
903 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
905 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
908 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
911 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
912 uint8_t type
, int direct
)
914 struct bgp_filter
*filter
;
916 if (peer_group_active(peer
))
917 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
920 filter
= &peer
->filter
[afi
][safi
];
922 case PEER_FT_DISTRIBUTE_LIST
:
923 return !!(filter
->dlist
[direct
].name
);
924 case PEER_FT_FILTER_LIST
:
925 return !!(filter
->aslist
[direct
].name
);
926 case PEER_FT_PREFIX_LIST
:
927 return !!(filter
->plist
[direct
].name
);
928 case PEER_FT_ROUTE_MAP
:
929 return !!(filter
->map
[direct
].name
);
930 case PEER_FT_UNSUPPRESS_MAP
:
931 return !!(filter
->usmap
.name
);
937 /* Return true if the addpath type is set for peer and different from
940 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
942 enum bgp_addpath_strat type
, g_type
;
944 type
= peer
->addpath_type
[afi
][safi
];
946 if (type
!= BGP_ADDPATH_NONE
) {
947 if (peer_group_active(peer
)) {
948 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
962 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
963 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
970 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
971 if (peer
->as_type
== AS_INTERNAL
)
972 return BGP_PEER_IBGP
;
974 else if (peer
->as_type
== AS_EXTERNAL
)
975 return BGP_PEER_EBGP
;
977 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
979 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
987 peer1
= listnode_head(peer
->group
->peer
);
992 return BGP_PEER_INTERNAL
;
996 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
997 if (peer
->local_as
== 0)
998 return BGP_PEER_INTERNAL
;
1000 if (peer
->local_as
== peer
->as
) {
1001 if (bgp
->as
== bgp
->confed_id
) {
1002 if (peer
->local_as
== bgp
->as
)
1003 return BGP_PEER_IBGP
;
1005 return BGP_PEER_EBGP
;
1007 if (peer
->local_as
== bgp
->confed_id
)
1008 return BGP_PEER_EBGP
;
1010 return BGP_PEER_IBGP
;
1014 if (bgp_confederation_peers_check(bgp
, peer
->as
))
1015 return BGP_PEER_CONFED
;
1017 return BGP_PEER_EBGP
;
1019 if (peer
->as_type
== AS_UNSPECIFIED
) {
1020 /* check if in peer-group with AS information */
1022 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
1023 if (peer
->group
->conf
->as_type
1026 == peer
->group
->conf
->as
)
1027 return BGP_PEER_IBGP
;
1029 return BGP_PEER_EBGP
;
1030 } else if (peer
->group
->conf
->as_type
1032 return BGP_PEER_IBGP
;
1034 return BGP_PEER_EBGP
;
1036 /* no AS information anywhere, let caller know */
1037 return BGP_PEER_UNSPECIFIED
;
1038 } else if (peer
->as_type
!= AS_SPECIFIED
)
1039 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1042 return (peer
->local_as
== 0
1044 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1049 /* Calculate and cache the peer "sort" */
1050 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1052 peer
->sort
= peer_calc_sort(peer
);
1056 static void peer_free(struct peer
*peer
)
1061 assert(peer
->status
== Deleted
);
1065 /* this /ought/ to have been done already through bgp_stop earlier,
1066 * but just to be sure..
1068 bgp_timer_set(peer
);
1069 bgp_reads_off(peer
);
1070 bgp_writes_off(peer
);
1071 assert(!peer
->t_write
);
1072 assert(!peer
->t_read
);
1073 BGP_EVENT_FLUSH(peer
);
1075 pthread_mutex_destroy(&peer
->io_mtx
);
1077 /* Free connected nexthop, if present */
1078 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1079 && !peer_dynamic_neighbor(peer
))
1080 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1083 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1086 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1090 /* Free allocated host character. */
1092 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1096 if (peer
->domainname
) {
1097 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1098 peer
->domainname
= NULL
;
1102 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1103 peer
->ifname
= NULL
;
1106 /* Update source configuration. */
1107 if (peer
->update_source
) {
1108 sockunion_free(peer
->update_source
);
1109 peer
->update_source
= NULL
;
1112 if (peer
->update_if
) {
1113 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1114 peer
->update_if
= NULL
;
1117 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1118 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1120 if (peer
->clear_node_queue
)
1121 work_queue_free_and_null(&peer
->clear_node_queue
);
1123 bgp_sync_delete(peer
);
1125 if (peer
->conf_if
) {
1126 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1127 peer
->conf_if
= NULL
;
1130 bfd_info_free(&(peer
->bfd_info
));
1132 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1133 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1134 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1139 bgp_unlock(peer
->bgp
);
1141 memset(peer
, 0, sizeof(struct peer
));
1143 XFREE(MTYPE_BGP_PEER
, peer
);
1146 /* increase reference count on a struct peer */
1147 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1149 assert(peer
&& (peer
->lock
>= 0));
1152 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1160 /* decrease reference count on a struct peer
1161 * struct peer is freed and NULL returned if last reference
1163 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1165 assert(peer
&& (peer
->lock
> 0));
1168 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1173 if (peer
->lock
== 0) {
1181 /* Allocate new peer object, implicitely locked. */
1182 struct peer
*peer_new(struct bgp
*bgp
)
1189 /* bgp argument is absolutely required */
1194 /* Allocate new peer. */
1195 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1197 /* Set default value. */
1199 peer
->v_start
= BGP_INIT_START_TIMER
;
1200 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1201 peer
->status
= Idle
;
1202 peer
->ostatus
= Idle
;
1203 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1204 peer
->bgp
= bgp_lock(bgp
);
1205 peer
= peer_lock(peer
); /* initial reference */
1206 peer
->password
= NULL
;
1208 /* Set default flags. */
1209 FOREACH_AFI_SAFI (afi
, safi
) {
1210 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
1211 SET_FLAG(peer
->af_flags
[afi
][safi
],
1212 PEER_FLAG_SEND_EXT_COMMUNITY
);
1213 SET_FLAG(peer
->af_flags
[afi
][safi
],
1214 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1216 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1217 PEER_FLAG_SEND_COMMUNITY
);
1218 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1219 PEER_FLAG_SEND_EXT_COMMUNITY
);
1220 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1221 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1222 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1225 /* set nexthop-unchanged for l2vpn evpn by default */
1226 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1227 PEER_FLAG_NEXTHOP_UNCHANGED
);
1229 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1231 /* Create buffers. */
1232 peer
->ibuf
= stream_fifo_new();
1233 peer
->obuf
= stream_fifo_new();
1234 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1236 /* We use a larger buffer for peer->obuf_work in the event that:
1237 * - We RX a BGP_UPDATE where the attributes alone are just
1238 * under BGP_MAX_PACKET_SIZE
1239 * - The user configures an outbound route-map that does many as-path
1240 * prepends or adds many communities. At most they can have
1241 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1242 * large they can make the attributes.
1244 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1245 * bounds checking for every single attribute as we construct an
1249 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1251 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1253 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1255 bgp_sync_init(peer
);
1257 /* Get service port number. */
1258 sp
= getservbyname("bgp", "tcp");
1259 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1261 QOBJ_REG(peer
, peer
);
1266 * This function is invoked when a duplicate peer structure associated with
1267 * a neighbor is being deleted. If this about-to-be-deleted structure is
1268 * the one with all the config, then we have to copy over the info.
1270 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1272 struct peer_af
*paf
;
1280 /* The following function is used by both peer group config copy to
1281 * individual peer and when we transfer config
1283 if (peer_src
->change_local_as
)
1284 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1286 /* peer flags apply */
1287 peer_dst
->flags
= peer_src
->flags
;
1288 peer_dst
->cap
= peer_src
->cap
;
1290 peer_dst
->local_as
= peer_src
->local_as
;
1291 peer_dst
->port
= peer_src
->port
;
1292 (void)peer_sort(peer_dst
);
1293 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1296 peer_dst
->holdtime
= peer_src
->holdtime
;
1297 peer_dst
->keepalive
= peer_src
->keepalive
;
1298 peer_dst
->connect
= peer_src
->connect
;
1299 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1300 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1301 peer_dst
->routeadv
= peer_src
->routeadv
;
1302 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1304 /* password apply */
1305 if (peer_src
->password
&& !peer_dst
->password
)
1306 peer_dst
->password
=
1307 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1309 FOREACH_AFI_SAFI (afi
, safi
) {
1310 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1311 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1312 peer_dst
->allowas_in
[afi
][safi
] =
1313 peer_src
->allowas_in
[afi
][safi
];
1314 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1315 peer_dst
->addpath_type
[afi
][safi
] =
1316 peer_src
->addpath_type
[afi
][safi
];
1319 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1320 paf
= peer_src
->peer_af_array
[afidx
];
1322 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1325 /* update-source apply */
1326 if (peer_src
->update_source
) {
1327 if (peer_dst
->update_source
)
1328 sockunion_free(peer_dst
->update_source
);
1329 if (peer_dst
->update_if
) {
1330 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1331 peer_dst
->update_if
= NULL
;
1333 peer_dst
->update_source
=
1334 sockunion_dup(peer_src
->update_source
);
1335 } else if (peer_src
->update_if
) {
1336 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1337 if (peer_dst
->update_source
) {
1338 sockunion_free(peer_dst
->update_source
);
1339 peer_dst
->update_source
= NULL
;
1341 peer_dst
->update_if
=
1342 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1345 if (peer_src
->ifname
) {
1346 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1349 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1353 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1354 struct interface
*ifp
)
1356 struct connected
*ifc
;
1359 struct listnode
*node
;
1361 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1362 * IPv4 address of the other end.
1364 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1365 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1366 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1367 if (p
.prefixlen
== 30) {
1368 peer
->su
.sa
.sa_family
= AF_INET
;
1369 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1371 peer
->su
.sin
.sin_addr
.s_addr
=
1373 else if (addr
% 4 == 2)
1374 peer
->su
.sin
.sin_addr
.s_addr
=
1376 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1377 peer
->su
.sin
.sin_len
=
1378 sizeof(struct sockaddr_in
);
1379 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1381 } else if (p
.prefixlen
== 31) {
1382 peer
->su
.sa
.sa_family
= AF_INET
;
1383 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1385 peer
->su
.sin
.sin_addr
.s_addr
=
1388 peer
->su
.sin
.sin_addr
.s_addr
=
1390 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1391 peer
->su
.sin
.sin_len
=
1392 sizeof(struct sockaddr_in
);
1393 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1395 } else if (bgp_debug_neighbor_events(peer
))
1397 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1405 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1406 struct interface
*ifp
)
1408 struct nbr_connected
*ifc_nbr
;
1410 /* Have we learnt the peer's IPv6 link-local address? */
1411 if (ifp
->nbr_connected
1412 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1413 peer
->su
.sa
.sa_family
= AF_INET6
;
1414 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1415 sizeof(struct in6_addr
));
1417 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1419 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1427 * Set or reset the peer address socketunion structure based on the
1428 * learnt/derived peer address. If the address has changed, update the
1429 * password on the listen socket, if needed.
1431 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1433 struct interface
*ifp
;
1435 int peer_addr_updated
= 0;
1441 * Our peer structure is stored in the bgp->peerhash
1442 * release it before we modify anything.
1444 hash_release(peer
->bgp
->peerhash
, peer
);
1446 prev_family
= peer
->su
.sa
.sa_family
;
1447 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1449 /* If BGP unnumbered is not "v6only", we first see if we can
1451 * peer's IPv4 address.
1453 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1455 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1457 /* If "v6only" or we can't derive peer's IPv4 address, see if
1459 * learnt the peer's IPv6 link-local address. This is from the
1461 * IPv6 address in router advertisement.
1463 if (!peer_addr_updated
)
1465 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1467 /* If we could derive the peer address, we may need to install the
1469 * configured for the peer, if any, on the listen socket. Otherwise,
1471 * that peer's address is not available and uninstall the password, if
1474 if (peer_addr_updated
) {
1475 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1476 && prev_family
== AF_UNSPEC
)
1479 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1480 && prev_family
!= AF_UNSPEC
)
1481 bgp_md5_unset(peer
);
1482 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1483 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1487 * Since our su changed we need to del/add peer to the peerhash
1489 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1492 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1495 struct bgp_node
*rn
, *nrn
;
1496 struct bgp_table
*table
;
1498 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1499 rn
= bgp_route_next(rn
)) {
1500 table
= bgp_node_get_bgp_table_info(rn
);
1501 if (table
!= NULL
) {
1502 /* Special handling for 2-level routing
1504 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1505 || safi
== SAFI_EVPN
) {
1506 for (nrn
= bgp_table_top(table
);
1507 nrn
; nrn
= bgp_route_next(nrn
))
1508 bgp_process(bgp
, nrn
, afi
, safi
);
1510 bgp_process(bgp
, rn
, afi
, safi
);
1515 /* Force a bestpath recalculation for all prefixes. This is used
1516 * when 'bgp bestpath' commands are entered.
1518 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1523 FOREACH_AFI_SAFI (afi
, safi
) {
1524 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1529 * Create new BGP peer.
1531 * conf_if and su are mutually exclusive if configuring from the cli.
1532 * If we are handing a doppelganger, then we *must* pass in both
1533 * the original peer's su and conf_if, so that we can appropriately
1534 * track the bgp->peerhash( ie we don't want to remove the current
1535 * one from the config ).
1537 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1538 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1539 int as_type
, afi_t afi
, safi_t safi
,
1540 struct peer_group
*group
)
1544 char buf
[SU_ADDRSTRLEN
];
1546 peer
= peer_new(bgp
);
1548 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1552 bgp_peer_conf_if_to_su_update(peer
);
1553 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1554 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1557 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1558 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1559 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1561 peer
->local_as
= local_as
;
1562 peer
->as
= remote_as
;
1563 peer
->as_type
= as_type
;
1564 peer
->local_id
= bgp
->router_id
;
1565 peer
->v_holdtime
= bgp
->default_holdtime
;
1566 peer
->v_keepalive
= bgp
->default_keepalive
;
1567 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1568 ? BGP_DEFAULT_IBGP_ROUTEADV
1569 : BGP_DEFAULT_EBGP_ROUTEADV
;
1571 peer
= peer_lock(peer
); /* bgp peer list reference */
1572 peer
->group
= group
;
1573 listnode_add_sort(bgp
->peer
, peer
);
1574 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1576 /* Adjust update-group coalesce timer heuristics for # peers. */
1577 if (bgp
->heuristic_coalesce
) {
1578 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1580 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1581 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1584 active
= peer_active(peer
);
1586 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
)
1587 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1589 peer
->last_reset
= PEER_DOWN_NOAFI_ACTIVATED
;
1592 /* Last read and reset time set */
1593 peer
->readtime
= peer
->resettime
= bgp_clock();
1595 /* Default TTL set. */
1596 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: BGP_DEFAULT_TTL
;
1598 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1601 peer
->afc
[afi
][safi
] = 1;
1602 peer_af_create(peer
, afi
, safi
);
1605 /* auto shutdown if configured */
1606 if (bgp
->autoshutdown
)
1607 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1608 /* Set up peer's events and timers. */
1609 else if (!active
&& peer_active(peer
))
1610 bgp_timer_set(peer
);
1615 /* Make accept BGP peer. This function is only called from the test code */
1616 struct peer
*peer_create_accept(struct bgp
*bgp
)
1620 peer
= peer_new(bgp
);
1622 peer
= peer_lock(peer
); /* bgp peer list reference */
1623 listnode_add_sort(bgp
->peer
, peer
);
1629 * Return true if we have a peer configured to use this afi/safi
1631 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1633 struct listnode
*node
;
1636 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1637 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1640 if (peer
->afc
[afi
][safi
])
1647 /* Change peer's AS number. */
1648 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1650 bgp_peer_sort_t type
;
1653 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1654 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1655 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1656 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1657 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1659 bgp_session_reset(peer
);
1661 type
= peer_sort(peer
);
1663 peer
->as_type
= as_specified
;
1665 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1666 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1667 && peer
->bgp
->as
!= as
)
1668 peer
->local_as
= peer
->bgp
->confed_id
;
1670 peer
->local_as
= peer
->bgp
->as
;
1672 /* Advertisement-interval reset */
1673 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1674 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1675 ? BGP_DEFAULT_IBGP_ROUTEADV
1676 : BGP_DEFAULT_EBGP_ROUTEADV
;
1680 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1682 else if (type
== BGP_PEER_IBGP
)
1683 peer
->ttl
= BGP_DEFAULT_TTL
;
1685 /* reflector-client reset */
1686 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1687 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1688 PEER_FLAG_REFLECTOR_CLIENT
);
1689 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1690 PEER_FLAG_REFLECTOR_CLIENT
);
1691 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1692 PEER_FLAG_REFLECTOR_CLIENT
);
1693 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1694 PEER_FLAG_REFLECTOR_CLIENT
);
1695 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1696 PEER_FLAG_REFLECTOR_CLIENT
);
1697 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1698 PEER_FLAG_REFLECTOR_CLIENT
);
1699 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1700 PEER_FLAG_REFLECTOR_CLIENT
);
1701 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1702 PEER_FLAG_REFLECTOR_CLIENT
);
1703 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1704 PEER_FLAG_REFLECTOR_CLIENT
);
1705 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1706 PEER_FLAG_REFLECTOR_CLIENT
);
1707 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1708 PEER_FLAG_REFLECTOR_CLIENT
);
1709 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1710 PEER_FLAG_REFLECTOR_CLIENT
);
1711 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1712 PEER_FLAG_REFLECTOR_CLIENT
);
1715 /* local-as reset */
1716 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1717 peer
->change_local_as
= 0;
1718 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1719 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1720 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1724 /* If peer does not exist, create new one. If peer already exists,
1725 set AS number to the peer. */
1726 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1727 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1733 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1735 peer
= peer_lookup(bgp
, su
);
1738 /* Not allowed for a dynamic peer. */
1739 if (peer_dynamic_neighbor(peer
)) {
1741 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1744 /* When this peer is a member of peer-group. */
1746 /* peer-group already has AS number/internal/external */
1747 if (peer
->group
->conf
->as
1748 || peer
->group
->conf
->as_type
) {
1749 /* Return peer group's AS number. */
1750 *as
= peer
->group
->conf
->as
;
1751 return BGP_ERR_PEER_GROUP_MEMBER
;
1754 bgp_peer_sort_t peer_sort_type
=
1755 peer_sort(peer
->group
->conf
);
1757 /* Explicit AS numbers used, compare AS numbers */
1758 if (as_type
== AS_SPECIFIED
) {
1759 if (((peer_sort_type
== BGP_PEER_IBGP
)
1760 && (bgp
->as
!= *as
))
1761 || ((peer_sort_type
== BGP_PEER_EBGP
)
1762 && (bgp
->as
== *as
))) {
1764 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1767 /* internal/external used, compare as-types */
1768 if (((peer_sort_type
== BGP_PEER_IBGP
)
1769 && (as_type
!= AS_INTERNAL
))
1770 || ((peer_sort_type
== BGP_PEER_EBGP
)
1771 && (as_type
!= AS_EXTERNAL
))) {
1773 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1778 /* Existing peer's AS number change. */
1779 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1780 || (peer
->as_type
!= as_type
))
1781 peer_as_change(peer
, *as
, as_type
);
1784 return BGP_ERR_NO_INTERFACE_CONFIG
;
1786 /* If the peer is not part of our confederation, and its not an
1787 iBGP peer then spoof the source AS */
1788 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1789 && !bgp_confederation_peers_check(bgp
, *as
)
1791 local_as
= bgp
->confed_id
;
1795 /* If this is IPv4 unicast configuration and "no bgp default
1796 ipv4-unicast" is specified. */
1798 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1799 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1800 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1803 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1810 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1811 struct peer
*peer
, afi_t afi
,
1815 int out
= FILTER_OUT
;
1817 uint32_t pflags_ovrd
;
1818 uint8_t *pfilter_ovrd
;
1822 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1823 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1825 /* peer af_flags apply */
1826 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1827 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1828 ^ peer
->af_flags_invert
[afi
][safi
];
1829 flags_tmp
&= ~pflags_ovrd
;
1831 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1832 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1833 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1834 conf
->af_flags_invert
[afi
][safi
]);
1836 /* maximum-prefix */
1837 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1838 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1839 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1840 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1844 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1845 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1848 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1849 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1851 /* default-originate route-map */
1852 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1853 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1854 MTYPE_ROUTE_MAP_NAME
);
1855 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1858 /* inbound filter apply */
1859 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1860 PEER_STR_ATTR_INHERIT(peer
, group
,
1861 filter
[afi
][safi
].dlist
[in
].name
,
1862 MTYPE_BGP_FILTER_NAME
);
1863 PEER_ATTR_INHERIT(peer
, group
,
1864 filter
[afi
][safi
].dlist
[in
].alist
);
1867 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1868 PEER_STR_ATTR_INHERIT(peer
, group
,
1869 filter
[afi
][safi
].plist
[in
].name
,
1870 MTYPE_BGP_FILTER_NAME
);
1871 PEER_ATTR_INHERIT(peer
, group
,
1872 filter
[afi
][safi
].plist
[in
].plist
);
1875 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1876 PEER_STR_ATTR_INHERIT(peer
, group
,
1877 filter
[afi
][safi
].aslist
[in
].name
,
1878 MTYPE_BGP_FILTER_NAME
);
1879 PEER_ATTR_INHERIT(peer
, group
,
1880 filter
[afi
][safi
].aslist
[in
].aslist
);
1883 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1884 PEER_STR_ATTR_INHERIT(peer
, group
,
1885 filter
[afi
][safi
].map
[in
].name
,
1886 MTYPE_BGP_FILTER_NAME
);
1887 PEER_ATTR_INHERIT(peer
, group
,
1888 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1891 /* outbound filter apply */
1892 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1893 PEER_STR_ATTR_INHERIT(peer
, group
,
1894 filter
[afi
][safi
].dlist
[out
].name
,
1895 MTYPE_BGP_FILTER_NAME
);
1896 PEER_ATTR_INHERIT(peer
, group
,
1897 filter
[afi
][safi
].dlist
[out
].alist
);
1900 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1901 PEER_STR_ATTR_INHERIT(peer
, group
,
1902 filter
[afi
][safi
].plist
[out
].name
,
1903 MTYPE_BGP_FILTER_NAME
);
1904 PEER_ATTR_INHERIT(peer
, group
,
1905 filter
[afi
][safi
].plist
[out
].plist
);
1908 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1909 PEER_STR_ATTR_INHERIT(peer
, group
,
1910 filter
[afi
][safi
].aslist
[out
].name
,
1911 MTYPE_BGP_FILTER_NAME
);
1912 PEER_ATTR_INHERIT(peer
, group
,
1913 filter
[afi
][safi
].aslist
[out
].aslist
);
1916 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1917 PEER_STR_ATTR_INHERIT(peer
, group
,
1918 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1919 MTYPE_BGP_FILTER_NAME
);
1920 PEER_ATTR_INHERIT(peer
, group
,
1921 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1924 /* nondirectional filter apply */
1925 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1926 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1927 MTYPE_BGP_FILTER_NAME
);
1928 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1931 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1932 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1933 bgp_addpath_type_changed(conf
->bgp
);
1937 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1942 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1943 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1944 __func__
, peer
->host
);
1948 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1950 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1951 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1952 return BGP_ERR_PEER_SAFI_CONFLICT
;
1954 /* Nothing to do if we've already activated this peer */
1955 if (peer
->afc
[afi
][safi
])
1958 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1961 active
= peer_active(peer
);
1962 peer
->afc
[afi
][safi
] = 1;
1965 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1967 if (!active
&& peer_active(peer
)) {
1968 bgp_timer_set(peer
);
1970 if (peer
->status
== Established
) {
1971 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1972 peer
->afc_adv
[afi
][safi
] = 1;
1973 bgp_capability_send(peer
, afi
, safi
,
1975 CAPABILITY_ACTION_SET
);
1976 if (peer
->afc_recv
[afi
][safi
]) {
1977 peer
->afc_nego
[afi
][safi
] = 1;
1978 bgp_announce_route(peer
, afi
, safi
);
1981 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1982 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1983 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1986 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1987 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1988 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1989 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1992 * If we are turning on a AFI/SAFI locally and we've
1993 * started bringing a peer up, we need to tell
1994 * the other peer to restart because we might loose
1995 * configuration here because when the doppelganger
1996 * gets to a established state due to how
1997 * we resolve we could just overwrite the afi/safi
2000 other
= peer
->doppelganger
;
2002 && (other
->status
== OpenSent
2003 || other
->status
== OpenConfirm
)) {
2004 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
2005 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
2006 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2013 /* Activate the peer or peer group for specified AFI and SAFI. */
2014 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2017 struct peer_group
*group
;
2018 struct listnode
*node
, *nnode
;
2019 struct peer
*tmp_peer
;
2022 /* Nothing to do if we've already activated this peer */
2023 if (peer
->afc
[afi
][safi
])
2028 /* This is a peer-group so activate all of the members of the
2029 * peer-group as well */
2030 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2032 /* Do not activate a peer for both SAFI_UNICAST and
2033 * SAFI_LABELED_UNICAST */
2034 if ((safi
== SAFI_UNICAST
2035 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2036 || (safi
== SAFI_LABELED_UNICAST
2037 && peer
->afc
[afi
][SAFI_UNICAST
]))
2038 return BGP_ERR_PEER_SAFI_CONFLICT
;
2040 peer
->afc
[afi
][safi
] = 1;
2041 group
= peer
->group
;
2043 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2044 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2047 ret
|= peer_activate_af(peer
, afi
, safi
);
2050 /* If this is the first peer to be activated for this
2051 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2052 if (safi
== SAFI_LABELED_UNICAST
2053 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2055 if (BGP_DEBUG(zebra
, ZEBRA
))
2057 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2059 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2060 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2063 if (safi
== SAFI_FLOWSPEC
) {
2064 /* connect to table manager */
2065 bgp_zebra_init_tm_connect(bgp
);
2070 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2073 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2074 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2075 __func__
, peer
->host
);
2079 /* Nothing to do if we've already deactivated this peer */
2080 if (!peer
->afc
[afi
][safi
])
2083 /* De-activate the address family configuration. */
2084 peer
->afc
[afi
][safi
] = 0;
2086 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2087 flog_err(EC_BGP_PEER_DELETE
,
2088 "couldn't delete af structure for peer %s",
2093 if (peer
->status
== Established
) {
2094 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2095 peer
->afc_adv
[afi
][safi
] = 0;
2096 peer
->afc_nego
[afi
][safi
] = 0;
2098 if (peer_active_nego(peer
)) {
2099 bgp_capability_send(peer
, afi
, safi
,
2101 CAPABILITY_ACTION_UNSET
);
2102 bgp_clear_route(peer
, afi
, safi
);
2103 peer
->pcount
[afi
][safi
] = 0;
2105 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2106 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2107 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2110 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2111 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2112 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2119 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2122 struct peer_group
*group
;
2123 struct peer
*tmp_peer
;
2124 struct listnode
*node
, *nnode
;
2127 /* Nothing to do if we've already de-activated this peer */
2128 if (!peer
->afc
[afi
][safi
])
2131 /* This is a peer-group so de-activate all of the members of the
2132 * peer-group as well */
2133 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2134 peer
->afc
[afi
][safi
] = 0;
2135 group
= peer
->group
;
2137 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2138 flog_err(EC_BGP_PEER_DELETE
,
2139 "couldn't delete af structure for peer %s",
2143 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2144 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2147 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2152 /* If this is the last peer to be deactivated for this
2153 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2154 if (safi
== SAFI_LABELED_UNICAST
2155 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2156 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2158 if (BGP_DEBUG(zebra
, ZEBRA
))
2160 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2162 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2163 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2168 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2171 return peer_activate(peer
, afi
, safi
);
2173 return peer_deactivate(peer
, afi
, safi
);
2176 static void peer_nsf_stop(struct peer
*peer
)
2181 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2182 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2184 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2185 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2186 peer
->nsf
[afi
][safi
] = 0;
2188 if (peer
->t_gr_restart
) {
2189 BGP_TIMER_OFF(peer
->t_gr_restart
);
2190 if (bgp_debug_neighbor_events(peer
))
2191 zlog_debug("%s graceful restart timer stopped",
2194 if (peer
->t_gr_stale
) {
2195 BGP_TIMER_OFF(peer
->t_gr_stale
);
2196 if (bgp_debug_neighbor_events(peer
))
2198 "%s graceful restart stalepath timer stopped",
2201 bgp_clear_route_all(peer
);
2204 /* Delete peer from confguration.
2206 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2207 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2209 * This function /should/ take care to be idempotent, to guard against
2210 * it being called multiple times through stray events that come in
2211 * that happen to result in this function being called again. That
2212 * said, getting here for a "Deleted" peer is a bug in the neighbour
2215 int peer_delete(struct peer
*peer
)
2221 struct bgp_filter
*filter
;
2222 struct listnode
*pn
;
2225 assert(peer
->status
!= Deleted
);
2228 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2230 bgp_keepalives_off(peer
);
2231 bgp_reads_off(peer
);
2232 bgp_writes_off(peer
);
2233 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2234 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2235 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_KEEPALIVES_ON
));
2237 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2238 peer_nsf_stop(peer
);
2240 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2242 bgp_bfd_deregister_peer(peer
);
2244 /* If this peer belongs to peer group, clear up the
2247 if (peer_dynamic_neighbor(peer
))
2248 peer_drop_dynamic_neighbor(peer
);
2250 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2252 peer
); /* group->peer list reference */
2253 list_delete_node(peer
->group
->peer
, pn
);
2258 /* Withdraw all information from routing table. We can not use
2259 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2260 * executed after peer structure is deleted.
2262 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2264 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2266 if (peer
->doppelganger
) {
2267 peer
->doppelganger
->doppelganger
= NULL
;
2268 peer
->doppelganger
= NULL
;
2271 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2272 bgp_fsm_change_status(peer
, Deleted
);
2274 /* Remove from NHT */
2275 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2276 bgp_unlink_nexthop_by_peer(peer
);
2278 /* Password configuration */
2279 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2280 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2282 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2283 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2284 bgp_md5_unset(peer
);
2287 bgp_timer_set(peer
); /* stops all timers for Deleted */
2289 /* Delete from all peer list. */
2290 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2291 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2292 peer_unlock(peer
); /* bgp peer list reference */
2293 list_delete_node(bgp
->peer
, pn
);
2294 hash_release(bgp
->peerhash
, peer
);
2299 stream_fifo_free(peer
->ibuf
);
2304 stream_fifo_free(peer
->obuf
);
2308 if (peer
->ibuf_work
) {
2309 ringbuf_del(peer
->ibuf_work
);
2310 peer
->ibuf_work
= NULL
;
2313 if (peer
->obuf_work
) {
2314 stream_free(peer
->obuf_work
);
2315 peer
->obuf_work
= NULL
;
2318 if (peer
->scratch
) {
2319 stream_free(peer
->scratch
);
2320 peer
->scratch
= NULL
;
2323 /* Local and remote addresses. */
2324 if (peer
->su_local
) {
2325 sockunion_free(peer
->su_local
);
2326 peer
->su_local
= NULL
;
2329 if (peer
->su_remote
) {
2330 sockunion_free(peer
->su_remote
);
2331 peer
->su_remote
= NULL
;
2334 /* Free filter related memory. */
2335 FOREACH_AFI_SAFI (afi
, safi
) {
2336 filter
= &peer
->filter
[afi
][safi
];
2338 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2339 if (filter
->dlist
[i
].name
) {
2340 XFREE(MTYPE_BGP_FILTER_NAME
,
2341 filter
->dlist
[i
].name
);
2342 filter
->dlist
[i
].name
= NULL
;
2345 if (filter
->plist
[i
].name
) {
2346 XFREE(MTYPE_BGP_FILTER_NAME
,
2347 filter
->plist
[i
].name
);
2348 filter
->plist
[i
].name
= NULL
;
2351 if (filter
->aslist
[i
].name
) {
2352 XFREE(MTYPE_BGP_FILTER_NAME
,
2353 filter
->aslist
[i
].name
);
2354 filter
->aslist
[i
].name
= NULL
;
2358 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2359 if (filter
->map
[i
].name
) {
2360 XFREE(MTYPE_BGP_FILTER_NAME
,
2361 filter
->map
[i
].name
);
2362 filter
->map
[i
].name
= NULL
;
2366 if (filter
->usmap
.name
) {
2367 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2368 filter
->usmap
.name
= NULL
;
2371 if (peer
->default_rmap
[afi
][safi
].name
) {
2372 XFREE(MTYPE_ROUTE_MAP_NAME
,
2373 peer
->default_rmap
[afi
][safi
].name
);
2374 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2378 FOREACH_AFI_SAFI (afi
, safi
)
2379 peer_af_delete(peer
, afi
, safi
);
2381 if (peer
->hostname
) {
2382 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2383 peer
->hostname
= NULL
;
2386 if (peer
->domainname
) {
2387 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2388 peer
->domainname
= NULL
;
2391 peer_unlock(peer
); /* initial reference */
2396 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2398 return strcmp(g1
->name
, g2
->name
);
2401 /* Peer group cofiguration. */
2402 static struct peer_group
*peer_group_new(void)
2404 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2407 static void peer_group_free(struct peer_group
*group
)
2409 XFREE(MTYPE_PEER_GROUP
, group
);
2412 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2414 struct peer_group
*group
;
2415 struct listnode
*node
, *nnode
;
2417 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2418 if (strcmp(group
->name
, name
) == 0)
2424 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2426 struct peer_group
*group
;
2429 group
= peer_group_lookup(bgp
, name
);
2433 group
= peer_group_new();
2435 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2436 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2437 group
->peer
= list_new();
2438 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2439 group
->listen_range
[afi
] = list_new();
2440 group
->conf
= peer_new(bgp
);
2441 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2442 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2443 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2444 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2445 group
->conf
->group
= group
;
2446 group
->conf
->as
= 0;
2447 group
->conf
->ttl
= BGP_DEFAULT_TTL
;
2448 group
->conf
->gtsm_hops
= 0;
2449 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2450 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2451 listnode_add_sort(bgp
->group
, group
);
2456 static void peer_group2peer_config_copy(struct peer_group
*group
,
2466 peer
->as
= conf
->as
;
2469 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2470 peer
->change_local_as
= conf
->change_local_as
;
2472 /* If peer-group has configured TTL then override it */
2473 if (conf
->ttl
!= BGP_DEFAULT_TTL
)
2474 peer
->ttl
= conf
->ttl
;
2477 peer
->gtsm_hops
= conf
->gtsm_hops
;
2479 /* peer flags apply */
2480 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2481 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2482 flags_tmp
&= ~peer
->flags_override
;
2484 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2485 SET_FLAG(peer
->flags
, flags_tmp
);
2486 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2488 /* peer timers apply */
2489 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2490 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2491 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2494 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2495 PEER_ATTR_INHERIT(peer
, group
, connect
);
2496 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2497 peer
->v_connect
= conf
->connect
;
2499 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2502 /* advertisement-interval apply */
2503 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2504 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2505 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2506 peer
->v_routeadv
= conf
->routeadv
;
2508 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2509 ? BGP_DEFAULT_IBGP_ROUTEADV
2510 : BGP_DEFAULT_EBGP_ROUTEADV
;
2513 /* password apply */
2514 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2515 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2516 MTYPE_PEER_PASSWORD
);
2518 if (!BGP_PEER_SU_UNSPEC(peer
))
2521 /* update-source apply */
2522 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2523 if (conf
->update_source
) {
2524 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2525 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2526 } else if (conf
->update_if
) {
2527 sockunion_free(peer
->update_source
);
2528 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2529 MTYPE_PEER_UPDATE_SOURCE
);
2533 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2536 /* Peer group's remote AS configuration. */
2537 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2540 struct peer_group
*group
;
2542 struct listnode
*node
, *nnode
;
2544 group
= peer_group_lookup(bgp
, group_name
);
2548 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2552 /* When we setup peer-group AS number all peer group member's AS
2553 number must be updated to same number. */
2554 peer_as_change(group
->conf
, *as
, as_type
);
2556 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2557 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2558 || (peer
->as_type
!= as_type
))
2559 peer_as_change(peer
, *as
, as_type
);
2565 int peer_notify_unconfig(struct peer
*peer
)
2567 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2568 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2569 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
2573 int peer_group_notify_unconfig(struct peer_group
*group
)
2575 struct peer
*peer
, *other
;
2576 struct listnode
*node
, *nnode
;
2578 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2579 other
= peer
->doppelganger
;
2580 if (other
&& other
->status
!= Deleted
) {
2581 other
->group
= NULL
;
2582 peer_notify_unconfig(other
);
2584 peer_notify_unconfig(peer
);
2589 int peer_group_delete(struct peer_group
*group
)
2593 struct prefix
*prefix
;
2595 struct listnode
*node
, *nnode
;
2600 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2601 other
= peer
->doppelganger
;
2603 if (other
&& other
->status
!= Deleted
) {
2604 other
->group
= NULL
;
2608 list_delete(&group
->peer
);
2610 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2611 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2613 prefix_free(&prefix
);
2615 list_delete(&group
->listen_range
[afi
]);
2618 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2621 bfd_info_free(&(group
->conf
->bfd_info
));
2623 group
->conf
->group
= NULL
;
2624 peer_delete(group
->conf
);
2626 /* Delete from all peer_group list. */
2627 listnode_delete(bgp
->group
, group
);
2629 peer_group_free(group
);
2634 int peer_group_remote_as_delete(struct peer_group
*group
)
2636 struct peer
*peer
, *other
;
2637 struct listnode
*node
, *nnode
;
2639 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2640 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2643 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2644 other
= peer
->doppelganger
;
2648 if (other
&& other
->status
!= Deleted
) {
2649 other
->group
= NULL
;
2653 list_delete_all_node(group
->peer
);
2655 group
->conf
->as
= 0;
2656 group
->conf
->as_type
= AS_UNSPECIFIED
;
2661 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2663 struct prefix
*prefix
;
2664 struct listnode
*node
, *nnode
;
2667 afi
= family2afi(range
->family
);
2669 /* Group needs remote AS configured. */
2670 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2671 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2673 /* Ensure no duplicates. Currently we don't care about overlaps. */
2674 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2675 if (prefix_same(range
, prefix
))
2679 prefix
= prefix_new();
2680 prefix_copy(prefix
, range
);
2681 listnode_add(group
->listen_range
[afi
], prefix
);
2683 /* Update passwords for new ranges */
2684 if (group
->conf
->password
)
2685 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2690 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2692 struct prefix
*prefix
, prefix2
;
2693 struct listnode
*node
, *nnode
;
2696 char buf
[PREFIX2STR_BUFFER
];
2698 afi
= family2afi(range
->family
);
2700 /* Identify the listen range. */
2701 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2702 if (prefix_same(range
, prefix
))
2707 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2709 prefix2str(prefix
, buf
, sizeof(buf
));
2711 /* Dispose off any dynamic neighbors that exist due to this listen range
2713 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2714 if (!peer_dynamic_neighbor(peer
))
2717 sockunion2hostprefix(&peer
->su
, &prefix2
);
2718 if (prefix_match(prefix
, &prefix2
)) {
2719 if (bgp_debug_neighbor_events(peer
))
2721 "Deleting dynamic neighbor %s group %s upon "
2722 "delete of listen range %s",
2723 peer
->host
, group
->name
, buf
);
2728 /* Get rid of the listen range */
2729 listnode_delete(group
->listen_range
[afi
], prefix
);
2731 /* Remove passwords for deleted ranges */
2732 if (group
->conf
->password
)
2733 bgp_md5_unset_prefix(prefix
);
2738 /* Bind specified peer to peer group. */
2739 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2740 struct peer_group
*group
, as_t
*as
)
2742 int first_member
= 0;
2746 /* Lookup the peer. */
2748 peer
= peer_lookup(bgp
, su
);
2750 /* The peer exist, bind it to the peer-group */
2752 /* When the peer already belongs to a peer-group, check the
2754 if (peer_group_active(peer
)) {
2756 /* The peer is already bound to the peer-group,
2759 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2762 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2765 /* The peer has not specified a remote-as, inherit it from the
2767 if (peer
->as_type
== AS_UNSPECIFIED
) {
2768 peer
->as_type
= group
->conf
->as_type
;
2769 peer
->as
= group
->conf
->as
;
2770 peer
->sort
= group
->conf
->sort
;
2773 if (!group
->conf
->as
&& peer_sort(peer
)) {
2774 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2775 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2778 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2781 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2785 peer_group2peer_config_copy(group
, peer
);
2787 FOREACH_AFI_SAFI (afi
, safi
) {
2788 if (group
->conf
->afc
[afi
][safi
]) {
2789 peer
->afc
[afi
][safi
] = 1;
2791 if (peer_af_find(peer
, afi
, safi
)
2792 || peer_af_create(peer
, afi
, safi
)) {
2793 peer_group2peer_config_copy_af(
2794 group
, peer
, afi
, safi
);
2796 } else if (peer
->afc
[afi
][safi
])
2797 peer_deactivate(peer
, afi
, safi
);
2801 assert(group
&& peer
->group
== group
);
2803 listnode_delete(bgp
->peer
, peer
);
2805 peer
->group
= group
;
2806 listnode_add_sort(bgp
->peer
, peer
);
2808 peer
= peer_lock(peer
); /* group->peer list reference */
2809 listnode_add(group
->peer
, peer
);
2813 /* Advertisement-interval reset */
2814 if (!CHECK_FLAG(group
->conf
->flags
,
2815 PEER_FLAG_ROUTEADV
)) {
2816 group
->conf
->v_routeadv
=
2817 (peer_sort(group
->conf
)
2819 ? BGP_DEFAULT_IBGP_ROUTEADV
2820 : BGP_DEFAULT_EBGP_ROUTEADV
;
2823 /* ebgp-multihop reset */
2824 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2825 group
->conf
->ttl
= MAXTTL
;
2827 /* local-as reset */
2828 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2829 group
->conf
->change_local_as
= 0;
2830 peer_flag_unset(group
->conf
,
2831 PEER_FLAG_LOCAL_AS
);
2832 peer_flag_unset(group
->conf
,
2833 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2834 peer_flag_unset(group
->conf
,
2835 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2839 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2841 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2842 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2843 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2844 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2846 bgp_session_reset(peer
);
2850 /* Create a new peer. */
2852 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2853 && (!group
->conf
->as
)) {
2854 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2857 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2858 group
->conf
->as_type
, 0, 0, group
);
2860 peer
= peer_lock(peer
); /* group->peer list reference */
2861 listnode_add(group
->peer
, peer
);
2863 peer_group2peer_config_copy(group
, peer
);
2865 /* If the peer-group is active for this afi/safi then activate
2867 FOREACH_AFI_SAFI (afi
, safi
) {
2868 if (group
->conf
->afc
[afi
][safi
]) {
2869 peer
->afc
[afi
][safi
] = 1;
2870 peer_af_create(peer
, afi
, safi
);
2871 peer_group2peer_config_copy_af(group
, peer
, afi
,
2873 } else if (peer
->afc
[afi
][safi
])
2874 peer_deactivate(peer
, afi
, safi
);
2877 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2879 /* Set up peer's events and timers. */
2880 if (peer_active(peer
))
2881 bgp_timer_set(peer
);
2887 static int bgp_startup_timer_expire(struct thread
*thread
)
2891 bgp
= THREAD_ARG(thread
);
2892 bgp
->t_startup
= NULL
;
2898 * On shutdown we call the cleanup function which
2899 * does a free of the link list nodes, free up
2900 * the data we are pointing at too.
2902 static void bgp_vrf_string_name_delete(void *data
)
2906 XFREE(MTYPE_TMP
, vname
);
2909 /* BGP instance creation by `router bgp' commands. */
2910 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2911 enum bgp_instance_type inst_type
)
2917 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2920 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2921 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2922 zlog_debug("Creating Default VRF, AS %u", *as
);
2924 zlog_debug("Creating %s %s, AS %u",
2925 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2931 /* Default the EVPN VRF to the default one */
2932 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
2938 bgp
->heuristic_coalesce
= true;
2939 bgp
->inst_type
= inst_type
;
2940 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2942 bgp
->peer_self
= peer_new(bgp
);
2943 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2944 bgp
->peer_self
->host
=
2945 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2946 if (bgp
->peer_self
->hostname
!= NULL
) {
2947 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2948 bgp
->peer_self
->hostname
= NULL
;
2950 if (cmd_hostname_get())
2951 bgp
->peer_self
->hostname
=
2952 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2954 if (bgp
->peer_self
->domainname
!= NULL
) {
2955 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2956 bgp
->peer_self
->domainname
= NULL
;
2958 if (cmd_domainname_get())
2959 bgp
->peer_self
->domainname
=
2960 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2961 bgp
->peer
= list_new();
2962 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2963 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2965 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2967 bgp
->group
= list_new();
2968 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2970 FOREACH_AFI_SAFI (afi
, safi
) {
2971 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2972 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2973 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2975 /* Enable maximum-paths */
2976 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2978 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2982 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2983 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2984 bgp
->default_subgroup_pkt_queue_max
=
2985 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2986 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2987 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2988 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2989 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2990 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2991 bgp
->dynamic_neighbors_count
= 0;
2992 bgp
->ebgp_requires_policy
= DEFAULT_EBGP_POLICY_DISABLED
;
2993 bgp
->reject_as_sets
= BGP_REJECT_AS_SETS_DISABLED
;
2994 #if DFLT_BGP_IMPORT_CHECK
2995 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2997 #if DFLT_BGP_SHOW_HOSTNAME
2998 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
3000 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
3001 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
3003 #if DFLT_BGP_DETERMINISTIC_MED
3004 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
3006 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
3011 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
3012 bgp
->rfapi
= bgp_rfapi_new(bgp
);
3014 assert(bgp
->rfapi_cfg
);
3016 #endif /* ENABLE_BGP_VNC */
3018 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3019 bgp
->vpn_policy
[afi
].bgp
= bgp
;
3020 bgp
->vpn_policy
[afi
].afi
= afi
;
3021 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
3022 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
3025 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
3026 bgp
->vpn_policy
[afi
].import_vrf
->del
=
3027 bgp_vrf_string_name_delete
;
3028 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
3029 bgp
->vpn_policy
[afi
].export_vrf
->del
=
3030 bgp_vrf_string_name_delete
;
3033 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
3035 /* TODO - The startup timer needs to be run for the whole of BGP
3037 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3038 bgp
->restart_time
, &bgp
->t_startup
);
3041 /* printable name we can use in debug messages */
3042 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3043 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3053 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3055 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3056 snprintf(bgp
->name_pretty
, len
, "%s %s",
3057 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3063 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3064 memory_order_relaxed
);
3065 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3066 memory_order_relaxed
);
3067 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3071 update_bgp_group_init(bgp
);
3073 /* assign a unique rd id for auto derivation of vrf's RD */
3074 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3076 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3077 sizeof(struct bgp_evpn_info
));
3084 /* Return the "default VRF" instance of BGP. */
3085 struct bgp
*bgp_get_default(void)
3088 struct listnode
*node
, *nnode
;
3090 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3091 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3096 /* Lookup BGP entry. */
3097 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3100 struct listnode
*node
, *nnode
;
3102 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3104 && ((bgp
->name
== NULL
&& name
== NULL
)
3105 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3110 /* Lookup BGP structure by view name. */
3111 struct bgp
*bgp_lookup_by_name(const char *name
)
3114 struct listnode
*node
, *nnode
;
3116 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3117 if ((bgp
->name
== NULL
&& name
== NULL
)
3118 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3123 /* Lookup BGP instance based on VRF id. */
3124 /* Note: Only to be used for incoming messages from Zebra. */
3125 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3129 /* Lookup VRF (in tree) and follow link. */
3130 vrf
= vrf_lookup_by_id(vrf_id
);
3133 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3136 /* Sets the BGP instance where EVPN is enabled */
3137 void bgp_set_evpn(struct bgp
*bgp
)
3139 if (bm
->bgp_evpn
== bgp
)
3142 /* First, release the reference count we hold on the instance */
3144 bgp_unlock(bm
->bgp_evpn
);
3148 /* Increase the reference count on this new VRF */
3150 bgp_lock(bm
->bgp_evpn
);
3153 /* Returns the BGP instance where EVPN is enabled, if any */
3154 struct bgp
*bgp_get_evpn(void)
3156 return bm
->bgp_evpn
;
3159 /* handle socket creation or deletion, if necessary
3160 * this is called for all new BGP instances
3162 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3167 /* Create BGP server socket, if listen mode not disabled */
3168 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3170 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3172 * suppress vrf socket
3174 if (create
== false) {
3175 bgp_close_vrf_socket(bgp
);
3179 return BGP_ERR_INVALID_VALUE
;
3181 * if vrf_id did not change
3183 if (vrf
->vrf_id
== old_vrf_id
)
3185 if (old_vrf_id
!= VRF_UNKNOWN
) {
3186 /* look for old socket. close it. */
3187 bgp_close_vrf_socket(bgp
);
3189 /* if backend is not yet identified ( VRF_UNKNOWN) then
3190 * creation will be done later
3192 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3194 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3196 return BGP_ERR_INVALID_VALUE
;
3199 return bgp_check_main_socket(create
, bgp
);
3202 /* Called from VTY commands. */
3203 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3204 enum bgp_instance_type inst_type
)
3207 struct vrf
*vrf
= NULL
;
3209 /* Multiple instance check. */
3211 bgp
= bgp_lookup_by_name(name
);
3213 bgp
= bgp_get_default();
3215 /* Already exists. */
3217 if (bgp
->as
!= *as
) {
3219 return BGP_ERR_INSTANCE_MISMATCH
;
3221 if (bgp
->inst_type
!= inst_type
)
3222 return BGP_ERR_INSTANCE_MISMATCH
;
3227 bgp
= bgp_create(as
, name
, inst_type
);
3228 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3229 bgp
->vrf_id
= vrf_generate_id();
3230 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3231 bgp_address_init(bgp
);
3232 bgp_tip_hash_init(bgp
);
3236 bgp
->t_rmap_def_originate_eval
= NULL
;
3238 /* If Default instance or VRF, link to the VRF structure, if present. */
3239 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3240 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3241 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3243 bgp_vrf_link(bgp
, vrf
);
3245 /* BGP server socket already processed if BGP instance
3246 * already part of the list
3248 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3249 listnode_add(bm
->bgp
, bgp
);
3251 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3252 if (BGP_DEBUG(zebra
, ZEBRA
))
3253 zlog_debug("%s: Registering BGP instance %s to zebra",
3254 __PRETTY_FUNCTION__
, name
);
3255 bgp_zebra_instance_register(bgp
);
3262 * Make BGP instance "up". Applies only to VRFs (non-default) and
3263 * implies the VRF has been learnt from Zebra.
3265 void bgp_instance_up(struct bgp
*bgp
)
3268 struct listnode
*node
, *next
;
3270 /* Register with zebra. */
3271 bgp_zebra_instance_register(bgp
);
3273 /* Kick off any peers that may have been configured. */
3274 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3275 if (!BGP_PEER_START_SUPPRESSED(peer
))
3276 BGP_EVENT_ADD(peer
, BGP_Start
);
3279 /* Process any networks that have been configured. */
3280 bgp_static_add(bgp
);
3284 * Make BGP instance "down". Applies only to VRFs (non-default) and
3285 * implies the VRF has been deleted by Zebra.
3287 void bgp_instance_down(struct bgp
*bgp
)
3290 struct listnode
*node
;
3291 struct listnode
*next
;
3294 if (bgp
->t_rmap_def_originate_eval
) {
3295 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3296 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3300 /* Bring down peers, so corresponding routes are purged. */
3301 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3302 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3303 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3304 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3306 bgp_session_reset(peer
);
3309 /* Purge network and redistributed routes. */
3310 bgp_purge_static_redist_routes(bgp
);
3312 /* Cleanup registered nexthops (flags) */
3313 bgp_cleanup_nexthops(bgp
);
3316 /* Delete BGP instance. */
3317 int bgp_delete(struct bgp
*bgp
)
3320 struct peer_group
*group
;
3321 struct listnode
*node
, *next
;
3328 hook_call(bgp_inst_delete
, bgp
);
3330 THREAD_OFF(bgp
->t_startup
);
3331 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3332 THREAD_OFF(bgp
->t_update_delay
);
3333 THREAD_OFF(bgp
->t_establish_wait
);
3335 /* Set flag indicating bgp instance delete in progress */
3336 bgp_flag_set(bgp
, BGP_FLAG_DELETE_IN_PROGRESS
);
3338 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3339 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3340 zlog_debug("Deleting Default VRF");
3342 zlog_debug("Deleting %s %s",
3343 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3349 /* unmap from RT list */
3350 bgp_evpn_vrf_delete(bgp
);
3352 /* unmap bgp vrf label */
3353 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3354 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3357 if (bgp
->t_rmap_def_originate_eval
) {
3358 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3359 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3363 /* Inform peers we're going down. */
3364 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3365 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3366 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3367 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3370 /* Delete static routes (networks). */
3371 bgp_static_delete(bgp
);
3373 /* Unset redistribution. */
3374 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3375 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3376 if (i
!= ZEBRA_ROUTE_BGP
)
3377 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3379 /* Free peers and peer-groups. */
3380 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3381 peer_group_delete(group
);
3383 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3386 if (bgp
->peer_self
) {
3387 peer_delete(bgp
->peer_self
);
3388 bgp
->peer_self
= NULL
;
3391 update_bgp_group_free(bgp
);
3393 /* TODO - Other memory may need to be freed - e.g., NHT */
3398 bgp_cleanup_routes(bgp
);
3400 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3401 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3404 &bgp
->vpn_policy
[afi
]
3405 .import_redirect_rtlist
);
3406 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3409 /* Deregister from Zebra, if needed */
3410 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3411 if (BGP_DEBUG(zebra
, ZEBRA
))
3412 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3413 __PRETTY_FUNCTION__
, bgp
->name
);
3414 bgp_zebra_instance_deregister(bgp
);
3417 /* Remove visibility via the master list - there may however still be
3418 * routes to be processed still referencing the struct bgp.
3420 listnode_delete(bm
->bgp
, bgp
);
3422 /* Free interfaces in this instance. */
3425 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3426 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3428 bgp_vrf_unlink(bgp
, vrf
);
3430 /* Update EVPN VRF pointer */
3431 if (bm
->bgp_evpn
== bgp
) {
3432 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3435 bgp_set_evpn(bgp_get_default());
3438 thread_master_free_unused(bm
->master
);
3439 bgp_unlock(bgp
); /* initial reference */
3444 void bgp_free(struct bgp
*bgp
)
3448 struct bgp_table
*table
;
3449 struct bgp_node
*rn
;
3450 struct bgp_rmap
*rmap
;
3454 list_delete(&bgp
->group
);
3455 list_delete(&bgp
->peer
);
3457 if (bgp
->peerhash
) {
3458 hash_free(bgp
->peerhash
);
3459 bgp
->peerhash
= NULL
;
3462 FOREACH_AFI_SAFI (afi
, safi
) {
3463 /* Special handling for 2-level routing tables. */
3464 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3465 || safi
== SAFI_EVPN
) {
3466 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3467 rn
= bgp_route_next(rn
)) {
3468 table
= bgp_node_get_bgp_table_info(rn
);
3469 bgp_table_finish(&table
);
3472 if (bgp
->route
[afi
][safi
])
3473 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3474 if (bgp
->aggregate
[afi
][safi
])
3475 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3476 if (bgp
->rib
[afi
][safi
])
3477 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3478 rmap
= &bgp
->table_map
[afi
][safi
];
3479 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3482 bgp_scan_finish(bgp
);
3483 bgp_address_destroy(bgp
);
3484 bgp_tip_hash_destroy(bgp
);
3486 /* release the auto RD id */
3487 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3489 bgp_evpn_cleanup(bgp
);
3490 bgp_pbr_cleanup(bgp
);
3491 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3493 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3494 vpn_policy_direction_t dir
;
3496 if (bgp
->vpn_policy
[afi
].import_vrf
)
3497 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3498 if (bgp
->vpn_policy
[afi
].export_vrf
)
3499 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3501 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3502 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3503 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3504 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3505 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3506 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3509 XFREE(MTYPE_BGP
, bgp
->name
);
3510 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3512 XFREE(MTYPE_BGP
, bgp
);
3515 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3518 struct listnode
*node
, *nnode
;
3524 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3525 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3526 && !CHECK_FLAG(peer
->sflags
,
3527 PEER_STATUS_ACCEPT_PEER
))
3529 } else if (bm
->bgp
!= NULL
) {
3530 struct listnode
*bgpnode
, *nbgpnode
;
3532 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3533 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3535 && !strcmp(peer
->conf_if
, conf_if
)
3536 && !CHECK_FLAG(peer
->sflags
,
3537 PEER_STATUS_ACCEPT_PEER
))
3543 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3546 struct listnode
*node
, *nnode
;
3552 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3553 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3554 && !CHECK_FLAG(peer
->sflags
,
3555 PEER_STATUS_ACCEPT_PEER
))
3557 } else if (bm
->bgp
!= NULL
) {
3558 struct listnode
*bgpnode
, *nbgpnode
;
3560 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3561 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3563 && !strcmp(peer
->hostname
, hostname
)
3564 && !CHECK_FLAG(peer
->sflags
,
3565 PEER_STATUS_ACCEPT_PEER
))
3571 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3573 struct peer
*peer
= NULL
;
3574 struct peer tmp_peer
;
3576 memset(&tmp_peer
, 0, sizeof(struct peer
));
3579 * We do not want to find the doppelganger peer so search for the peer
3581 * the hash that has PEER_FLAG_CONFIG_NODE
3583 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3588 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3589 } else if (bm
->bgp
!= NULL
) {
3590 struct listnode
*bgpnode
, *nbgpnode
;
3592 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3593 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3602 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3603 union sockunion
*su
,
3604 struct peer_group
*group
)
3610 /* Create peer first; we've already checked group config is valid. */
3611 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3612 group
->conf
->as_type
, 0, 0, group
);
3617 peer
= peer_lock(peer
);
3618 listnode_add(group
->peer
, peer
);
3620 peer_group2peer_config_copy(group
, peer
);
3623 * Bind peer for all AFs configured for the group. We don't call
3624 * peer_group_bind as that is sub-optimal and does some stuff we don't
3627 FOREACH_AFI_SAFI (afi
, safi
) {
3628 if (!group
->conf
->afc
[afi
][safi
])
3630 peer
->afc
[afi
][safi
] = 1;
3632 if (!peer_af_find(peer
, afi
, safi
))
3633 peer_af_create(peer
, afi
, safi
);
3635 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3638 /* Mark as dynamic, but also as a "config node" for other things to
3640 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3641 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3647 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3648 struct prefix
*prefix
)
3650 struct listnode
*node
, *nnode
;
3651 struct prefix
*range
;
3654 afi
= family2afi(prefix
->family
);
3656 if (group
->listen_range
[afi
])
3657 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3659 if (prefix_match(range
, prefix
))
3666 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3667 struct prefix
**listen_range
)
3669 struct prefix
*range
= NULL
;
3670 struct peer_group
*group
= NULL
;
3671 struct listnode
*node
, *nnode
;
3673 *listen_range
= NULL
;
3675 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3676 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3679 } else if (bm
->bgp
!= NULL
) {
3680 struct listnode
*bgpnode
, *nbgpnode
;
3682 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3683 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3684 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3690 *listen_range
= range
;
3691 return (group
&& range
) ? group
: NULL
;
3694 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3696 struct peer_group
*group
;
3699 struct prefix prefix
;
3700 struct prefix
*listen_range
;
3702 char buf
[PREFIX2STR_BUFFER
];
3703 char buf1
[PREFIX2STR_BUFFER
];
3705 sockunion2hostprefix(su
, &prefix
);
3707 /* See if incoming connection matches a configured listen range. */
3708 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3719 prefix2str(&prefix
, buf
, sizeof(buf
));
3720 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3722 if (bgp_debug_neighbor_events(NULL
))
3724 "Dynamic Neighbor %s matches group %s listen range %s",
3725 buf
, group
->name
, buf1
);
3727 /* Are we within the listen limit? */
3728 dncount
= gbgp
->dynamic_neighbors_count
;
3730 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3731 if (bgp_debug_neighbor_events(NULL
))
3732 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3733 inet_sutop(su
, buf
),
3734 gbgp
->dynamic_neighbors_limit
);
3738 /* Ensure group is not disabled. */
3739 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3740 if (bgp_debug_neighbor_events(NULL
))
3742 "Dynamic Neighbor %s rejected - group %s disabled",
3747 /* Check that at least one AF is activated for the group. */
3748 if (!peer_group_af_configured(group
)) {
3749 if (bgp_debug_neighbor_events(NULL
))
3751 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3756 /* Create dynamic peer and bind to associated group. */
3757 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3760 gbgp
->dynamic_neighbors_count
= ++dncount
;
3762 if (bgp_debug_neighbor_events(peer
))
3763 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3764 peer
->host
, group
->name
, dncount
);
3769 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3772 if (peer
->group
->bgp
) {
3773 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3775 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3777 if (bgp_debug_neighbor_events(peer
))
3778 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3779 peer
->group
->name
, dncount
);
3782 /* If peer is configured at least one address family return 1. */
3783 int peer_active(struct peer
*peer
)
3785 if (BGP_PEER_SU_UNSPEC(peer
))
3787 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3788 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3789 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3790 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3791 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3792 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3793 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3794 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3795 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3796 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3797 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3802 /* If peer is negotiated at least one address family return 1. */
3803 int peer_active_nego(struct peer
*peer
)
3805 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3806 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3807 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3808 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3809 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3810 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3811 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3812 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3813 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3814 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3815 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3816 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3817 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3822 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3823 enum peer_change_type type
)
3825 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3828 if (peer
->status
!= Established
)
3831 if (type
== peer_change_reset
) {
3832 /* If we're resetting session, we've to delete both peer struct
3834 if ((peer
->doppelganger
)
3835 && (peer
->doppelganger
->status
!= Deleted
)
3836 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3837 PEER_FLAG_CONFIG_NODE
)))
3838 peer_delete(peer
->doppelganger
);
3840 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3841 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3842 } else if (type
== peer_change_reset_in
) {
3843 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3844 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3845 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3847 if ((peer
->doppelganger
)
3848 && (peer
->doppelganger
->status
!= Deleted
)
3849 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3850 PEER_FLAG_CONFIG_NODE
)))
3851 peer_delete(peer
->doppelganger
);
3853 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3854 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3856 } else if (type
== peer_change_reset_out
) {
3857 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3858 bgp_announce_route(peer
, afi
, safi
);
3862 struct peer_flag_action
{
3866 /* This flag can be set for peer-group member. */
3867 uint8_t not_for_member
;
3869 /* Action when the flag is changed. */
3870 enum peer_change_type type
;
3873 static const struct peer_flag_action peer_flag_action_list
[] = {
3874 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3875 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3876 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3877 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3878 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3879 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3880 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3881 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3882 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3883 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3884 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3885 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3886 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3887 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3888 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3889 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3890 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3891 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3894 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3895 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3896 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3897 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3898 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3899 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3900 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3901 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3902 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3903 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3904 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3905 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3906 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3907 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3908 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3909 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3910 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3911 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3912 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3913 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3914 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3915 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3916 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3917 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3918 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3919 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3922 /* Proper action set. */
3923 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3924 int size
, struct peer_flag_action
*action
,
3931 const struct peer_flag_action
*match
= NULL
;
3933 /* Check peer's frag action. */
3934 for (i
= 0; i
< size
; i
++) {
3935 match
= &action_list
[i
];
3937 if (match
->flag
== 0)
3940 if (match
->flag
& flag
) {
3943 if (match
->type
== peer_change_reset_in
)
3945 if (match
->type
== peer_change_reset_out
)
3947 if (match
->type
== peer_change_reset
) {
3951 if (match
->not_for_member
)
3952 action
->not_for_member
= 1;
3956 /* Set peer clear type. */
3957 if (reset_in
&& reset_out
)
3958 action
->type
= peer_change_reset
;
3960 action
->type
= peer_change_reset_in
;
3962 action
->type
= peer_change_reset_out
;
3964 action
->type
= peer_change_none
;
3969 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3971 if (flag
== PEER_FLAG_SHUTDOWN
) {
3972 if (CHECK_FLAG(peer
->flags
, flag
)) {
3973 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3974 peer_nsf_stop(peer
);
3976 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3977 if (peer
->t_pmax_restart
) {
3978 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3979 if (bgp_debug_neighbor_events(peer
))
3981 "%s Maximum-prefix restart timer canceled",
3985 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3986 peer_nsf_stop(peer
);
3988 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3989 char *msg
= peer
->tx_shutdown_message
;
3992 if (!msg
&& peer_group_active(peer
))
3993 msg
= peer
->group
->conf
3994 ->tx_shutdown_message
;
3995 msglen
= msg
? strlen(msg
) : 0;
4000 uint8_t msgbuf
[129];
4003 memcpy(msgbuf
+ 1, msg
, msglen
);
4005 bgp_notify_send_with_data(
4006 peer
, BGP_NOTIFY_CEASE
,
4007 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
4008 msgbuf
, msglen
+ 1);
4011 peer
, BGP_NOTIFY_CEASE
,
4012 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
4014 bgp_session_reset(peer
);
4016 peer
->v_start
= BGP_INIT_START_TIMER
;
4017 BGP_EVENT_ADD(peer
, BGP_Stop
);
4019 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4020 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
4021 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4022 else if (flag
== PEER_FLAG_PASSIVE
)
4023 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
4024 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
4025 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
4027 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4028 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4030 bgp_session_reset(peer
);
4033 /* Change specified peer flag. */
4034 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
4038 bool invert
, member_invert
;
4039 struct peer
*member
;
4040 struct listnode
*node
, *nnode
;
4041 struct peer_flag_action action
;
4043 memset(&action
, 0, sizeof(struct peer_flag_action
));
4044 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
4046 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4047 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4050 /* Abort if no flag action exists. */
4052 return BGP_ERR_INVALID_FLAG
;
4054 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4055 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4056 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4057 return BGP_ERR_PEER_FLAG_CONFLICT
;
4059 /* Handle flag updates where desired state matches current state. */
4060 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4061 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4062 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4066 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4067 COND_FLAG(peer
->flags_override
, flag
, invert
);
4072 /* Inherit from peer-group or set/unset flags accordingly. */
4073 if (peer_group_active(peer
) && set
== invert
)
4074 peer_flag_inherit(peer
, flag
);
4076 COND_FLAG(peer
->flags
, flag
, set
);
4078 /* Check if handling a regular peer. */
4079 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4080 /* Update flag override state accordingly. */
4081 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4083 /* Execute flag action on peer. */
4084 if (action
.type
== peer_change_reset
)
4085 peer_flag_modify_action(peer
, flag
);
4087 /* Skip peer-group mechanics for regular peers. */
4091 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4092 bgp_nht_register_enhe_capability_interfaces(peer
);
4095 * Update peer-group members, unless they are explicitely overriding
4096 * peer-group configuration.
4098 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4099 /* Skip peers with overridden configuration. */
4100 if (CHECK_FLAG(member
->flags_override
, flag
))
4103 /* Check if only member without group is inverted. */
4105 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4107 /* Skip peers with equivalent configuration. */
4108 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4111 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4114 /* Update flag on peer-group member. */
4115 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4117 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4118 bgp_nht_register_enhe_capability_interfaces(member
);
4120 /* Execute flag action on peer-group member. */
4121 if (action
.type
== peer_change_reset
)
4122 peer_flag_modify_action(member
, flag
);
4128 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4130 return peer_flag_modify(peer
, flag
, 1);
4133 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4135 return peer_flag_modify(peer
, flag
, 0);
4138 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4139 uint32_t flag
, bool set
)
4143 bool invert
, member_invert
;
4144 struct peer
*member
;
4145 struct listnode
*node
, *nnode
;
4146 struct peer_flag_action action
;
4148 memset(&action
, 0, sizeof(struct peer_flag_action
));
4149 size
= sizeof peer_af_flag_action_list
4150 / sizeof(struct peer_flag_action
);
4152 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4153 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4156 /* Abort if flag action exists. */
4158 return BGP_ERR_INVALID_FLAG
;
4160 /* Special check for reflector client. */
4161 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4162 && peer_sort(peer
) != BGP_PEER_IBGP
)
4163 return BGP_ERR_NOT_INTERNAL_PEER
;
4165 /* Special check for remove-private-AS. */
4166 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4167 && peer_sort(peer
) == BGP_PEER_IBGP
)
4168 return BGP_ERR_REMOVE_PRIVATE_AS
;
4170 /* as-override is not allowed for IBGP peers */
4171 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4172 return BGP_ERR_AS_OVERRIDE
;
4174 /* Handle flag updates where desired state matches current state. */
4175 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4176 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4177 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4182 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4183 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4190 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4191 * if we are setting/unsetting flags which conflict with this flag
4192 * handle accordingly
4194 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4198 * if we are setting NEXTHOP_SELF, we need to unset the
4199 * NEXTHOP_UNCHANGED flag
4201 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4202 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4203 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4204 PEER_FLAG_NEXTHOP_UNCHANGED
);
4208 * if we are unsetting NEXTHOP_SELF, we need to set the
4209 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4211 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4212 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4213 SET_FLAG(peer
->af_flags
[afi
][safi
],
4214 PEER_FLAG_NEXTHOP_UNCHANGED
);
4218 /* Inherit from peer-group or set/unset flags accordingly. */
4219 if (peer_group_active(peer
) && set
== invert
)
4220 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4222 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4224 /* Execute action when peer is established. */
4225 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4226 && peer
->status
== Established
) {
4227 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4228 bgp_clear_adj_in(peer
, afi
, safi
);
4230 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4231 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4232 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4233 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4234 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4235 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4236 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4237 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4239 peer_change_action(peer
, afi
, safi
, action
.type
);
4243 /* Check if handling a regular peer. */
4244 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4245 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4249 * Update peer-group members, unless they are explicitely
4250 * overriding peer-group configuration.
4252 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4254 /* Skip peers with overridden configuration. */
4255 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4259 /* Check if only member without group is inverted. */
4261 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4265 /* Skip peers with equivalent configuration. */
4266 if (set
!= member_invert
4267 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4270 if (set
== member_invert
4271 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4274 /* Update flag on peer-group member. */
4275 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4276 set
!= member_invert
);
4278 /* Execute flag action on peer-group member. */
4279 if (member
->status
== Established
) {
4280 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4281 bgp_clear_adj_in(member
, afi
, safi
);
4283 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4284 member
->last_reset
=
4285 PEER_DOWN_RR_CLIENT_CHANGE
;
4287 == PEER_FLAG_RSERVER_CLIENT
)
4288 member
->last_reset
=
4289 PEER_DOWN_RS_CLIENT_CHANGE
;
4291 == PEER_FLAG_ORF_PREFIX_SM
)
4292 member
->last_reset
=
4293 PEER_DOWN_CAPABILITY_CHANGE
;
4295 == PEER_FLAG_ORF_PREFIX_RM
)
4296 member
->last_reset
=
4297 PEER_DOWN_CAPABILITY_CHANGE
;
4299 peer_change_action(member
, afi
, safi
,
4309 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4311 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4314 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4316 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4320 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4322 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4323 peer
->tx_shutdown_message
=
4324 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4328 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4330 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4335 /* EBGP multihop configuration. */
4336 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4338 struct peer_group
*group
;
4339 struct listnode
*node
, *nnode
;
4342 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4345 /* see comment in peer_ttl_security_hops_set() */
4346 if (ttl
!= MAXTTL
) {
4347 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4348 group
= peer
->group
;
4349 if (group
->conf
->gtsm_hops
!= 0)
4350 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4352 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4354 if (peer1
->sort
== BGP_PEER_IBGP
)
4357 if (peer1
->gtsm_hops
!= 0)
4358 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4361 if (peer
->gtsm_hops
!= 0)
4362 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4368 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4369 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4370 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4371 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4372 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4374 bgp_session_reset(peer
);
4377 group
= peer
->group
;
4378 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4379 if (peer
->sort
== BGP_PEER_IBGP
)
4382 peer
->ttl
= group
->conf
->ttl
;
4384 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4385 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4386 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4388 bgp_session_reset(peer
);
4394 int peer_ebgp_multihop_unset(struct peer
*peer
)
4396 struct peer_group
*group
;
4397 struct listnode
*node
, *nnode
;
4399 if (peer
->sort
== BGP_PEER_IBGP
)
4402 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4403 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4405 if (peer_group_active(peer
))
4406 peer
->ttl
= peer
->group
->conf
->ttl
;
4408 peer
->ttl
= BGP_DEFAULT_TTL
;
4410 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4411 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4412 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4413 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4415 bgp_session_reset(peer
);
4417 group
= peer
->group
;
4418 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4419 if (peer
->sort
== BGP_PEER_IBGP
)
4422 peer
->ttl
= BGP_DEFAULT_TTL
;
4424 if (peer
->fd
>= 0) {
4425 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4427 peer
, BGP_NOTIFY_CEASE
,
4428 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4430 bgp_session_reset(peer
);
4437 /* Neighbor description. */
4438 int peer_description_set(struct peer
*peer
, const char *desc
)
4440 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4442 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4447 int peer_description_unset(struct peer
*peer
)
4449 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4456 /* Neighbor update-source. */
4457 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4459 struct peer
*member
;
4460 struct listnode
*node
, *nnode
;
4462 /* Set flag and configuration on peer. */
4463 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4464 if (peer
->update_if
) {
4465 if (strcmp(peer
->update_if
, ifname
) == 0)
4467 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4469 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4470 sockunion_free(peer
->update_source
);
4471 peer
->update_source
= NULL
;
4473 /* Check if handling a regular peer. */
4474 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4475 /* Send notification or reset peer depending on state. */
4476 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4477 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4478 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4479 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4481 bgp_session_reset(peer
);
4483 /* Skip peer-group mechanics for regular peers. */
4488 * Set flag and configuration on all peer-group members, unless they are
4489 * explicitely overriding peer-group configuration.
4491 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4492 /* Skip peers with overridden configuration. */
4493 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4496 /* Skip peers with the same configuration. */
4497 if (member
->update_if
) {
4498 if (strcmp(member
->update_if
, ifname
) == 0)
4500 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4503 /* Set flag and configuration on peer-group member. */
4504 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4505 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4506 sockunion_free(member
->update_source
);
4507 member
->update_source
= NULL
;
4509 /* Send notification or reset peer depending on state. */
4510 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4511 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4512 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4513 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4515 bgp_session_reset(member
);
4521 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4523 struct peer
*member
;
4524 struct listnode
*node
, *nnode
;
4526 /* Set flag and configuration on peer. */
4527 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4528 if (peer
->update_source
) {
4529 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4531 sockunion_free(peer
->update_source
);
4533 peer
->update_source
= sockunion_dup(su
);
4534 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4536 /* Check if handling a regular peer. */
4537 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4538 /* Send notification or reset peer depending on state. */
4539 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4540 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4541 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4542 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4544 bgp_session_reset(peer
);
4546 /* Skip peer-group mechanics for regular peers. */
4551 * Set flag and configuration on all peer-group members, unless they are
4552 * explicitely overriding peer-group configuration.
4554 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4555 /* Skip peers with overridden configuration. */
4556 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4559 /* Skip peers with the same configuration. */
4560 if (member
->update_source
) {
4561 if (sockunion_cmp(member
->update_source
, su
) == 0)
4563 sockunion_free(member
->update_source
);
4566 /* Set flag and configuration on peer-group member. */
4567 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4568 member
->update_source
= sockunion_dup(su
);
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_update_source_unset(struct peer
*peer
)
4585 struct peer
*member
;
4586 struct listnode
*node
, *nnode
;
4588 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4591 /* Inherit configuration from peer-group if peer is member. */
4592 if (peer_group_active(peer
)) {
4593 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4594 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4595 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4596 MTYPE_PEER_UPDATE_SOURCE
);
4598 /* Otherwise remove flag and configuration from peer. */
4599 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4600 sockunion_free(peer
->update_source
);
4601 peer
->update_source
= NULL
;
4602 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4605 /* Check if handling a regular peer. */
4606 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4607 /* Send notification or reset peer depending on state. */
4608 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4609 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4610 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4611 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4613 bgp_session_reset(peer
);
4615 /* Skip peer-group mechanics for regular peers. */
4620 * Set flag and configuration on all peer-group members, unless they are
4621 * explicitely overriding peer-group configuration.
4623 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4624 /* Skip peers with overridden configuration. */
4625 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4628 /* Skip peers with the same configuration. */
4629 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4630 && !member
->update_source
&& !member
->update_if
)
4633 /* Remove flag and configuration on peer-group member. */
4634 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4635 sockunion_free(member
->update_source
);
4636 member
->update_source
= NULL
;
4637 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4639 /* Send notification or reset peer depending on state. */
4640 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4641 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4642 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4643 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4645 bgp_session_reset(member
);
4651 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4652 const char *rmap
, struct route_map
*route_map
)
4654 struct peer
*member
;
4655 struct listnode
*node
, *nnode
;
4657 /* Set flag and configuration on peer. */
4658 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4660 if (!peer
->default_rmap
[afi
][safi
].name
4661 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4662 if (peer
->default_rmap
[afi
][safi
].name
)
4663 XFREE(MTYPE_ROUTE_MAP_NAME
,
4664 peer
->default_rmap
[afi
][safi
].name
);
4666 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4667 peer
->default_rmap
[afi
][safi
].name
=
4668 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4669 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4670 route_map_counter_increment(route_map
);
4673 if (peer
->default_rmap
[afi
][safi
].name
)
4674 XFREE(MTYPE_ROUTE_MAP_NAME
,
4675 peer
->default_rmap
[afi
][safi
].name
);
4677 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4678 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4679 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4682 /* Check if handling a regular peer. */
4683 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4684 /* Update peer route announcements. */
4685 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4686 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4687 bgp_default_originate(peer
, afi
, safi
, 0);
4688 bgp_announce_route(peer
, afi
, safi
);
4691 /* Skip peer-group mechanics for regular peers. */
4696 * Set flag and configuration on all peer-group members, unless they are
4697 * explicitely overriding peer-group configuration.
4699 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4700 /* Skip peers with overridden configuration. */
4701 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4702 PEER_FLAG_DEFAULT_ORIGINATE
))
4705 /* Set flag and configuration on peer-group member. */
4706 SET_FLAG(member
->af_flags
[afi
][safi
],
4707 PEER_FLAG_DEFAULT_ORIGINATE
);
4709 if (member
->default_rmap
[afi
][safi
].name
)
4710 XFREE(MTYPE_ROUTE_MAP_NAME
,
4711 member
->default_rmap
[afi
][safi
].name
);
4712 route_map_counter_decrement(
4713 member
->default_rmap
[afi
][safi
].map
);
4714 member
->default_rmap
[afi
][safi
].name
=
4715 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4716 member
->default_rmap
[afi
][safi
].map
= route_map
;
4717 route_map_counter_increment(route_map
);
4720 /* Update peer route announcements. */
4721 if (member
->status
== Established
4722 && member
->afc_nego
[afi
][safi
]) {
4723 update_group_adjust_peer(
4724 peer_af_find(member
, afi
, safi
));
4725 bgp_default_originate(member
, afi
, safi
, 0);
4726 bgp_announce_route(member
, afi
, safi
);
4733 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4735 struct peer
*member
;
4736 struct listnode
*node
, *nnode
;
4738 /* Inherit configuration from peer-group if peer is member. */
4739 if (peer_group_active(peer
)) {
4740 peer_af_flag_inherit(peer
, afi
, safi
,
4741 PEER_FLAG_DEFAULT_ORIGINATE
);
4742 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4743 default_rmap
[afi
][safi
].name
,
4744 MTYPE_ROUTE_MAP_NAME
);
4745 PEER_ATTR_INHERIT(peer
, peer
->group
,
4746 default_rmap
[afi
][safi
].map
);
4748 /* Otherwise remove flag and configuration from peer. */
4749 peer_af_flag_unset(peer
, afi
, safi
,
4750 PEER_FLAG_DEFAULT_ORIGINATE
);
4751 if (peer
->default_rmap
[afi
][safi
].name
)
4752 XFREE(MTYPE_ROUTE_MAP_NAME
,
4753 peer
->default_rmap
[afi
][safi
].name
);
4754 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4755 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4756 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4759 /* Check if handling a regular peer. */
4760 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4761 /* Update peer route announcements. */
4762 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4763 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4764 bgp_default_originate(peer
, afi
, safi
, 1);
4765 bgp_announce_route(peer
, afi
, safi
);
4768 /* Skip peer-group mechanics for regular peers. */
4773 * Remove flag and configuration from all peer-group members, unless
4774 * they are explicitely overriding peer-group configuration.
4776 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4777 /* Skip peers with overridden configuration. */
4778 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4779 PEER_FLAG_DEFAULT_ORIGINATE
))
4782 /* Remove flag and configuration on peer-group member. */
4783 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4784 PEER_FLAG_DEFAULT_ORIGINATE
);
4785 if (peer
->default_rmap
[afi
][safi
].name
)
4786 XFREE(MTYPE_ROUTE_MAP_NAME
,
4787 peer
->default_rmap
[afi
][safi
].name
);
4788 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4789 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4790 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4792 /* Update peer route announcements. */
4793 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4794 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4795 bgp_default_originate(peer
, afi
, safi
, 1);
4796 bgp_announce_route(peer
, afi
, safi
);
4803 int peer_port_set(struct peer
*peer
, uint16_t port
)
4809 int peer_port_unset(struct peer
*peer
)
4811 peer
->port
= BGP_PORT_DEFAULT
;
4816 * Helper function that is called after the name of the policy
4817 * being used by a peer has changed (AF specific). Automatically
4818 * initiates inbound or outbound processing as needed.
4820 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4824 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4825 if (peer
->status
== Established
)
4826 bgp_announce_route(peer
, afi
, safi
);
4828 if (peer
->status
!= Established
)
4831 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4832 PEER_FLAG_SOFT_RECONFIG
))
4833 bgp_soft_reconfig_in(peer
, afi
, safi
);
4834 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4835 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4836 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4841 /* neighbor weight. */
4842 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4844 struct peer
*member
;
4845 struct listnode
*node
, *nnode
;
4847 /* Set flag and configuration on peer. */
4848 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4849 if (peer
->weight
[afi
][safi
] != weight
) {
4850 peer
->weight
[afi
][safi
] = weight
;
4851 peer_on_policy_change(peer
, afi
, safi
, 0);
4854 /* Skip peer-group mechanics for regular peers. */
4855 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4859 * Set flag and configuration on all peer-group members, unless they are
4860 * explicitely overriding peer-group configuration.
4862 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4863 /* Skip peers with overridden configuration. */
4864 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4868 /* Set flag and configuration on peer-group member. */
4869 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4870 if (member
->weight
[afi
][safi
] != weight
) {
4871 member
->weight
[afi
][safi
] = weight
;
4872 peer_on_policy_change(member
, afi
, safi
, 0);
4879 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4881 struct peer
*member
;
4882 struct listnode
*node
, *nnode
;
4884 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4887 /* Inherit configuration from peer-group if peer is member. */
4888 if (peer_group_active(peer
)) {
4889 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4890 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4892 peer_on_policy_change(peer
, afi
, safi
, 0);
4896 /* Remove flag and configuration from peer. */
4897 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4898 peer
->weight
[afi
][safi
] = 0;
4899 peer_on_policy_change(peer
, afi
, safi
, 0);
4901 /* Skip peer-group mechanics for regular peers. */
4902 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4906 * Remove flag and configuration from all peer-group members, unless
4907 * they are explicitely overriding peer-group configuration.
4909 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4910 /* Skip peers with overridden configuration. */
4911 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4915 /* Skip peers where flag is already disabled. */
4916 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4919 /* Remove flag and configuration on peer-group member. */
4920 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4921 member
->weight
[afi
][safi
] = 0;
4922 peer_on_policy_change(member
, afi
, safi
, 0);
4928 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4930 struct peer
*member
;
4931 struct listnode
*node
, *nnode
;
4933 if (keepalive
> 65535)
4934 return BGP_ERR_INVALID_VALUE
;
4936 if (holdtime
> 65535)
4937 return BGP_ERR_INVALID_VALUE
;
4939 if (holdtime
< 3 && holdtime
!= 0)
4940 return BGP_ERR_INVALID_VALUE
;
4942 /* Set flag and configuration on peer. */
4943 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4944 peer
->holdtime
= holdtime
;
4945 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4947 /* Skip peer-group mechanics for regular peers. */
4948 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4952 * Set flag and configuration on all peer-group members, unless they are
4953 * explicitely overriding peer-group configuration.
4955 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4956 /* Skip peers with overridden configuration. */
4957 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4960 /* Set flag and configuration on peer-group member. */
4961 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4962 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4963 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4969 int peer_timers_unset(struct peer
*peer
)
4971 struct peer
*member
;
4972 struct listnode
*node
, *nnode
;
4974 /* Inherit configuration from peer-group if peer is member. */
4975 if (peer_group_active(peer
)) {
4976 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4977 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4978 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4980 /* Otherwise remove flag and configuration from peer. */
4981 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4983 peer
->keepalive
= 0;
4986 /* Skip peer-group mechanics for regular peers. */
4987 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4991 * Remove flag and configuration from all peer-group members, unless
4992 * they are explicitely overriding peer-group configuration.
4994 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4995 /* Skip peers with overridden configuration. */
4996 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4999 /* Remove flag and configuration on peer-group member. */
5000 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
5001 member
->holdtime
= 0;
5002 member
->keepalive
= 0;
5008 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
5010 struct peer
*member
;
5011 struct listnode
*node
, *nnode
;
5013 if (connect
> 65535)
5014 return BGP_ERR_INVALID_VALUE
;
5016 /* Set flag and configuration on peer. */
5017 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
5018 peer
->connect
= connect
;
5019 peer
->v_connect
= connect
;
5021 /* Skip peer-group mechanics for regular peers. */
5022 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5026 * Set flag and configuration on all peer-group members, unless they are
5027 * explicitely overriding peer-group configuration.
5029 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5030 /* Skip peers with overridden configuration. */
5031 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5034 /* Set flag and configuration on peer-group member. */
5035 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5036 member
->connect
= connect
;
5037 member
->v_connect
= connect
;
5043 int peer_timers_connect_unset(struct peer
*peer
)
5045 struct peer
*member
;
5046 struct listnode
*node
, *nnode
;
5048 /* Inherit configuration from peer-group if peer is member. */
5049 if (peer_group_active(peer
)) {
5050 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5051 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5053 /* Otherwise remove flag and configuration from peer. */
5054 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5058 /* Set timer with fallback to default value. */
5060 peer
->v_connect
= peer
->connect
;
5062 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5064 /* Skip peer-group mechanics for regular peers. */
5065 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5069 * Remove flag and configuration from all peer-group members, unless
5070 * they are explicitely overriding peer-group configuration.
5072 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5073 /* Skip peers with overridden configuration. */
5074 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5077 /* Remove flag and configuration on peer-group member. */
5078 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5079 member
->connect
= 0;
5080 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5086 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5088 struct peer
*member
;
5089 struct listnode
*node
, *nnode
;
5092 return BGP_ERR_INVALID_VALUE
;
5094 /* Set flag and configuration on peer. */
5095 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5096 peer
->routeadv
= routeadv
;
5097 peer
->v_routeadv
= routeadv
;
5099 /* Check if handling a regular peer. */
5100 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5101 /* Update peer route announcements. */
5102 update_group_adjust_peer_afs(peer
);
5103 if (peer
->status
== Established
)
5104 bgp_announce_route_all(peer
);
5106 /* Skip peer-group mechanics for regular peers. */
5111 * Set flag and configuration on all peer-group members, unless they are
5112 * explicitely overriding peer-group configuration.
5114 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5115 /* Skip peers with overridden configuration. */
5116 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5119 /* Set flag and configuration on peer-group member. */
5120 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5121 member
->routeadv
= routeadv
;
5122 member
->v_routeadv
= routeadv
;
5124 /* Update peer route announcements. */
5125 update_group_adjust_peer_afs(member
);
5126 if (member
->status
== Established
)
5127 bgp_announce_route_all(member
);
5133 int peer_advertise_interval_unset(struct peer
*peer
)
5135 struct peer
*member
;
5136 struct listnode
*node
, *nnode
;
5138 /* Inherit configuration from peer-group if peer is member. */
5139 if (peer_group_active(peer
)) {
5140 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5141 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5143 /* Otherwise remove flag and configuration from peer. */
5144 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5148 /* Set timer with fallback to default value. */
5150 peer
->v_routeadv
= peer
->routeadv
;
5152 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5153 ? BGP_DEFAULT_IBGP_ROUTEADV
5154 : BGP_DEFAULT_EBGP_ROUTEADV
;
5156 /* Check if handling a regular peer. */
5157 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5158 /* Update peer route announcements. */
5159 update_group_adjust_peer_afs(peer
);
5160 if (peer
->status
== Established
)
5161 bgp_announce_route_all(peer
);
5163 /* Skip peer-group mechanics for regular peers. */
5168 * Remove flag and configuration from all peer-group members, unless
5169 * they are explicitely overriding peer-group configuration.
5171 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5172 /* Skip peers with overridden configuration. */
5173 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5176 /* Remove flag and configuration on peer-group member. */
5177 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5178 member
->routeadv
= 0;
5179 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5180 ? BGP_DEFAULT_IBGP_ROUTEADV
5181 : BGP_DEFAULT_EBGP_ROUTEADV
;
5183 /* Update peer route announcements. */
5184 update_group_adjust_peer_afs(member
);
5185 if (member
->status
== Established
)
5186 bgp_announce_route_all(member
);
5192 /* neighbor interface */
5193 void peer_interface_set(struct peer
*peer
, const char *str
)
5195 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5196 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5199 void peer_interface_unset(struct peer
*peer
)
5201 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5202 peer
->ifname
= NULL
;
5206 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5207 int allow_num
, int origin
)
5209 struct peer
*member
;
5210 struct listnode
*node
, *nnode
;
5212 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5213 return BGP_ERR_INVALID_VALUE
;
5215 /* Set flag and configuration on peer. */
5216 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5218 if (peer
->allowas_in
[afi
][safi
] != 0
5219 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5220 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5221 peer_af_flag_set(peer
, afi
, safi
,
5222 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5223 peer
->allowas_in
[afi
][safi
] = 0;
5224 peer_on_policy_change(peer
, afi
, safi
, 0);
5227 if (peer
->allowas_in
[afi
][safi
] != allow_num
5228 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5229 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5231 peer_af_flag_unset(peer
, afi
, safi
,
5232 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5233 peer
->allowas_in
[afi
][safi
] = allow_num
;
5234 peer_on_policy_change(peer
, afi
, safi
, 0);
5238 /* Skip peer-group mechanics for regular peers. */
5239 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5243 * Set flag and configuration on 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 /* Set flag and configuration on peer-group member. */
5253 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5255 if (member
->allowas_in
[afi
][safi
] != 0
5256 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5257 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5258 SET_FLAG(member
->af_flags
[afi
][safi
],
5259 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5260 member
->allowas_in
[afi
][safi
] = 0;
5261 peer_on_policy_change(peer
, afi
, safi
, 0);
5264 if (member
->allowas_in
[afi
][safi
] != allow_num
5265 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5266 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5267 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5268 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5269 member
->allowas_in
[afi
][safi
] = allow_num
;
5270 peer_on_policy_change(peer
, afi
, safi
, 0);
5278 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5280 struct peer
*member
;
5281 struct listnode
*node
, *nnode
;
5283 /* Skip peer if flag is already disabled. */
5284 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5287 /* Inherit configuration from peer-group if peer is member. */
5288 if (peer_group_active(peer
)) {
5289 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5290 peer_af_flag_inherit(peer
, afi
, safi
,
5291 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5292 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5293 peer_on_policy_change(peer
, afi
, safi
, 0);
5298 /* Remove flag and configuration from peer. */
5299 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5300 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5301 peer
->allowas_in
[afi
][safi
] = 0;
5302 peer_on_policy_change(peer
, afi
, safi
, 0);
5304 /* Skip peer-group mechanics if handling a regular peer. */
5305 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5309 * Remove flags and configuration from all peer-group members, unless
5310 * they are explicitely overriding peer-group configuration.
5312 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5313 /* Skip peers with overridden configuration. */
5314 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5315 PEER_FLAG_ALLOWAS_IN
))
5318 /* Skip peers where flag is already disabled. */
5319 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5320 PEER_FLAG_ALLOWAS_IN
))
5323 /* Remove flags and configuration on peer-group member. */
5324 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5325 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5326 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5327 member
->allowas_in
[afi
][safi
] = 0;
5328 peer_on_policy_change(member
, afi
, safi
, 0);
5334 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5337 bool old_no_prepend
, old_replace_as
;
5338 struct bgp
*bgp
= peer
->bgp
;
5339 struct peer
*member
;
5340 struct listnode
*node
, *nnode
;
5342 if (peer_sort(peer
) != BGP_PEER_EBGP
5343 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5344 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5347 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5350 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5352 /* Save previous flag states. */
5354 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5356 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5358 /* Set flag and configuration on peer. */
5359 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5360 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5361 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5363 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5364 && old_replace_as
== replace_as
)
5366 peer
->change_local_as
= as
;
5368 /* Check if handling a regular peer. */
5369 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5370 /* Send notification or reset peer depending on state. */
5371 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5372 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5373 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5374 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5376 bgp_session_reset(peer
);
5378 /* Skip peer-group mechanics for regular peers. */
5383 * Set flag and configuration on all peer-group members, unless they are
5384 * explicitely overriding peer-group configuration.
5386 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5387 /* Skip peers with overridden configuration. */
5388 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5391 /* Skip peers with the same configuration. */
5392 old_no_prepend
= CHECK_FLAG(member
->flags
,
5393 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5394 old_replace_as
= CHECK_FLAG(member
->flags
,
5395 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5396 if (member
->change_local_as
== as
5397 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5398 && old_no_prepend
== no_prepend
5399 && old_replace_as
== replace_as
)
5402 /* Set flag and configuration on peer-group member. */
5403 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5404 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5406 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5408 member
->change_local_as
= as
;
5410 /* Send notification or stop peer depending on state. */
5411 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5412 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5413 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5414 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5416 BGP_EVENT_ADD(member
, BGP_Stop
);
5422 int peer_local_as_unset(struct peer
*peer
)
5424 struct peer
*member
;
5425 struct listnode
*node
, *nnode
;
5427 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5430 /* Inherit configuration from peer-group if peer is member. */
5431 if (peer_group_active(peer
)) {
5432 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5433 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5434 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5435 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5437 /* Otherwise remove flag and configuration from peer. */
5438 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5439 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5440 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5441 peer
->change_local_as
= 0;
5444 /* Check if handling a regular peer. */
5445 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5446 /* Send notification or stop peer depending on state. */
5447 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5448 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5449 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5450 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5452 BGP_EVENT_ADD(peer
, BGP_Stop
);
5454 /* Skip peer-group mechanics for regular peers. */
5459 * Remove flag and configuration from all peer-group members, unless
5460 * they are explicitely overriding peer-group configuration.
5462 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5463 /* Skip peers with overridden configuration. */
5464 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5467 /* Remove flag and configuration on peer-group member. */
5468 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5469 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5470 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5471 member
->change_local_as
= 0;
5473 /* Send notification or stop peer depending on state. */
5474 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5475 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5476 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5477 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5479 bgp_session_reset(member
);
5485 /* Set password for authenticating with the peer. */
5486 int peer_password_set(struct peer
*peer
, const char *password
)
5488 struct peer
*member
;
5489 struct listnode
*node
, *nnode
;
5490 int len
= password
? strlen(password
) : 0;
5491 int ret
= BGP_SUCCESS
;
5493 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5494 return BGP_ERR_INVALID_VALUE
;
5496 /* Set flag and configuration on peer. */
5497 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5498 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5500 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5501 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5503 /* Check if handling a regular peer. */
5504 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5505 /* Send notification or reset peer depending on state. */
5506 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5507 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5508 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5510 bgp_session_reset(peer
);
5513 * Attempt to install password on socket and skip peer-group
5516 if (BGP_PEER_SU_UNSPEC(peer
))
5518 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5519 : BGP_ERR_TCPSIG_FAILED
;
5523 * Set flag and configuration on all peer-group members, unless they are
5524 * explicitely overriding peer-group configuration.
5526 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5527 /* Skip peers with overridden configuration. */
5528 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5531 /* Skip peers with the same password. */
5532 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5535 /* Set flag and configuration on peer-group member. */
5536 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5537 if (member
->password
)
5538 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5539 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5541 /* Send notification or reset peer depending on state. */
5542 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5543 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5544 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5546 bgp_session_reset(member
);
5548 /* Attempt to install password on socket. */
5549 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5550 ret
= BGP_ERR_TCPSIG_FAILED
;
5553 /* Set flag and configuration on all peer-group listen ranges */
5554 struct listnode
*ln
;
5557 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5558 bgp_md5_set_prefix(lr
, password
);
5559 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5560 bgp_md5_set_prefix(lr
, password
);
5565 int peer_password_unset(struct peer
*peer
)
5567 struct peer
*member
;
5568 struct listnode
*node
, *nnode
;
5570 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5573 /* Inherit configuration from peer-group if peer is member. */
5574 if (peer_group_active(peer
)) {
5575 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5576 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5577 MTYPE_PEER_PASSWORD
);
5579 /* Otherwise remove flag and configuration from peer. */
5580 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5581 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5584 /* Check if handling a regular peer. */
5585 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5586 /* Send notification or reset peer depending on state. */
5587 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5588 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5589 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5591 bgp_session_reset(peer
);
5593 /* Attempt to uninstall password on socket. */
5594 if (!BGP_PEER_SU_UNSPEC(peer
))
5595 bgp_md5_unset(peer
);
5597 /* Skip peer-group mechanics for regular peers. */
5602 * Remove flag and configuration from all peer-group members, unless
5603 * they are explicitely overriding peer-group configuration.
5605 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5606 /* Skip peers with overridden configuration. */
5607 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5610 /* Remove flag and configuration on peer-group member. */
5611 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5612 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5614 /* Send notification or reset peer depending on state. */
5615 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5616 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5617 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5619 bgp_session_reset(member
);
5621 /* Attempt to uninstall password on socket. */
5622 if (!BGP_PEER_SU_UNSPEC(member
))
5623 bgp_md5_unset(member
);
5626 /* Set flag and configuration on all peer-group listen ranges */
5627 struct listnode
*ln
;
5630 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5631 bgp_md5_unset_prefix(lr
);
5632 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5633 bgp_md5_unset_prefix(lr
);
5639 /* Set distribute list to the peer. */
5640 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5643 struct peer
*member
;
5644 struct bgp_filter
*filter
;
5645 struct listnode
*node
, *nnode
;
5647 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5648 return BGP_ERR_INVALID_VALUE
;
5650 /* Set configuration on peer. */
5651 filter
= &peer
->filter
[afi
][safi
];
5652 if (filter
->plist
[direct
].name
)
5653 return BGP_ERR_PEER_FILTER_CONFLICT
;
5654 if (filter
->dlist
[direct
].name
)
5655 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5656 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5657 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5659 /* Check if handling a regular peer. */
5660 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5661 /* Set override-flag and process peer route updates. */
5662 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5663 PEER_FT_DISTRIBUTE_LIST
);
5664 peer_on_policy_change(peer
, afi
, safi
,
5665 (direct
== FILTER_OUT
) ? 1 : 0);
5667 /* Skip peer-group mechanics for regular peers. */
5672 * Set configuration on all peer-group members, un less they are
5673 * explicitely overriding peer-group configuration.
5675 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5676 /* Skip peers with overridden configuration. */
5677 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5678 PEER_FT_DISTRIBUTE_LIST
))
5681 /* Set configuration on peer-group member. */
5682 filter
= &member
->filter
[afi
][safi
];
5683 if (filter
->dlist
[direct
].name
)
5684 XFREE(MTYPE_BGP_FILTER_NAME
,
5685 filter
->dlist
[direct
].name
);
5686 filter
->dlist
[direct
].name
=
5687 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5688 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5690 /* Process peer route updates. */
5691 peer_on_policy_change(member
, afi
, safi
,
5692 (direct
== FILTER_OUT
) ? 1 : 0);
5698 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5700 struct peer
*member
;
5701 struct bgp_filter
*filter
;
5702 struct listnode
*node
, *nnode
;
5704 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5705 return BGP_ERR_INVALID_VALUE
;
5707 /* Unset override-flag unconditionally. */
5708 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5709 PEER_FT_DISTRIBUTE_LIST
);
5711 /* Inherit configuration from peer-group if peer is member. */
5712 if (peer_group_active(peer
)) {
5713 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5714 filter
[afi
][safi
].dlist
[direct
].name
,
5715 MTYPE_BGP_FILTER_NAME
);
5716 PEER_ATTR_INHERIT(peer
, peer
->group
,
5717 filter
[afi
][safi
].dlist
[direct
].alist
);
5719 /* Otherwise remove configuration from peer. */
5720 filter
= &peer
->filter
[afi
][safi
];
5721 if (filter
->dlist
[direct
].name
)
5722 XFREE(MTYPE_BGP_FILTER_NAME
,
5723 filter
->dlist
[direct
].name
);
5724 filter
->dlist
[direct
].name
= NULL
;
5725 filter
->dlist
[direct
].alist
= NULL
;
5728 /* Check if handling a regular peer. */
5729 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5730 /* Process peer route updates. */
5731 peer_on_policy_change(peer
, afi
, safi
,
5732 (direct
== FILTER_OUT
) ? 1 : 0);
5734 /* Skip peer-group mechanics for regular peers. */
5739 * Remove configuration on all peer-group members, unless they are
5740 * explicitely overriding peer-group configuration.
5742 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5743 /* Skip peers with overridden configuration. */
5744 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5745 PEER_FT_DISTRIBUTE_LIST
))
5748 /* Remove configuration on peer-group member. */
5749 filter
= &member
->filter
[afi
][safi
];
5750 if (filter
->dlist
[direct
].name
)
5751 XFREE(MTYPE_BGP_FILTER_NAME
,
5752 filter
->dlist
[direct
].name
);
5753 filter
->dlist
[direct
].name
= NULL
;
5754 filter
->dlist
[direct
].alist
= NULL
;
5756 /* Process peer route updates. */
5757 peer_on_policy_change(member
, afi
, safi
,
5758 (direct
== FILTER_OUT
) ? 1 : 0);
5764 /* Update distribute list. */
5765 static void peer_distribute_update(struct access_list
*access
)
5770 struct listnode
*mnode
, *mnnode
;
5771 struct listnode
*node
, *nnode
;
5774 struct peer_group
*group
;
5775 struct bgp_filter
*filter
;
5777 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5779 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5780 access
->name
, 0, 0);
5781 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5782 FOREACH_AFI_SAFI (afi
, safi
) {
5783 filter
= &peer
->filter
[afi
][safi
];
5785 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5787 if (filter
->dlist
[direct
].name
)
5788 filter
->dlist
[direct
]
5789 .alist
= access_list_lookup(
5791 filter
->dlist
[direct
]
5794 filter
->dlist
[direct
].alist
=
5799 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5800 FOREACH_AFI_SAFI (afi
, safi
) {
5801 filter
= &group
->conf
->filter
[afi
][safi
];
5803 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5805 if (filter
->dlist
[direct
].name
)
5806 filter
->dlist
[direct
]
5807 .alist
= access_list_lookup(
5809 filter
->dlist
[direct
]
5812 filter
->dlist
[direct
].alist
=
5818 vnc_prefix_list_update(bgp
);
5823 /* Set prefix list to the peer. */
5824 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5827 struct peer
*member
;
5828 struct bgp_filter
*filter
;
5829 struct listnode
*node
, *nnode
;
5831 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5832 return BGP_ERR_INVALID_VALUE
;
5834 /* Set configuration on peer. */
5835 filter
= &peer
->filter
[afi
][safi
];
5836 if (filter
->dlist
[direct
].name
)
5837 return BGP_ERR_PEER_FILTER_CONFLICT
;
5838 if (filter
->plist
[direct
].name
)
5839 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5840 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5841 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5843 /* Check if handling a regular peer. */
5844 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5845 /* Set override-flag and process peer route updates. */
5846 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5847 PEER_FT_PREFIX_LIST
);
5848 peer_on_policy_change(peer
, afi
, safi
,
5849 (direct
== FILTER_OUT
) ? 1 : 0);
5851 /* Skip peer-group mechanics for regular peers. */
5856 * Set configuration on all peer-group members, unless they are
5857 * explicitely overriding peer-group configuration.
5859 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5860 /* Skip peers with overridden configuration. */
5861 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5862 PEER_FT_PREFIX_LIST
))
5865 /* Set configuration on peer-group member. */
5866 filter
= &member
->filter
[afi
][safi
];
5867 if (filter
->plist
[direct
].name
)
5868 XFREE(MTYPE_BGP_FILTER_NAME
,
5869 filter
->plist
[direct
].name
);
5870 filter
->plist
[direct
].name
=
5871 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5872 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5874 /* Process peer route updates. */
5875 peer_on_policy_change(member
, afi
, safi
,
5876 (direct
== FILTER_OUT
) ? 1 : 0);
5882 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5885 struct peer
*member
;
5886 struct bgp_filter
*filter
;
5887 struct listnode
*node
, *nnode
;
5889 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5890 return BGP_ERR_INVALID_VALUE
;
5892 /* Unset override-flag unconditionally. */
5893 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5894 PEER_FT_PREFIX_LIST
);
5896 /* Inherit configuration from peer-group if peer is member. */
5897 if (peer_group_active(peer
)) {
5898 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5899 filter
[afi
][safi
].plist
[direct
].name
,
5900 MTYPE_BGP_FILTER_NAME
);
5901 PEER_ATTR_INHERIT(peer
, peer
->group
,
5902 filter
[afi
][safi
].plist
[direct
].plist
);
5904 /* Otherwise remove configuration from peer. */
5905 filter
= &peer
->filter
[afi
][safi
];
5906 if (filter
->plist
[direct
].name
)
5907 XFREE(MTYPE_BGP_FILTER_NAME
,
5908 filter
->plist
[direct
].name
);
5909 filter
->plist
[direct
].name
= NULL
;
5910 filter
->plist
[direct
].plist
= NULL
;
5913 /* Check if handling a regular peer. */
5914 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5915 /* Process peer route updates. */
5916 peer_on_policy_change(peer
, afi
, safi
,
5917 (direct
== FILTER_OUT
) ? 1 : 0);
5919 /* Skip peer-group mechanics for regular peers. */
5924 * Remove configuration on all peer-group members, unless they are
5925 * explicitely overriding peer-group configuration.
5927 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5928 /* Skip peers with overridden configuration. */
5929 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5930 PEER_FT_PREFIX_LIST
))
5933 /* Remove configuration on peer-group member. */
5934 filter
= &member
->filter
[afi
][safi
];
5935 if (filter
->plist
[direct
].name
)
5936 XFREE(MTYPE_BGP_FILTER_NAME
,
5937 filter
->plist
[direct
].name
);
5938 filter
->plist
[direct
].name
= NULL
;
5939 filter
->plist
[direct
].plist
= NULL
;
5941 /* Process peer route updates. */
5942 peer_on_policy_change(member
, afi
, safi
,
5943 (direct
== FILTER_OUT
) ? 1 : 0);
5949 /* Update prefix-list list. */
5950 static void peer_prefix_list_update(struct prefix_list
*plist
)
5952 struct listnode
*mnode
, *mnnode
;
5953 struct listnode
*node
, *nnode
;
5956 struct peer_group
*group
;
5957 struct bgp_filter
*filter
;
5962 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5965 * Update the prefix-list on update groups.
5967 update_group_policy_update(
5968 bgp
, BGP_POLICY_PREFIX_LIST
,
5969 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5971 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5972 FOREACH_AFI_SAFI (afi
, safi
) {
5973 filter
= &peer
->filter
[afi
][safi
];
5975 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5977 if (filter
->plist
[direct
].name
)
5978 filter
->plist
[direct
]
5979 .plist
= prefix_list_lookup(
5981 filter
->plist
[direct
]
5984 filter
->plist
[direct
].plist
=
5989 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5990 FOREACH_AFI_SAFI (afi
, safi
) {
5991 filter
= &group
->conf
->filter
[afi
][safi
];
5993 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5995 if (filter
->plist
[direct
].name
)
5996 filter
->plist
[direct
]
5997 .plist
= prefix_list_lookup(
5999 filter
->plist
[direct
]
6002 filter
->plist
[direct
].plist
=
6010 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6013 struct peer
*member
;
6014 struct bgp_filter
*filter
;
6015 struct listnode
*node
, *nnode
;
6017 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6018 return BGP_ERR_INVALID_VALUE
;
6020 /* Set configuration on peer. */
6021 filter
= &peer
->filter
[afi
][safi
];
6022 if (filter
->aslist
[direct
].name
)
6023 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
6024 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6025 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6027 /* Check if handling a regular peer. */
6028 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6029 /* Set override-flag and process peer route updates. */
6030 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6031 PEER_FT_FILTER_LIST
);
6032 peer_on_policy_change(peer
, afi
, safi
,
6033 (direct
== FILTER_OUT
) ? 1 : 0);
6035 /* Skip peer-group mechanics for regular peers. */
6040 * Set configuration on all peer-group members, unless they are
6041 * explicitely overriding peer-group configuration.
6043 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6044 /* Skip peers with overridden configuration. */
6045 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6046 PEER_FT_FILTER_LIST
))
6049 /* Set configuration on peer-group member. */
6050 filter
= &member
->filter
[afi
][safi
];
6051 if (filter
->aslist
[direct
].name
)
6052 XFREE(MTYPE_BGP_FILTER_NAME
,
6053 filter
->aslist
[direct
].name
);
6054 filter
->aslist
[direct
].name
=
6055 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6056 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6058 /* Process peer route updates. */
6059 peer_on_policy_change(member
, afi
, safi
,
6060 (direct
== FILTER_OUT
) ? 1 : 0);
6066 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6068 struct peer
*member
;
6069 struct bgp_filter
*filter
;
6070 struct listnode
*node
, *nnode
;
6072 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6073 return BGP_ERR_INVALID_VALUE
;
6075 /* Unset override-flag unconditionally. */
6076 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6077 PEER_FT_FILTER_LIST
);
6079 /* Inherit configuration from peer-group if peer is member. */
6080 if (peer_group_active(peer
)) {
6081 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6082 filter
[afi
][safi
].aslist
[direct
].name
,
6083 MTYPE_BGP_FILTER_NAME
);
6084 PEER_ATTR_INHERIT(peer
, peer
->group
,
6085 filter
[afi
][safi
].aslist
[direct
].aslist
);
6087 /* Otherwise remove configuration from peer. */
6088 filter
= &peer
->filter
[afi
][safi
];
6089 if (filter
->aslist
[direct
].name
)
6090 XFREE(MTYPE_BGP_FILTER_NAME
,
6091 filter
->aslist
[direct
].name
);
6092 filter
->aslist
[direct
].name
= NULL
;
6093 filter
->aslist
[direct
].aslist
= NULL
;
6096 /* Check if handling a regular peer. */
6097 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6098 /* Process peer route updates. */
6099 peer_on_policy_change(peer
, afi
, safi
,
6100 (direct
== FILTER_OUT
) ? 1 : 0);
6102 /* Skip peer-group mechanics for regular peers. */
6107 * Remove configuration on all peer-group members, unless they are
6108 * explicitely overriding peer-group configuration.
6110 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6111 /* Skip peers with overridden configuration. */
6112 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6113 PEER_FT_FILTER_LIST
))
6116 /* Remove configuration on peer-group member. */
6117 filter
= &member
->filter
[afi
][safi
];
6118 if (filter
->aslist
[direct
].name
)
6119 XFREE(MTYPE_BGP_FILTER_NAME
,
6120 filter
->aslist
[direct
].name
);
6121 filter
->aslist
[direct
].name
= NULL
;
6122 filter
->aslist
[direct
].aslist
= NULL
;
6124 /* Process peer route updates. */
6125 peer_on_policy_change(member
, afi
, safi
,
6126 (direct
== FILTER_OUT
) ? 1 : 0);
6132 static void peer_aslist_update(const char *aslist_name
)
6137 struct listnode
*mnode
, *mnnode
;
6138 struct listnode
*node
, *nnode
;
6141 struct peer_group
*group
;
6142 struct bgp_filter
*filter
;
6144 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6145 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6148 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6149 FOREACH_AFI_SAFI (afi
, safi
) {
6150 filter
= &peer
->filter
[afi
][safi
];
6152 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6154 if (filter
->aslist
[direct
].name
)
6155 filter
->aslist
[direct
]
6156 .aslist
= as_list_lookup(
6157 filter
->aslist
[direct
]
6160 filter
->aslist
[direct
].aslist
=
6165 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6166 FOREACH_AFI_SAFI (afi
, safi
) {
6167 filter
= &group
->conf
->filter
[afi
][safi
];
6169 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6171 if (filter
->aslist
[direct
].name
)
6172 filter
->aslist
[direct
]
6173 .aslist
= as_list_lookup(
6174 filter
->aslist
[direct
]
6177 filter
->aslist
[direct
].aslist
=
6185 static void peer_aslist_add(char *aslist_name
)
6187 peer_aslist_update(aslist_name
);
6188 route_map_notify_dependencies((char *)aslist_name
,
6189 RMAP_EVENT_ASLIST_ADDED
);
6192 static void peer_aslist_del(const char *aslist_name
)
6194 peer_aslist_update(aslist_name
);
6195 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6199 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6200 const char *name
, struct route_map
*route_map
)
6202 struct peer
*member
;
6203 struct bgp_filter
*filter
;
6204 struct listnode
*node
, *nnode
;
6206 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6207 return BGP_ERR_INVALID_VALUE
;
6209 /* Set configuration on peer. */
6210 filter
= &peer
->filter
[afi
][safi
];
6211 if (filter
->map
[direct
].name
) {
6212 /* If the neighbor is configured with the same route-map
6213 * again then, ignore the duplicate configuration.
6215 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6218 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6220 route_map_counter_decrement(filter
->map
[direct
].map
);
6221 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6222 filter
->map
[direct
].map
= route_map
;
6223 route_map_counter_increment(route_map
);
6225 /* Check if handling a regular peer. */
6226 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6227 /* Set override-flag and process peer route updates. */
6228 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6230 peer_on_policy_change(peer
, afi
, safi
,
6231 (direct
== RMAP_OUT
) ? 1 : 0);
6233 /* Skip peer-group mechanics for regular peers. */
6238 * Set configuration on all peer-group members, unless they are
6239 * explicitely overriding peer-group configuration.
6241 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6242 /* Skip peers with overridden configuration. */
6243 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6247 /* Set configuration on peer-group member. */
6248 filter
= &member
->filter
[afi
][safi
];
6249 if (filter
->map
[direct
].name
)
6250 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6251 route_map_counter_decrement(filter
->map
[direct
].map
);
6252 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6253 filter
->map
[direct
].map
= route_map
;
6254 route_map_counter_increment(route_map
);
6256 /* Process peer route updates. */
6257 peer_on_policy_change(member
, afi
, safi
,
6258 (direct
== RMAP_OUT
) ? 1 : 0);
6263 /* Unset route-map from the peer. */
6264 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6266 struct peer
*member
;
6267 struct bgp_filter
*filter
;
6268 struct listnode
*node
, *nnode
;
6270 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6271 return BGP_ERR_INVALID_VALUE
;
6273 /* Unset override-flag unconditionally. */
6274 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6276 /* Inherit configuration from peer-group if peer is member. */
6277 if (peer_group_active(peer
)) {
6278 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6279 filter
[afi
][safi
].map
[direct
].name
,
6280 MTYPE_BGP_FILTER_NAME
);
6281 PEER_ATTR_INHERIT(peer
, peer
->group
,
6282 filter
[afi
][safi
].map
[direct
].map
);
6284 /* Otherwise remove configuration from peer. */
6285 filter
= &peer
->filter
[afi
][safi
];
6286 if (filter
->map
[direct
].name
)
6287 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6288 route_map_counter_decrement(filter
->map
[direct
].map
);
6289 filter
->map
[direct
].name
= NULL
;
6290 filter
->map
[direct
].map
= NULL
;
6293 /* Check if handling a regular peer. */
6294 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6295 /* Process peer route updates. */
6296 peer_on_policy_change(peer
, afi
, safi
,
6297 (direct
== RMAP_OUT
) ? 1 : 0);
6299 /* Skip peer-group mechanics for regular peers. */
6304 * Remove configuration on all peer-group members, unless they are
6305 * explicitely overriding peer-group configuration.
6307 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6308 /* Skip peers with overridden configuration. */
6309 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6313 /* Remove configuration on peer-group member. */
6314 filter
= &member
->filter
[afi
][safi
];
6315 if (filter
->map
[direct
].name
)
6316 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6317 route_map_counter_decrement(filter
->map
[direct
].map
);
6318 filter
->map
[direct
].name
= NULL
;
6319 filter
->map
[direct
].map
= NULL
;
6321 /* Process peer route updates. */
6322 peer_on_policy_change(member
, afi
, safi
,
6323 (direct
== RMAP_OUT
) ? 1 : 0);
6329 /* Set unsuppress-map to the peer. */
6330 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6331 const char *name
, struct route_map
*route_map
)
6333 struct peer
*member
;
6334 struct bgp_filter
*filter
;
6335 struct listnode
*node
, *nnode
;
6337 /* Set configuration on peer. */
6338 filter
= &peer
->filter
[afi
][safi
];
6339 if (filter
->usmap
.name
)
6340 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6341 route_map_counter_decrement(filter
->usmap
.map
);
6342 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6343 filter
->usmap
.map
= route_map
;
6344 route_map_counter_increment(route_map
);
6346 /* Check if handling a regular peer. */
6347 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6348 /* Set override-flag and process peer route updates. */
6349 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6350 PEER_FT_UNSUPPRESS_MAP
);
6351 peer_on_policy_change(peer
, afi
, safi
, 1);
6353 /* Skip peer-group mechanics for regular peers. */
6358 * Set configuration on all peer-group members, unless they are
6359 * explicitely overriding peer-group configuration.
6361 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6362 /* Skip peers with overridden configuration. */
6363 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6364 PEER_FT_UNSUPPRESS_MAP
))
6367 /* Set configuration on peer-group member. */
6368 filter
= &member
->filter
[afi
][safi
];
6369 if (filter
->usmap
.name
)
6370 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6371 route_map_counter_decrement(filter
->usmap
.map
);
6372 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6373 filter
->usmap
.map
= route_map
;
6374 route_map_counter_increment(route_map
);
6376 /* Process peer route updates. */
6377 peer_on_policy_change(member
, afi
, safi
, 1);
6383 /* Unset route-map from the peer. */
6384 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6386 struct peer
*member
;
6387 struct bgp_filter
*filter
;
6388 struct listnode
*node
, *nnode
;
6390 /* Unset override-flag unconditionally. */
6391 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6393 /* Inherit configuration from peer-group if peer is member. */
6394 if (peer_group_active(peer
)) {
6395 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6396 filter
[afi
][safi
].usmap
.name
,
6397 MTYPE_BGP_FILTER_NAME
);
6398 PEER_ATTR_INHERIT(peer
, peer
->group
,
6399 filter
[afi
][safi
].usmap
.map
);
6401 /* Otherwise remove configuration from peer. */
6402 filter
= &peer
->filter
[afi
][safi
];
6403 if (filter
->usmap
.name
)
6404 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6405 route_map_counter_decrement(filter
->usmap
.map
);
6406 filter
->usmap
.name
= NULL
;
6407 filter
->usmap
.map
= NULL
;
6410 /* Check if handling a regular peer. */
6411 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6412 /* Process peer route updates. */
6413 peer_on_policy_change(peer
, afi
, safi
, 1);
6415 /* Skip peer-group mechanics for regular peers. */
6420 * Remove configuration on all peer-group members, unless they are
6421 * explicitely overriding peer-group configuration.
6423 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6424 /* Skip peers with overridden configuration. */
6425 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6426 PEER_FT_UNSUPPRESS_MAP
))
6429 /* Remove configuration on peer-group member. */
6430 filter
= &member
->filter
[afi
][safi
];
6431 if (filter
->usmap
.name
)
6432 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6433 route_map_counter_decrement(filter
->usmap
.map
);
6434 filter
->usmap
.name
= NULL
;
6435 filter
->usmap
.map
= NULL
;
6437 /* Process peer route updates. */
6438 peer_on_policy_change(member
, afi
, safi
, 1);
6444 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6445 uint32_t max
, uint8_t threshold
, int warning
,
6448 struct peer
*member
;
6449 struct listnode
*node
, *nnode
;
6451 /* Set flags and configuration on peer. */
6452 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6454 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6456 peer_af_flag_unset(peer
, afi
, safi
,
6457 PEER_FLAG_MAX_PREFIX_WARNING
);
6459 peer
->pmax
[afi
][safi
] = max
;
6460 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6461 peer
->pmax_restart
[afi
][safi
] = restart
;
6463 /* Check if handling a regular peer. */
6464 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6465 /* Re-check if peer violates maximum-prefix. */
6466 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6467 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6469 /* Skip peer-group mechanics for regular peers. */
6474 * Set flags and configuration on all peer-group members, unless they
6475 * are explicitely overriding peer-group configuration.
6477 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6478 /* Skip peers with overridden configuration. */
6479 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6480 PEER_FLAG_MAX_PREFIX
))
6483 /* Set flag and configuration on peer-group member. */
6484 member
->pmax
[afi
][safi
] = max
;
6485 member
->pmax_threshold
[afi
][safi
] = threshold
;
6486 member
->pmax_restart
[afi
][safi
] = restart
;
6488 SET_FLAG(member
->af_flags
[afi
][safi
],
6489 PEER_FLAG_MAX_PREFIX_WARNING
);
6491 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6492 PEER_FLAG_MAX_PREFIX_WARNING
);
6494 /* Re-check if peer violates maximum-prefix. */
6495 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6496 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6502 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6504 /* Inherit configuration from peer-group if peer is member. */
6505 if (peer_group_active(peer
)) {
6506 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6507 peer_af_flag_inherit(peer
, afi
, safi
,
6508 PEER_FLAG_MAX_PREFIX_WARNING
);
6509 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6510 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6511 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6516 /* Remove flags and configuration from peer. */
6517 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6518 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6519 peer
->pmax
[afi
][safi
] = 0;
6520 peer
->pmax_threshold
[afi
][safi
] = 0;
6521 peer
->pmax_restart
[afi
][safi
] = 0;
6524 * Remove flags and configuration from all peer-group members, unless
6525 * they are explicitely overriding peer-group configuration.
6527 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6528 struct peer
*member
;
6529 struct listnode
*node
;
6531 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6532 /* Skip peers with overridden configuration. */
6533 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6534 PEER_FLAG_MAX_PREFIX
))
6537 /* Remove flag and configuration on peer-group member.
6539 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6540 PEER_FLAG_MAX_PREFIX
);
6541 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6542 PEER_FLAG_MAX_PREFIX_WARNING
);
6543 member
->pmax
[afi
][safi
] = 0;
6544 member
->pmax_threshold
[afi
][safi
] = 0;
6545 member
->pmax_restart
[afi
][safi
] = 0;
6552 int is_ebgp_multihop_configured(struct peer
*peer
)
6554 struct peer_group
*group
;
6555 struct listnode
*node
, *nnode
;
6558 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6559 group
= peer
->group
;
6560 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6561 && (group
->conf
->ttl
!= BGP_DEFAULT_TTL
))
6564 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6565 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6566 && (peer1
->ttl
!= BGP_DEFAULT_TTL
))
6570 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6571 && (peer
->ttl
!= BGP_DEFAULT_TTL
))
6577 /* Set # of hops between us and BGP peer. */
6578 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6580 struct peer_group
*group
;
6581 struct listnode
*node
, *nnode
;
6584 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6585 gtsm_hops
, peer
->host
);
6587 /* We cannot configure ttl-security hops when ebgp-multihop is already
6588 set. For non peer-groups, the check is simple. For peer-groups,
6590 slightly messy, because we need to check both the peer-group
6592 and all peer-group members for any trace of ebgp-multihop
6594 before actually applying the ttl-security rules. Cisco really made a
6595 mess of this configuration parameter, and OpenBGPD got it right.
6598 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6599 if (is_ebgp_multihop_configured(peer
))
6600 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6602 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6603 peer
->gtsm_hops
= gtsm_hops
;
6605 /* Calling ebgp multihop also resets the session.
6606 * On restart, NHT will get setup correctly as will the
6607 * min & max ttls on the socket. The return value is
6610 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6615 group
= peer
->group
;
6616 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6618 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6620 /* Calling ebgp multihop also resets the
6622 * On restart, NHT will get setup correctly as
6624 * min & max ttls on the socket. The return
6628 peer_ebgp_multihop_set(peer
, MAXTTL
);
6632 /* Post the first gtsm setup or if its ibgp, maxttl setting
6634 * necessary, just set the minttl.
6636 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6637 peer
->gtsm_hops
= gtsm_hops
;
6640 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6641 MAXTTL
+ 1 - gtsm_hops
);
6642 if ((peer
->status
< Established
) && peer
->doppelganger
6643 && (peer
->doppelganger
->fd
>= 0))
6644 sockopt_minttl(peer
->su
.sa
.sa_family
,
6645 peer
->doppelganger
->fd
,
6646 MAXTTL
+ 1 - gtsm_hops
);
6648 group
= peer
->group
;
6649 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6651 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6653 /* Change setting of existing peer
6654 * established then change value (may break
6656 * not established yet (teardown session and
6658 * no session then do nothing (will get
6659 * handled by next connection)
6661 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6663 peer
->su
.sa
.sa_family
, peer
->fd
,
6664 MAXTTL
+ 1 - peer
->gtsm_hops
);
6665 if ((peer
->status
< Established
)
6666 && peer
->doppelganger
6667 && (peer
->doppelganger
->fd
>= 0))
6668 sockopt_minttl(peer
->su
.sa
.sa_family
,
6669 peer
->doppelganger
->fd
,
6670 MAXTTL
+ 1 - gtsm_hops
);
6678 int peer_ttl_security_hops_unset(struct peer
*peer
)
6680 struct peer_group
*group
;
6681 struct listnode
*node
, *nnode
;
6684 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6687 /* if a peer-group member, then reset to peer-group default rather than
6689 if (peer_group_active(peer
))
6690 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6692 peer
->gtsm_hops
= 0;
6694 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6695 /* Invoking ebgp_multihop_set will set the TTL back to the
6697 * value as well as restting the NHT and such. The session is
6700 if (peer
->sort
== BGP_PEER_EBGP
)
6701 ret
= peer_ebgp_multihop_unset(peer
);
6704 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6707 if ((peer
->status
< Established
) && peer
->doppelganger
6708 && (peer
->doppelganger
->fd
>= 0))
6709 sockopt_minttl(peer
->su
.sa
.sa_family
,
6710 peer
->doppelganger
->fd
, 0);
6713 group
= peer
->group
;
6714 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6715 peer
->gtsm_hops
= 0;
6716 if (peer
->sort
== BGP_PEER_EBGP
)
6717 ret
= peer_ebgp_multihop_unset(peer
);
6720 sockopt_minttl(peer
->su
.sa
.sa_family
,
6723 if ((peer
->status
< Established
)
6724 && peer
->doppelganger
6725 && (peer
->doppelganger
->fd
>= 0))
6726 sockopt_minttl(peer
->su
.sa
.sa_family
,
6727 peer
->doppelganger
->fd
,
6737 * If peer clear is invoked in a loop for all peers on the BGP instance,
6738 * it may end up freeing the doppelganger, and if this was the next node
6739 * to the current node, we would end up accessing the freed next node.
6740 * Pass along additional parameter which can be updated if next node
6741 * is freed; only required when walking the peer list on BGP instance.
6743 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6745 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6746 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6747 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6748 if (peer
->t_pmax_restart
) {
6749 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6750 if (bgp_debug_neighbor_events(peer
))
6752 "%s Maximum-prefix restart timer canceled",
6755 BGP_EVENT_ADD(peer
, BGP_Start
);
6759 peer
->v_start
= BGP_INIT_START_TIMER
;
6760 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6761 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6762 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6764 bgp_session_reset_safe(peer
, nnode
);
6769 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6770 enum bgp_clear_type stype
)
6772 struct peer_af
*paf
;
6774 if (peer
->status
!= Established
)
6777 if (!peer
->afc
[afi
][safi
])
6778 return BGP_ERR_AF_UNCONFIGURED
;
6780 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6782 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6783 /* Clear the "neighbor x.x.x.x default-originate" flag */
6784 paf
= peer_af_find(peer
, afi
, safi
);
6785 if (paf
&& paf
->subgroup
6786 && CHECK_FLAG(paf
->subgroup
->sflags
,
6787 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6788 UNSET_FLAG(paf
->subgroup
->sflags
,
6789 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6791 bgp_announce_route(peer
, afi
, safi
);
6794 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6795 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6796 PEER_CAP_ORF_PREFIX_SM_ADV
)
6797 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6798 PEER_CAP_ORF_PREFIX_RM_RCV
)
6799 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6800 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6801 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6802 uint8_t prefix_type
;
6804 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6805 PEER_CAP_ORF_PREFIX_RM_RCV
))
6806 prefix_type
= ORF_TYPE_PREFIX
;
6808 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6810 if (filter
->plist
[FILTER_IN
].plist
) {
6811 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6812 PEER_STATUS_ORF_PREFIX_SEND
))
6813 bgp_route_refresh_send(
6814 peer
, afi
, safi
, prefix_type
,
6816 bgp_route_refresh_send(peer
, afi
, safi
,
6818 REFRESH_IMMEDIATE
, 0);
6820 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6821 PEER_STATUS_ORF_PREFIX_SEND
))
6822 bgp_route_refresh_send(
6823 peer
, afi
, safi
, prefix_type
,
6824 REFRESH_IMMEDIATE
, 1);
6826 bgp_route_refresh_send(peer
, afi
, safi
,
6833 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6834 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6835 /* If neighbor has soft reconfiguration inbound flag.
6836 Use Adj-RIB-In database. */
6837 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6838 PEER_FLAG_SOFT_RECONFIG
))
6839 bgp_soft_reconfig_in(peer
, afi
, safi
);
6841 /* If neighbor has route refresh capability, send route
6843 message to the peer. */
6844 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6845 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6846 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6849 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6855 /* Display peer uptime.*/
6856 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6859 time_t uptime1
, epoch_tbuf
;
6862 /* If there is no connection has been done before print `never'. */
6865 json_object_string_add(json
, "peerUptime", "never");
6866 json_object_int_add(json
, "peerUptimeMsec", 0);
6868 snprintf(buf
, len
, "never");
6872 /* Get current time. */
6873 uptime1
= bgp_clock();
6875 tm
= gmtime(&uptime1
);
6877 if (uptime1
< ONE_DAY_SECOND
)
6878 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6880 else if (uptime1
< ONE_WEEK_SECOND
)
6881 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6883 else if (uptime1
< ONE_YEAR_SECOND
)
6884 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6885 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6887 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6889 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6892 epoch_tbuf
= time(NULL
) - uptime1
;
6893 json_object_string_add(json
, "peerUptime", buf
);
6894 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6895 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6902 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6903 afi_t afi
, safi_t safi
)
6905 struct bgp_filter
*filter
;
6909 filter
= &peer
->filter
[afi
][safi
];
6911 /* distribute-list. */
6912 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6914 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6915 filter
->dlist
[FILTER_IN
].name
);
6917 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6919 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6920 filter
->dlist
[FILTER_OUT
].name
);
6923 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6925 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6926 filter
->plist
[FILTER_IN
].name
);
6928 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6930 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6931 filter
->plist
[FILTER_OUT
].name
);
6934 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6935 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6936 filter
->map
[RMAP_IN
].name
);
6938 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6940 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6941 filter
->map
[RMAP_OUT
].name
);
6943 /* unsuppress-map */
6944 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6945 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6946 filter
->usmap
.name
);
6949 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6951 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6952 filter
->aslist
[FILTER_IN
].name
);
6954 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6956 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6957 filter
->aslist
[FILTER_OUT
].name
);
6960 /* BGP peer configuration display function. */
6961 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6964 struct peer
*g_peer
= NULL
;
6965 char buf
[SU_ADDRSTRLEN
];
6967 int if_pg_printed
= false;
6968 int if_ras_printed
= false;
6970 /* Skip dynamic neighbors. */
6971 if (peer_dynamic_neighbor(peer
))
6975 addr
= peer
->conf_if
;
6979 /************************************
6980 ****** Global to the neighbor ******
6981 ************************************/
6982 if (peer
->conf_if
) {
6983 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6984 vty_out(vty
, " neighbor %s interface v6only", addr
);
6986 vty_out(vty
, " neighbor %s interface", addr
);
6988 if (peer_group_active(peer
)) {
6989 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6990 if_pg_printed
= true;
6991 } else if (peer
->as_type
== AS_SPECIFIED
) {
6992 vty_out(vty
, " remote-as %u", peer
->as
);
6993 if_ras_printed
= true;
6994 } else if (peer
->as_type
== AS_INTERNAL
) {
6995 vty_out(vty
, " remote-as internal");
6996 if_ras_printed
= true;
6997 } else if (peer
->as_type
== AS_EXTERNAL
) {
6998 vty_out(vty
, " remote-as external");
6999 if_ras_printed
= true;
7005 /* remote-as and peer-group */
7006 /* peer is a member of a peer-group */
7007 if (peer_group_active(peer
)) {
7008 g_peer
= peer
->group
->conf
;
7010 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
7011 if (peer
->as_type
== AS_SPECIFIED
) {
7012 vty_out(vty
, " neighbor %s remote-as %u\n",
7014 } else if (peer
->as_type
== AS_INTERNAL
) {
7016 " neighbor %s remote-as internal\n",
7018 } else if (peer
->as_type
== AS_EXTERNAL
) {
7020 " neighbor %s remote-as external\n",
7025 /* For swpX peers we displayed the peer-group
7026 * via 'neighbor swpX interface peer-group PGNAME' */
7028 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
7032 /* peer is NOT a member of a peer-group */
7034 /* peer is a peer-group, declare the peer-group */
7035 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7036 vty_out(vty
, " neighbor %s peer-group\n", addr
);
7039 if (!if_ras_printed
) {
7040 if (peer
->as_type
== AS_SPECIFIED
) {
7041 vty_out(vty
, " neighbor %s remote-as %u\n",
7043 } else if (peer
->as_type
== AS_INTERNAL
) {
7045 " neighbor %s remote-as internal\n",
7047 } else if (peer
->as_type
== AS_EXTERNAL
) {
7049 " neighbor %s remote-as external\n",
7056 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
7057 vty_out(vty
, " neighbor %s local-as %u", addr
,
7058 peer
->change_local_as
);
7059 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
7060 vty_out(vty
, " no-prepend");
7061 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
7062 vty_out(vty
, " replace-as");
7068 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
7072 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
7073 if (peer
->tx_shutdown_message
)
7074 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
7075 peer
->tx_shutdown_message
);
7077 vty_out(vty
, " neighbor %s shutdown\n", addr
);
7081 if (peer
->bfd_info
) {
7082 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
7083 bgp_bfd_peer_config_write(vty
, peer
, addr
);
7088 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
7089 vty_out(vty
, " neighbor %s password %s\n", addr
,
7093 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
7094 if (!peer_group_active(peer
)) {
7095 vty_out(vty
, " neighbor %s solo\n", addr
);
7100 if (peer
->port
!= BGP_PORT_DEFAULT
) {
7101 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
7104 /* Local interface name */
7106 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
7110 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
7111 vty_out(vty
, " neighbor %s passive\n", addr
);
7114 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= BGP_DEFAULT_TTL
7115 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
7116 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
7117 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
7122 /* ttl-security hops */
7123 if (peer
->gtsm_hops
!= 0) {
7124 if (!peer_group_active(peer
)
7125 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
7126 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
7127 addr
, peer
->gtsm_hops
);
7131 /* disable-connected-check */
7132 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
7133 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
7135 /* enforce-first-as */
7136 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
7137 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
7140 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
7141 if (peer
->update_source
)
7142 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7143 sockunion2str(peer
->update_source
, buf
,
7145 else if (peer
->update_if
)
7146 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7150 /* advertisement-interval */
7151 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7152 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7156 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7157 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7158 peer
->keepalive
, peer
->holdtime
);
7160 /* timers connect */
7161 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7162 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7165 /* capability dynamic */
7166 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7167 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7169 /* capability extended-nexthop */
7170 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7171 if (!peer
->conf_if
) {
7172 if (CHECK_FLAG(peer
->flags_invert
,
7173 PEER_FLAG_CAPABILITY_ENHE
))
7175 " no neighbor %s capability extended-nexthop\n",
7179 " neighbor %s capability extended-nexthop\n",
7184 /* dont-capability-negotiation */
7185 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7186 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7188 /* override-capability */
7189 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7190 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7192 /* strict-capability-match */
7193 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7194 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7196 /* Sender side AS path loop detection. */
7197 if (peer
->as_path_loop_detection
)
7198 vty_out(vty
, " neighbor %s sender-as-path-loop-detection\n",
7202 /* BGP peer configuration display function. */
7203 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7204 struct peer
*peer
, afi_t afi
, safi_t safi
)
7206 struct peer
*g_peer
= NULL
;
7208 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7210 /* Skip dynamic neighbors. */
7211 if (peer_dynamic_neighbor(peer
))
7215 addr
= peer
->conf_if
;
7219 /************************************
7220 ****** Per AF to the neighbor ******
7221 ************************************/
7222 if (peer_group_active(peer
)) {
7223 g_peer
= peer
->group
->conf
;
7225 /* If the peer-group is active but peer is not, print a 'no
7227 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7228 vty_out(vty
, " no neighbor %s activate\n", addr
);
7231 /* If the peer-group is not active but peer is, print an
7233 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7234 vty_out(vty
, " neighbor %s activate\n", addr
);
7237 if (peer
->afc
[afi
][safi
]) {
7238 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7239 if (bgp_flag_check(bgp
,
7240 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7241 vty_out(vty
, " neighbor %s activate\n",
7245 vty_out(vty
, " neighbor %s activate\n", addr
);
7247 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7248 if (!bgp_flag_check(bgp
,
7249 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7251 " no neighbor %s activate\n",
7258 /* addpath TX knobs */
7259 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7260 switch (peer
->addpath_type
[afi
][safi
]) {
7261 case BGP_ADDPATH_ALL
:
7262 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7265 case BGP_ADDPATH_BEST_PER_AS
:
7267 " neighbor %s addpath-tx-bestpath-per-AS\n",
7270 case BGP_ADDPATH_MAX
:
7271 case BGP_ADDPATH_NONE
:
7276 /* ORF capability. */
7277 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7278 || peergroup_af_flag_check(peer
, afi
, safi
,
7279 PEER_FLAG_ORF_PREFIX_RM
)) {
7280 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7282 if (peergroup_af_flag_check(peer
, afi
, safi
,
7283 PEER_FLAG_ORF_PREFIX_SM
)
7284 && peergroup_af_flag_check(peer
, afi
, safi
,
7285 PEER_FLAG_ORF_PREFIX_RM
))
7286 vty_out(vty
, " both");
7287 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7288 PEER_FLAG_ORF_PREFIX_SM
))
7289 vty_out(vty
, " send");
7291 vty_out(vty
, " receive");
7295 /* BGP flag dampening. */
7296 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7297 BGP_CONFIG_DAMPENING
))
7298 bgp_config_write_damp(vty
, afi
, safi
);
7300 /* Route reflector client. */
7301 if (peergroup_af_flag_check(peer
, afi
, safi
,
7302 PEER_FLAG_REFLECTOR_CLIENT
)) {
7303 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7306 /* next-hop-self force */
7307 if (peergroup_af_flag_check(peer
, afi
, safi
,
7308 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7309 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7313 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7314 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7317 /* remove-private-AS */
7318 if (peergroup_af_flag_check(peer
, afi
, safi
,
7319 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7320 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7324 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7325 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7326 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7330 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7331 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7332 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7335 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7336 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7337 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7341 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7342 vty_out(vty
, " neighbor %s as-override\n", addr
);
7345 /* send-community print. */
7346 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7347 PEER_FLAG_SEND_COMMUNITY
);
7348 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7349 PEER_FLAG_SEND_EXT_COMMUNITY
);
7350 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7351 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7353 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7354 vty_out(vty
, " no neighbor %s send-community all\n", addr
);
7357 vty_out(vty
, " no neighbor %s send-community\n", addr
);
7360 " no neighbor %s send-community extended\n",
7364 vty_out(vty
, " no neighbor %s send-community large\n",
7368 /* Default information */
7369 if (peergroup_af_flag_check(peer
, afi
, safi
,
7370 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7371 vty_out(vty
, " neighbor %s default-originate", addr
);
7373 if (peer
->default_rmap
[afi
][safi
].name
)
7374 vty_out(vty
, " route-map %s",
7375 peer
->default_rmap
[afi
][safi
].name
);
7380 /* Soft reconfiguration inbound. */
7381 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7382 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7386 /* maximum-prefix. */
7387 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7388 vty_out(vty
, " neighbor %s maximum-prefix %" PRIu32
, addr
,
7389 peer
->pmax
[afi
][safi
]);
7391 if (peer
->pmax_threshold
[afi
][safi
]
7392 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7393 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7394 if (peer_af_flag_check(peer
, afi
, safi
,
7395 PEER_FLAG_MAX_PREFIX_WARNING
))
7396 vty_out(vty
, " warning-only");
7397 if (peer
->pmax_restart
[afi
][safi
])
7398 vty_out(vty
, " restart %u",
7399 peer
->pmax_restart
[afi
][safi
]);
7404 /* Route server client. */
7405 if (peergroup_af_flag_check(peer
, afi
, safi
,
7406 PEER_FLAG_RSERVER_CLIENT
)) {
7407 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7410 /* Nexthop-local unchanged. */
7411 if (peergroup_af_flag_check(peer
, afi
, safi
,
7412 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7413 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7416 /* allowas-in <1-10> */
7417 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7418 if (peer_af_flag_check(peer
, afi
, safi
,
7419 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7420 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7421 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7422 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7424 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7425 peer
->allowas_in
[afi
][safi
]);
7430 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7431 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7432 peer
->weight
[afi
][safi
]);
7435 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7437 /* atribute-unchanged. */
7438 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7439 || (safi
!= SAFI_EVPN
7440 && peer_af_flag_check(peer
, afi
, safi
,
7441 PEER_FLAG_NEXTHOP_UNCHANGED
))
7442 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7444 if (!peer_group_active(peer
)
7445 || peergroup_af_flag_check(peer
, afi
, safi
,
7446 PEER_FLAG_AS_PATH_UNCHANGED
)
7447 || peergroup_af_flag_check(peer
, afi
, safi
,
7448 PEER_FLAG_NEXTHOP_UNCHANGED
)
7449 || peergroup_af_flag_check(peer
, afi
, safi
,
7450 PEER_FLAG_MED_UNCHANGED
)) {
7453 " neighbor %s attribute-unchanged%s%s%s\n",
7455 peer_af_flag_check(peer
, afi
, safi
,
7456 PEER_FLAG_AS_PATH_UNCHANGED
)
7459 peer_af_flag_check(peer
, afi
, safi
,
7460 PEER_FLAG_NEXTHOP_UNCHANGED
)
7463 peer_af_flag_check(peer
, afi
, safi
,
7464 PEER_FLAG_MED_UNCHANGED
)
7471 /* Address family based peer configuration display. */
7472 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7476 struct peer_group
*group
;
7477 struct listnode
*node
, *nnode
;
7480 vty_frame(vty
, " !\n address-family ");
7481 if (afi
== AFI_IP
) {
7482 if (safi
== SAFI_UNICAST
)
7483 vty_frame(vty
, "ipv4 unicast");
7484 else if (safi
== SAFI_LABELED_UNICAST
)
7485 vty_frame(vty
, "ipv4 labeled-unicast");
7486 else if (safi
== SAFI_MULTICAST
)
7487 vty_frame(vty
, "ipv4 multicast");
7488 else if (safi
== SAFI_MPLS_VPN
)
7489 vty_frame(vty
, "ipv4 vpn");
7490 else if (safi
== SAFI_ENCAP
)
7491 vty_frame(vty
, "ipv4 encap");
7492 else if (safi
== SAFI_FLOWSPEC
)
7493 vty_frame(vty
, "ipv4 flowspec");
7494 } else if (afi
== AFI_IP6
) {
7495 if (safi
== SAFI_UNICAST
)
7496 vty_frame(vty
, "ipv6 unicast");
7497 else if (safi
== SAFI_LABELED_UNICAST
)
7498 vty_frame(vty
, "ipv6 labeled-unicast");
7499 else if (safi
== SAFI_MULTICAST
)
7500 vty_frame(vty
, "ipv6 multicast");
7501 else if (safi
== SAFI_MPLS_VPN
)
7502 vty_frame(vty
, "ipv6 vpn");
7503 else if (safi
== SAFI_ENCAP
)
7504 vty_frame(vty
, "ipv6 encap");
7505 else if (safi
== SAFI_FLOWSPEC
)
7506 vty_frame(vty
, "ipv6 flowspec");
7507 } else if (afi
== AFI_L2VPN
) {
7508 if (safi
== SAFI_EVPN
)
7509 vty_frame(vty
, "l2vpn evpn");
7511 vty_frame(vty
, "\n");
7513 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7515 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7517 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7519 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7520 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7522 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7523 /* Skip dynamic neighbors. */
7524 if (peer_dynamic_neighbor(peer
))
7527 /* Do not display doppelganger peers */
7528 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7529 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7532 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7533 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7535 if (safi
== SAFI_EVPN
)
7536 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7538 if (safi
== SAFI_FLOWSPEC
)
7539 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7541 if (safi
== SAFI_UNICAST
) {
7542 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7543 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7544 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7546 vty_out(vty
, " export vpn\n");
7548 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7549 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7551 vty_out(vty
, " import vpn\n");
7553 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7554 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7557 for (ALL_LIST_ELEMENTS_RO(
7558 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7560 vty_out(vty
, " import vrf %s\n", name
);
7564 vty_endframe(vty
, " exit-address-family\n");
7567 int bgp_config_write(struct vty
*vty
)
7570 struct peer_group
*group
;
7572 struct listnode
*node
, *nnode
;
7573 struct listnode
*mnode
, *mnnode
;
7575 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7576 vty_out(vty
, "bgp route-map delay-timer %u\n",
7577 bm
->rmap_update_timer
);
7579 /* BGP configuration. */
7580 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7582 /* skip all auto created vrf as they dont have user config */
7583 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7586 /* Router bgp ASN */
7587 vty_out(vty
, "router bgp %u", bgp
->as
);
7590 vty_out(vty
, " %s %s",
7591 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
)
7592 ? "view" : "vrf", bgp
->name
);
7595 /* BGP fast-external-failover. */
7596 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7597 vty_out(vty
, " no bgp fast-external-failover\n");
7599 /* BGP router ID. */
7600 if (bgp
->router_id_static
.s_addr
!= 0)
7601 vty_out(vty
, " bgp router-id %s\n",
7602 inet_ntoa(bgp
->router_id_static
));
7604 /* BGP log-neighbor-changes. */
7605 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7606 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7607 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7609 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7613 /* BGP configuration. */
7614 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7615 vty_out(vty
, " bgp always-compare-med\n");
7617 /* RFC8212 default eBGP policy. */
7618 if (bgp
->ebgp_requires_policy
7619 == DEFAULT_EBGP_POLICY_ENABLED
)
7620 vty_out(vty
, " bgp ebgp-requires-policy\n");
7622 /* draft-ietf-idr-deprecate-as-set-confed-set */
7623 if (bgp
->reject_as_sets
== BGP_REJECT_AS_SETS_ENABLED
)
7624 vty_out(vty
, " bgp reject-as-sets\n");
7626 /* BGP default ipv4-unicast. */
7627 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7628 vty_out(vty
, " no bgp default ipv4-unicast\n");
7630 /* BGP default local-preference. */
7631 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7632 vty_out(vty
, " bgp default local-preference %u\n",
7633 bgp
->default_local_pref
);
7635 /* BGP default show-hostname */
7636 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7637 != DFLT_BGP_SHOW_HOSTNAME
)
7638 vty_out(vty
, " %sbgp default show-hostname\n",
7639 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7643 /* BGP default subgroup-pkt-queue-max. */
7644 if (bgp
->default_subgroup_pkt_queue_max
7645 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7646 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7647 bgp
->default_subgroup_pkt_queue_max
);
7649 /* BGP client-to-client reflection. */
7650 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7651 vty_out(vty
, " no bgp client-to-client reflection\n");
7653 /* BGP cluster ID. */
7654 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7655 vty_out(vty
, " bgp cluster-id %s\n",
7656 inet_ntoa(bgp
->cluster_id
));
7658 /* Disable ebgp connected nexthop check */
7659 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7661 " bgp disable-ebgp-connected-route-check\n");
7663 /* Confederation identifier*/
7664 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7665 vty_out(vty
, " bgp confederation identifier %u\n",
7668 /* Confederation peer */
7669 if (bgp
->confed_peers_cnt
> 0) {
7672 vty_out(vty
, " bgp confederation peers");
7674 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7675 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7680 /* BGP deterministic-med. */
7681 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7682 != DFLT_BGP_DETERMINISTIC_MED
)
7683 vty_out(vty
, " %sbgp deterministic-med\n",
7684 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7688 /* BGP update-delay. */
7689 bgp_config_write_update_delay(vty
, bgp
);
7691 if (bgp
->v_maxmed_onstartup
7692 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7693 vty_out(vty
, " bgp max-med on-startup %u",
7694 bgp
->v_maxmed_onstartup
);
7695 if (bgp
->maxmed_onstartup_value
7696 != BGP_MAXMED_VALUE_DEFAULT
)
7698 bgp
->maxmed_onstartup_value
);
7701 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7702 vty_out(vty
, " bgp max-med administrative");
7703 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7704 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7709 bgp_config_write_wpkt_quanta(vty
, bgp
);
7711 bgp_config_write_rpkt_quanta(vty
, bgp
);
7714 bgp_config_write_coalesce_time(vty
, bgp
);
7716 /* BGP graceful-restart. */
7717 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7719 " bgp graceful-restart stalepath-time %u\n",
7720 bgp
->stalepath_time
);
7721 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7722 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7724 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7725 vty_out(vty
, " bgp graceful-restart\n");
7727 /* BGP graceful-shutdown */
7728 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7729 vty_out(vty
, " bgp graceful-shutdown\n");
7731 /* BGP graceful-restart Preserve State F bit. */
7732 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7734 " bgp graceful-restart preserve-fw-state\n");
7736 /* BGP bestpath method. */
7737 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7738 vty_out(vty
, " bgp bestpath as-path ignore\n");
7739 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7740 vty_out(vty
, " bgp bestpath as-path confed\n");
7742 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7743 if (bgp_flag_check(bgp
,
7744 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7746 " bgp bestpath as-path multipath-relax as-set\n");
7749 " bgp bestpath as-path multipath-relax\n");
7753 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7755 " bgp route-reflector allow-outbound-policy\n");
7757 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7758 vty_out(vty
, " bgp bestpath compare-routerid\n");
7759 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7760 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7761 vty_out(vty
, " bgp bestpath med");
7762 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7763 vty_out(vty
, " confed");
7764 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7765 vty_out(vty
, " missing-as-worst");
7769 /* BGP network import check. */
7770 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7771 != DFLT_BGP_IMPORT_CHECK
)
7772 vty_out(vty
, " %sbgp network import-check\n",
7773 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7777 /* BGP timers configuration. */
7778 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7779 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7780 vty_out(vty
, " timers bgp %u %u\n",
7781 bgp
->default_keepalive
, bgp
->default_holdtime
);
7784 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7785 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7788 /* Normal neighbor configuration. */
7789 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7790 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7791 bgp_config_write_peer_global(vty
, bgp
, peer
);
7794 /* listen range and limit for dynamic BGP neighbors */
7795 bgp_config_write_listen(vty
, bgp
);
7798 * BGP default autoshutdown neighbors
7800 * This must be placed after any peer and peer-group
7801 * configuration, to avoid setting all peers to shutdown after
7802 * a daemon restart, which is undesired behavior. (see #2286)
7804 if (bgp
->autoshutdown
)
7805 vty_out(vty
, " bgp default shutdown\n");
7807 /* IPv4 unicast configuration. */
7808 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7810 /* IPv4 multicast configuration. */
7811 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7813 /* IPv4 labeled-unicast configuration. */
7814 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7816 /* IPv4 VPN configuration. */
7817 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7819 /* ENCAPv4 configuration. */
7820 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7822 /* FLOWSPEC v4 configuration. */
7823 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7825 /* IPv6 unicast configuration. */
7826 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7828 /* IPv6 multicast configuration. */
7829 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7831 /* IPv6 labeled-unicast configuration. */
7832 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7833 SAFI_LABELED_UNICAST
);
7835 /* IPv6 VPN configuration. */
7836 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7838 /* ENCAPv6 configuration. */
7839 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7841 /* FLOWSPEC v6 configuration. */
7842 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7844 /* EVPN configuration. */
7845 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7847 hook_call(bgp_inst_config_write
, bgp
, vty
);
7850 bgp_rfapi_cfg_write(vty
, bgp
);
7853 vty_out(vty
, "!\n");
7858 void bgp_master_init(struct thread_master
*master
, const int buffer_size
)
7862 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7865 bm
->bgp
= list_new();
7866 bm
->listen_sockets
= list_new();
7867 bm
->port
= BGP_PORT_DEFAULT
;
7868 bm
->master
= master
;
7869 bm
->start_time
= bgp_clock();
7870 bm
->t_rmap_update
= NULL
;
7871 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7872 bm
->terminating
= false;
7873 bm
->socket_buffer
= buffer_size
;
7875 bgp_process_queue_init();
7878 /* init the rd id space.
7879 assign 0th index in the bitfield,
7880 so that we start with id 1
7882 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7883 bf_assign_zero_index(bm
->rd_idspace
);
7885 /* mpls label dynamic allocation pool */
7886 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7888 QOBJ_REG(bm
, bgp_master
);
7892 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7893 * instance delete (non-default only) or BGP exit.
7895 static void bgp_if_finish(struct bgp
*bgp
)
7898 struct interface
*ifp
;
7900 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
7902 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7905 FOR_ALL_INTERFACES (vrf
, ifp
) {
7906 struct listnode
*c_node
, *c_nnode
;
7907 struct connected
*c
;
7909 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7910 bgp_connected_delete(bgp
, c
);
7914 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7916 struct vrf
*vrf
= NULL
;
7917 struct listnode
*next
;
7920 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7921 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7923 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7924 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7927 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7931 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
7933 struct listnode
*next
, *next2
;
7934 struct bgp
*bgp
, *bgp2
;
7937 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7939 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
7940 if (bgp2
->as
== bgp
->as
)
7948 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
7949 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
7953 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7954 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7955 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
7956 {.completions
= NULL
},
7959 struct frr_pthread
*bgp_pth_io
;
7960 struct frr_pthread
*bgp_pth_ka
;
7962 static void bgp_pthreads_init(void)
7964 assert(!bgp_pth_io
);
7965 assert(!bgp_pth_ka
);
7967 struct frr_pthread_attr io
= {
7968 .start
= frr_pthread_attr_default
.start
,
7969 .stop
= frr_pthread_attr_default
.stop
,
7971 struct frr_pthread_attr ka
= {
7972 .start
= bgp_keepalives_start
,
7973 .stop
= bgp_keepalives_stop
,
7975 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7976 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7979 void bgp_pthreads_run(void)
7981 frr_pthread_run(bgp_pth_io
, NULL
);
7982 frr_pthread_run(bgp_pth_ka
, NULL
);
7984 /* Wait until threads are ready. */
7985 frr_pthread_wait_running(bgp_pth_io
);
7986 frr_pthread_wait_running(bgp_pth_ka
);
7989 void bgp_pthreads_finish(void)
7991 frr_pthread_stop_all();
7994 void bgp_init(unsigned short instance
)
7997 /* allocates some vital data structures used by peer commands in
8000 /* pre-init pthreads */
8001 bgp_pthreads_init();
8004 bgp_zebra_init(bm
->master
, instance
);
8007 vnc_zebra_init(bm
->master
);
8010 /* BGP VTY commands installation. */
8018 bgp_route_map_init();
8019 bgp_scan_vty_init();
8024 bgp_ethernetvpn_init();
8025 bgp_flowspec_vty_init();
8027 /* Access list initialize. */
8029 access_list_add_hook(peer_distribute_update
);
8030 access_list_delete_hook(peer_distribute_update
);
8032 /* Filter list initialize. */
8034 as_list_add_hook(peer_aslist_add
);
8035 as_list_delete_hook(peer_aslist_del
);
8037 /* Prefix list initialize.*/
8039 prefix_list_add_hook(peer_prefix_list_update
);
8040 prefix_list_delete_hook(peer_prefix_list_update
);
8042 /* Community list initialize. */
8043 bgp_clist
= community_list_init();
8048 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
8051 void bgp_terminate(void)
8055 struct listnode
*node
, *nnode
;
8056 struct listnode
*mnode
, *mnnode
;
8060 /* Close the listener sockets first as this prevents peers from
8062 * to reconnect on receiving the peer unconfig message. In the presence
8063 * of a large number of peers this will ensure that no peer is left with
8064 * a dangling connection
8066 /* reverse bgp_master_init */
8069 if (bm
->listen_sockets
)
8070 list_delete(&bm
->listen_sockets
);
8072 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
8073 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
8074 if (peer
->status
== Established
8075 || peer
->status
== OpenSent
8076 || peer
->status
== OpenConfirm
)
8077 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
8078 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
8080 if (bm
->process_main_queue
)
8081 work_queue_free_and_null(&bm
->process_main_queue
);
8083 if (bm
->t_rmap_update
)
8084 BGP_TIMER_OFF(bm
->t_rmap_update
);
8089 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
8090 const char *ip_str
, bool use_json
)
8096 /* Get peer sockunion. */
8097 ret
= str2sockunion(ip_str
, &su
);
8099 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
8101 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8105 json_object
*json_no
= NULL
;
8106 json_no
= json_object_new_object();
8107 json_object_string_add(
8109 "malformedAddressOrName",
8111 vty_out(vty
, "%s\n",
8112 json_object_to_json_string_ext(
8114 JSON_C_TO_STRING_PRETTY
));
8115 json_object_free(json_no
);
8118 "%% Malformed address or name: %s\n",
8126 /* Peer structure lookup. */
8127 peer
= peer_lookup(bgp
, &su
);
8130 json_object
*json_no
= NULL
;
8131 json_no
= json_object_new_object();
8132 json_object_string_add(json_no
, "warning",
8133 "No such neighbor in this view/vrf");
8134 vty_out(vty
, "%s\n",
8135 json_object_to_json_string_ext(
8136 json_no
, JSON_C_TO_STRING_PRETTY
));
8137 json_object_free(json_no
);
8139 vty_out(vty
, "No such neighbor in this view/vrf\n");