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_group_delete(struct peer_group
*group
)
2569 struct prefix
*prefix
;
2571 struct listnode
*node
, *nnode
;
2576 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2577 other
= peer
->doppelganger
;
2579 if (other
&& other
->status
!= Deleted
) {
2580 other
->group
= NULL
;
2584 list_delete(&group
->peer
);
2586 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2587 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2589 prefix_free(&prefix
);
2591 list_delete(&group
->listen_range
[afi
]);
2594 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2597 bfd_info_free(&(group
->conf
->bfd_info
));
2599 group
->conf
->group
= NULL
;
2600 peer_delete(group
->conf
);
2602 /* Delete from all peer_group list. */
2603 listnode_delete(bgp
->group
, group
);
2605 peer_group_free(group
);
2610 int peer_group_remote_as_delete(struct peer_group
*group
)
2612 struct peer
*peer
, *other
;
2613 struct listnode
*node
, *nnode
;
2615 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2616 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2619 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2620 other
= peer
->doppelganger
;
2624 if (other
&& other
->status
!= Deleted
) {
2625 other
->group
= NULL
;
2629 list_delete_all_node(group
->peer
);
2631 group
->conf
->as
= 0;
2632 group
->conf
->as_type
= AS_UNSPECIFIED
;
2637 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2639 struct prefix
*prefix
;
2640 struct listnode
*node
, *nnode
;
2643 afi
= family2afi(range
->family
);
2645 /* Group needs remote AS configured. */
2646 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2647 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2649 /* Ensure no duplicates. Currently we don't care about overlaps. */
2650 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2651 if (prefix_same(range
, prefix
))
2655 prefix
= prefix_new();
2656 prefix_copy(prefix
, range
);
2657 listnode_add(group
->listen_range
[afi
], prefix
);
2659 /* Update passwords for new ranges */
2660 if (group
->conf
->password
)
2661 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2666 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2668 struct prefix
*prefix
, prefix2
;
2669 struct listnode
*node
, *nnode
;
2672 char buf
[PREFIX2STR_BUFFER
];
2674 afi
= family2afi(range
->family
);
2676 /* Identify the listen range. */
2677 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2678 if (prefix_same(range
, prefix
))
2683 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2685 prefix2str(prefix
, buf
, sizeof(buf
));
2687 /* Dispose off any dynamic neighbors that exist due to this listen range
2689 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2690 if (!peer_dynamic_neighbor(peer
))
2693 sockunion2hostprefix(&peer
->su
, &prefix2
);
2694 if (prefix_match(prefix
, &prefix2
)) {
2695 if (bgp_debug_neighbor_events(peer
))
2697 "Deleting dynamic neighbor %s group %s upon "
2698 "delete of listen range %s",
2699 peer
->host
, group
->name
, buf
);
2704 /* Get rid of the listen range */
2705 listnode_delete(group
->listen_range
[afi
], prefix
);
2707 /* Remove passwords for deleted ranges */
2708 if (group
->conf
->password
)
2709 bgp_md5_unset_prefix(prefix
);
2714 /* Bind specified peer to peer group. */
2715 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2716 struct peer_group
*group
, as_t
*as
)
2718 int first_member
= 0;
2722 /* Lookup the peer. */
2724 peer
= peer_lookup(bgp
, su
);
2726 /* The peer exist, bind it to the peer-group */
2728 /* When the peer already belongs to a peer-group, check the
2730 if (peer_group_active(peer
)) {
2732 /* The peer is already bound to the peer-group,
2735 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2738 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2741 /* The peer has not specified a remote-as, inherit it from the
2743 if (peer
->as_type
== AS_UNSPECIFIED
) {
2744 peer
->as_type
= group
->conf
->as_type
;
2745 peer
->as
= group
->conf
->as
;
2746 peer
->sort
= group
->conf
->sort
;
2749 if (!group
->conf
->as
&& peer_sort(peer
)) {
2750 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2751 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2754 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2757 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2761 peer_group2peer_config_copy(group
, peer
);
2763 FOREACH_AFI_SAFI (afi
, safi
) {
2764 if (group
->conf
->afc
[afi
][safi
]) {
2765 peer
->afc
[afi
][safi
] = 1;
2767 if (peer_af_find(peer
, afi
, safi
)
2768 || peer_af_create(peer
, afi
, safi
)) {
2769 peer_group2peer_config_copy_af(
2770 group
, peer
, afi
, safi
);
2772 } else if (peer
->afc
[afi
][safi
])
2773 peer_deactivate(peer
, afi
, safi
);
2777 assert(group
&& peer
->group
== group
);
2779 listnode_delete(bgp
->peer
, peer
);
2781 peer
->group
= group
;
2782 listnode_add_sort(bgp
->peer
, peer
);
2784 peer
= peer_lock(peer
); /* group->peer list reference */
2785 listnode_add(group
->peer
, peer
);
2789 /* Advertisement-interval reset */
2790 if (!CHECK_FLAG(group
->conf
->flags
,
2791 PEER_FLAG_ROUTEADV
)) {
2792 group
->conf
->v_routeadv
=
2793 (peer_sort(group
->conf
)
2795 ? BGP_DEFAULT_IBGP_ROUTEADV
2796 : BGP_DEFAULT_EBGP_ROUTEADV
;
2799 /* ebgp-multihop reset */
2800 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2801 group
->conf
->ttl
= MAXTTL
;
2803 /* local-as reset */
2804 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2805 group
->conf
->change_local_as
= 0;
2806 peer_flag_unset(group
->conf
,
2807 PEER_FLAG_LOCAL_AS
);
2808 peer_flag_unset(group
->conf
,
2809 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2810 peer_flag_unset(group
->conf
,
2811 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2815 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2817 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2818 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2819 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2820 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2822 bgp_session_reset(peer
);
2826 /* Create a new peer. */
2828 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2829 && (!group
->conf
->as
)) {
2830 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2833 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2834 group
->conf
->as_type
, 0, 0, group
);
2836 peer
= peer_lock(peer
); /* group->peer list reference */
2837 listnode_add(group
->peer
, peer
);
2839 peer_group2peer_config_copy(group
, peer
);
2841 /* If the peer-group is active for this afi/safi then activate
2843 FOREACH_AFI_SAFI (afi
, safi
) {
2844 if (group
->conf
->afc
[afi
][safi
]) {
2845 peer
->afc
[afi
][safi
] = 1;
2846 peer_af_create(peer
, afi
, safi
);
2847 peer_group2peer_config_copy_af(group
, peer
, afi
,
2849 } else if (peer
->afc
[afi
][safi
])
2850 peer_deactivate(peer
, afi
, safi
);
2853 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2855 /* Set up peer's events and timers. */
2856 if (peer_active(peer
))
2857 bgp_timer_set(peer
);
2863 static int bgp_startup_timer_expire(struct thread
*thread
)
2867 bgp
= THREAD_ARG(thread
);
2868 bgp
->t_startup
= NULL
;
2874 * On shutdown we call the cleanup function which
2875 * does a free of the link list nodes, free up
2876 * the data we are pointing at too.
2878 static void bgp_vrf_string_name_delete(void *data
)
2882 XFREE(MTYPE_TMP
, vname
);
2885 /* BGP instance creation by `router bgp' commands. */
2886 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2887 enum bgp_instance_type inst_type
)
2893 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2896 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2897 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2898 zlog_debug("Creating Default VRF, AS %u", *as
);
2900 zlog_debug("Creating %s %s, AS %u",
2901 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2907 /* Default the EVPN VRF to the default one */
2908 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
2914 bgp
->heuristic_coalesce
= true;
2915 bgp
->inst_type
= inst_type
;
2916 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2918 bgp
->peer_self
= peer_new(bgp
);
2919 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2920 bgp
->peer_self
->host
=
2921 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2922 if (bgp
->peer_self
->hostname
!= NULL
) {
2923 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2924 bgp
->peer_self
->hostname
= NULL
;
2926 if (cmd_hostname_get())
2927 bgp
->peer_self
->hostname
=
2928 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2930 if (bgp
->peer_self
->domainname
!= NULL
) {
2931 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2932 bgp
->peer_self
->domainname
= NULL
;
2934 if (cmd_domainname_get())
2935 bgp
->peer_self
->domainname
=
2936 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2937 bgp
->peer
= list_new();
2938 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2939 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2941 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2943 bgp
->group
= list_new();
2944 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2946 FOREACH_AFI_SAFI (afi
, safi
) {
2947 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2948 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2949 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2951 /* Enable maximum-paths */
2952 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2954 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2958 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2959 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2960 bgp
->default_subgroup_pkt_queue_max
=
2961 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2962 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2963 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2964 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2965 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2966 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2967 bgp
->dynamic_neighbors_count
= 0;
2968 bgp
->ebgp_requires_policy
= DEFAULT_EBGP_POLICY_DISABLED
;
2969 bgp
->reject_as_sets
= BGP_REJECT_AS_SETS_DISABLED
;
2970 #if DFLT_BGP_IMPORT_CHECK
2971 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2973 #if DFLT_BGP_SHOW_HOSTNAME
2974 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2976 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2977 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2979 #if DFLT_BGP_DETERMINISTIC_MED
2980 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2982 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2987 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2988 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2990 assert(bgp
->rfapi_cfg
);
2992 #endif /* ENABLE_BGP_VNC */
2994 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2995 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2996 bgp
->vpn_policy
[afi
].afi
= afi
;
2997 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2998 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
3001 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
3002 bgp
->vpn_policy
[afi
].import_vrf
->del
=
3003 bgp_vrf_string_name_delete
;
3004 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
3005 bgp
->vpn_policy
[afi
].export_vrf
->del
=
3006 bgp_vrf_string_name_delete
;
3009 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
3011 /* TODO - The startup timer needs to be run for the whole of BGP
3013 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3014 bgp
->restart_time
, &bgp
->t_startup
);
3017 /* printable name we can use in debug messages */
3018 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3019 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3029 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3031 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3032 snprintf(bgp
->name_pretty
, len
, "%s %s",
3033 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3039 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3040 memory_order_relaxed
);
3041 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3042 memory_order_relaxed
);
3043 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3047 update_bgp_group_init(bgp
);
3049 /* assign a unique rd id for auto derivation of vrf's RD */
3050 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3052 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3053 sizeof(struct bgp_evpn_info
));
3060 /* Return the "default VRF" instance of BGP. */
3061 struct bgp
*bgp_get_default(void)
3064 struct listnode
*node
, *nnode
;
3066 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3067 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3072 /* Lookup BGP entry. */
3073 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3076 struct listnode
*node
, *nnode
;
3078 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3080 && ((bgp
->name
== NULL
&& name
== NULL
)
3081 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3086 /* Lookup BGP structure by view name. */
3087 struct bgp
*bgp_lookup_by_name(const char *name
)
3090 struct listnode
*node
, *nnode
;
3092 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3093 if ((bgp
->name
== NULL
&& name
== NULL
)
3094 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3099 /* Lookup BGP instance based on VRF id. */
3100 /* Note: Only to be used for incoming messages from Zebra. */
3101 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3105 /* Lookup VRF (in tree) and follow link. */
3106 vrf
= vrf_lookup_by_id(vrf_id
);
3109 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3112 /* Sets the BGP instance where EVPN is enabled */
3113 void bgp_set_evpn(struct bgp
*bgp
)
3115 if (bm
->bgp_evpn
== bgp
)
3118 /* First, release the reference count we hold on the instance */
3120 bgp_unlock(bm
->bgp_evpn
);
3124 /* Increase the reference count on this new VRF */
3126 bgp_lock(bm
->bgp_evpn
);
3129 /* Returns the BGP instance where EVPN is enabled, if any */
3130 struct bgp
*bgp_get_evpn(void)
3132 return bm
->bgp_evpn
;
3135 /* handle socket creation or deletion, if necessary
3136 * this is called for all new BGP instances
3138 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3143 /* Create BGP server socket, if listen mode not disabled */
3144 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3146 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3148 * suppress vrf socket
3150 if (create
== false) {
3151 bgp_close_vrf_socket(bgp
);
3155 return BGP_ERR_INVALID_VALUE
;
3157 * if vrf_id did not change
3159 if (vrf
->vrf_id
== old_vrf_id
)
3161 if (old_vrf_id
!= VRF_UNKNOWN
) {
3162 /* look for old socket. close it. */
3163 bgp_close_vrf_socket(bgp
);
3165 /* if backend is not yet identified ( VRF_UNKNOWN) then
3166 * creation will be done later
3168 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3170 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3172 return BGP_ERR_INVALID_VALUE
;
3175 return bgp_check_main_socket(create
, bgp
);
3178 /* Called from VTY commands. */
3179 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3180 enum bgp_instance_type inst_type
)
3183 struct vrf
*vrf
= NULL
;
3185 /* Multiple instance check. */
3187 bgp
= bgp_lookup_by_name(name
);
3189 bgp
= bgp_get_default();
3191 /* Already exists. */
3193 if (bgp
->as
!= *as
) {
3195 return BGP_ERR_INSTANCE_MISMATCH
;
3197 if (bgp
->inst_type
!= inst_type
)
3198 return BGP_ERR_INSTANCE_MISMATCH
;
3203 bgp
= bgp_create(as
, name
, inst_type
);
3204 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3205 bgp
->vrf_id
= vrf_generate_id();
3206 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3207 bgp_address_init(bgp
);
3208 bgp_tip_hash_init(bgp
);
3212 bgp
->t_rmap_def_originate_eval
= NULL
;
3214 /* If Default instance or VRF, link to the VRF structure, if present. */
3215 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3216 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3217 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3219 bgp_vrf_link(bgp
, vrf
);
3221 /* BGP server socket already processed if BGP instance
3222 * already part of the list
3224 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3225 listnode_add(bm
->bgp
, bgp
);
3227 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3228 if (BGP_DEBUG(zebra
, ZEBRA
))
3229 zlog_debug("%s: Registering BGP instance %s to zebra",
3230 __PRETTY_FUNCTION__
, name
);
3231 bgp_zebra_instance_register(bgp
);
3238 * Make BGP instance "up". Applies only to VRFs (non-default) and
3239 * implies the VRF has been learnt from Zebra.
3241 void bgp_instance_up(struct bgp
*bgp
)
3244 struct listnode
*node
, *next
;
3246 /* Register with zebra. */
3247 bgp_zebra_instance_register(bgp
);
3249 /* Kick off any peers that may have been configured. */
3250 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3251 if (!BGP_PEER_START_SUPPRESSED(peer
))
3252 BGP_EVENT_ADD(peer
, BGP_Start
);
3255 /* Process any networks that have been configured. */
3256 bgp_static_add(bgp
);
3260 * Make BGP instance "down". Applies only to VRFs (non-default) and
3261 * implies the VRF has been deleted by Zebra.
3263 void bgp_instance_down(struct bgp
*bgp
)
3266 struct listnode
*node
;
3267 struct listnode
*next
;
3270 if (bgp
->t_rmap_def_originate_eval
) {
3271 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3272 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3276 /* Bring down peers, so corresponding routes are purged. */
3277 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3278 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3279 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3280 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3282 bgp_session_reset(peer
);
3285 /* Purge network and redistributed routes. */
3286 bgp_purge_static_redist_routes(bgp
);
3288 /* Cleanup registered nexthops (flags) */
3289 bgp_cleanup_nexthops(bgp
);
3292 /* Delete BGP instance. */
3293 int bgp_delete(struct bgp
*bgp
)
3296 struct peer_group
*group
;
3297 struct listnode
*node
, *next
;
3304 hook_call(bgp_inst_delete
, bgp
);
3306 THREAD_OFF(bgp
->t_startup
);
3307 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3308 THREAD_OFF(bgp
->t_update_delay
);
3309 THREAD_OFF(bgp
->t_establish_wait
);
3311 /* Set flag indicating bgp instance delete in progress */
3312 bgp_flag_set(bgp
, BGP_FLAG_DELETE_IN_PROGRESS
);
3314 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3315 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3316 zlog_debug("Deleting Default VRF");
3318 zlog_debug("Deleting %s %s",
3319 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3325 /* unmap from RT list */
3326 bgp_evpn_vrf_delete(bgp
);
3328 /* unmap bgp vrf label */
3329 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3330 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3333 if (bgp
->t_rmap_def_originate_eval
) {
3334 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3335 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3339 /* Inform peers we're going down. */
3340 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3341 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3342 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3343 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3346 /* Delete static routes (networks). */
3347 bgp_static_delete(bgp
);
3349 /* Unset redistribution. */
3350 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3351 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3352 if (i
!= ZEBRA_ROUTE_BGP
)
3353 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3355 /* Free peers and peer-groups. */
3356 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3357 peer_group_delete(group
);
3359 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3362 if (bgp
->peer_self
) {
3363 peer_delete(bgp
->peer_self
);
3364 bgp
->peer_self
= NULL
;
3367 update_bgp_group_free(bgp
);
3369 /* TODO - Other memory may need to be freed - e.g., NHT */
3374 bgp_cleanup_routes(bgp
);
3376 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3377 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3380 &bgp
->vpn_policy
[afi
]
3381 .import_redirect_rtlist
);
3382 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3385 /* Deregister from Zebra, if needed */
3386 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3387 if (BGP_DEBUG(zebra
, ZEBRA
))
3388 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3389 __PRETTY_FUNCTION__
, bgp
->name
);
3390 bgp_zebra_instance_deregister(bgp
);
3393 /* Remove visibility via the master list - there may however still be
3394 * routes to be processed still referencing the struct bgp.
3396 listnode_delete(bm
->bgp
, bgp
);
3398 /* Free interfaces in this instance. */
3401 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3402 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3404 bgp_vrf_unlink(bgp
, vrf
);
3406 /* Update EVPN VRF pointer */
3407 if (bm
->bgp_evpn
== bgp
) {
3408 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3411 bgp_set_evpn(bgp_get_default());
3414 thread_master_free_unused(bm
->master
);
3415 bgp_unlock(bgp
); /* initial reference */
3420 void bgp_free(struct bgp
*bgp
)
3424 struct bgp_table
*table
;
3425 struct bgp_node
*rn
;
3426 struct bgp_rmap
*rmap
;
3430 list_delete(&bgp
->group
);
3431 list_delete(&bgp
->peer
);
3433 if (bgp
->peerhash
) {
3434 hash_free(bgp
->peerhash
);
3435 bgp
->peerhash
= NULL
;
3438 FOREACH_AFI_SAFI (afi
, safi
) {
3439 /* Special handling for 2-level routing tables. */
3440 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3441 || safi
== SAFI_EVPN
) {
3442 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3443 rn
= bgp_route_next(rn
)) {
3444 table
= bgp_node_get_bgp_table_info(rn
);
3445 bgp_table_finish(&table
);
3448 if (bgp
->route
[afi
][safi
])
3449 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3450 if (bgp
->aggregate
[afi
][safi
])
3451 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3452 if (bgp
->rib
[afi
][safi
])
3453 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3454 rmap
= &bgp
->table_map
[afi
][safi
];
3455 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3458 bgp_scan_finish(bgp
);
3459 bgp_address_destroy(bgp
);
3460 bgp_tip_hash_destroy(bgp
);
3462 /* release the auto RD id */
3463 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3465 bgp_evpn_cleanup(bgp
);
3466 bgp_pbr_cleanup(bgp
);
3467 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3469 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3470 vpn_policy_direction_t dir
;
3472 if (bgp
->vpn_policy
[afi
].import_vrf
)
3473 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3474 if (bgp
->vpn_policy
[afi
].export_vrf
)
3475 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3477 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3478 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3479 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3480 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3481 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3482 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3485 XFREE(MTYPE_BGP
, bgp
->name
);
3486 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3488 XFREE(MTYPE_BGP
, bgp
);
3491 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3494 struct listnode
*node
, *nnode
;
3500 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3501 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3502 && !CHECK_FLAG(peer
->sflags
,
3503 PEER_STATUS_ACCEPT_PEER
))
3505 } else if (bm
->bgp
!= NULL
) {
3506 struct listnode
*bgpnode
, *nbgpnode
;
3508 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3509 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3511 && !strcmp(peer
->conf_if
, conf_if
)
3512 && !CHECK_FLAG(peer
->sflags
,
3513 PEER_STATUS_ACCEPT_PEER
))
3519 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3522 struct listnode
*node
, *nnode
;
3528 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3529 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3530 && !CHECK_FLAG(peer
->sflags
,
3531 PEER_STATUS_ACCEPT_PEER
))
3533 } else if (bm
->bgp
!= NULL
) {
3534 struct listnode
*bgpnode
, *nbgpnode
;
3536 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3537 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3539 && !strcmp(peer
->hostname
, hostname
)
3540 && !CHECK_FLAG(peer
->sflags
,
3541 PEER_STATUS_ACCEPT_PEER
))
3547 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3549 struct peer
*peer
= NULL
;
3550 struct peer tmp_peer
;
3552 memset(&tmp_peer
, 0, sizeof(struct peer
));
3555 * We do not want to find the doppelganger peer so search for the peer
3557 * the hash that has PEER_FLAG_CONFIG_NODE
3559 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3564 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3565 } else if (bm
->bgp
!= NULL
) {
3566 struct listnode
*bgpnode
, *nbgpnode
;
3568 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3569 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3578 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3579 union sockunion
*su
,
3580 struct peer_group
*group
)
3586 /* Create peer first; we've already checked group config is valid. */
3587 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3588 group
->conf
->as_type
, 0, 0, group
);
3593 peer
= peer_lock(peer
);
3594 listnode_add(group
->peer
, peer
);
3596 peer_group2peer_config_copy(group
, peer
);
3599 * Bind peer for all AFs configured for the group. We don't call
3600 * peer_group_bind as that is sub-optimal and does some stuff we don't
3603 FOREACH_AFI_SAFI (afi
, safi
) {
3604 if (!group
->conf
->afc
[afi
][safi
])
3606 peer
->afc
[afi
][safi
] = 1;
3608 if (!peer_af_find(peer
, afi
, safi
))
3609 peer_af_create(peer
, afi
, safi
);
3611 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3614 /* Mark as dynamic, but also as a "config node" for other things to
3616 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3617 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3623 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3624 struct prefix
*prefix
)
3626 struct listnode
*node
, *nnode
;
3627 struct prefix
*range
;
3630 afi
= family2afi(prefix
->family
);
3632 if (group
->listen_range
[afi
])
3633 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3635 if (prefix_match(range
, prefix
))
3642 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3643 struct prefix
**listen_range
)
3645 struct prefix
*range
= NULL
;
3646 struct peer_group
*group
= NULL
;
3647 struct listnode
*node
, *nnode
;
3649 *listen_range
= NULL
;
3651 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3652 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3655 } else if (bm
->bgp
!= NULL
) {
3656 struct listnode
*bgpnode
, *nbgpnode
;
3658 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3659 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3660 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3666 *listen_range
= range
;
3667 return (group
&& range
) ? group
: NULL
;
3670 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3672 struct peer_group
*group
;
3675 struct prefix prefix
;
3676 struct prefix
*listen_range
;
3678 char buf
[PREFIX2STR_BUFFER
];
3679 char buf1
[PREFIX2STR_BUFFER
];
3681 sockunion2hostprefix(su
, &prefix
);
3683 /* See if incoming connection matches a configured listen range. */
3684 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3695 prefix2str(&prefix
, buf
, sizeof(buf
));
3696 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3698 if (bgp_debug_neighbor_events(NULL
))
3700 "Dynamic Neighbor %s matches group %s listen range %s",
3701 buf
, group
->name
, buf1
);
3703 /* Are we within the listen limit? */
3704 dncount
= gbgp
->dynamic_neighbors_count
;
3706 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3707 if (bgp_debug_neighbor_events(NULL
))
3708 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3709 inet_sutop(su
, buf
),
3710 gbgp
->dynamic_neighbors_limit
);
3714 /* Ensure group is not disabled. */
3715 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3716 if (bgp_debug_neighbor_events(NULL
))
3718 "Dynamic Neighbor %s rejected - group %s disabled",
3723 /* Check that at least one AF is activated for the group. */
3724 if (!peer_group_af_configured(group
)) {
3725 if (bgp_debug_neighbor_events(NULL
))
3727 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3732 /* Create dynamic peer and bind to associated group. */
3733 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3736 gbgp
->dynamic_neighbors_count
= ++dncount
;
3738 if (bgp_debug_neighbor_events(peer
))
3739 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3740 peer
->host
, group
->name
, dncount
);
3745 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3748 if (peer
->group
->bgp
) {
3749 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3751 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3753 if (bgp_debug_neighbor_events(peer
))
3754 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3755 peer
->group
->name
, dncount
);
3758 /* If peer is configured at least one address family return 1. */
3759 int peer_active(struct peer
*peer
)
3761 if (BGP_PEER_SU_UNSPEC(peer
))
3763 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3764 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3765 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3766 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3767 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3768 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3769 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3770 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3771 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3772 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3773 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3778 /* If peer is negotiated at least one address family return 1. */
3779 int peer_active_nego(struct peer
*peer
)
3781 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3782 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3783 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3784 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3785 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3786 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3787 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3788 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3789 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3790 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3791 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3792 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3793 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3798 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3799 enum peer_change_type type
)
3801 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3804 if (peer
->status
!= Established
)
3807 if (type
== peer_change_reset
) {
3808 /* If we're resetting session, we've to delete both peer struct
3810 if ((peer
->doppelganger
)
3811 && (peer
->doppelganger
->status
!= Deleted
)
3812 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3813 PEER_FLAG_CONFIG_NODE
)))
3814 peer_delete(peer
->doppelganger
);
3816 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3817 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3818 } else if (type
== peer_change_reset_in
) {
3819 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3820 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3821 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3823 if ((peer
->doppelganger
)
3824 && (peer
->doppelganger
->status
!= Deleted
)
3825 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3826 PEER_FLAG_CONFIG_NODE
)))
3827 peer_delete(peer
->doppelganger
);
3829 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3830 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3832 } else if (type
== peer_change_reset_out
) {
3833 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3834 bgp_announce_route(peer
, afi
, safi
);
3838 struct peer_flag_action
{
3842 /* This flag can be set for peer-group member. */
3843 uint8_t not_for_member
;
3845 /* Action when the flag is changed. */
3846 enum peer_change_type type
;
3849 static const struct peer_flag_action peer_flag_action_list
[] = {
3850 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3851 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3852 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3853 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3854 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3855 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3856 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3857 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3858 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3859 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3860 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3861 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3862 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3863 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3864 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3865 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3866 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3867 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3870 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3871 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3872 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3873 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3874 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3875 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3876 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3877 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3878 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3879 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3880 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3881 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3882 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3883 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3884 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3885 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3886 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3887 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3888 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3889 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3890 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3891 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3892 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3893 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3894 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3895 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3898 /* Proper action set. */
3899 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3900 int size
, struct peer_flag_action
*action
,
3907 const struct peer_flag_action
*match
= NULL
;
3909 /* Check peer's frag action. */
3910 for (i
= 0; i
< size
; i
++) {
3911 match
= &action_list
[i
];
3913 if (match
->flag
== 0)
3916 if (match
->flag
& flag
) {
3919 if (match
->type
== peer_change_reset_in
)
3921 if (match
->type
== peer_change_reset_out
)
3923 if (match
->type
== peer_change_reset
) {
3927 if (match
->not_for_member
)
3928 action
->not_for_member
= 1;
3932 /* Set peer clear type. */
3933 if (reset_in
&& reset_out
)
3934 action
->type
= peer_change_reset
;
3936 action
->type
= peer_change_reset_in
;
3938 action
->type
= peer_change_reset_out
;
3940 action
->type
= peer_change_none
;
3945 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3947 if (flag
== PEER_FLAG_SHUTDOWN
) {
3948 if (CHECK_FLAG(peer
->flags
, flag
)) {
3949 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3950 peer_nsf_stop(peer
);
3952 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3953 if (peer
->t_pmax_restart
) {
3954 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3955 if (bgp_debug_neighbor_events(peer
))
3957 "%s Maximum-prefix restart timer canceled",
3961 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3962 peer_nsf_stop(peer
);
3964 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3965 char *msg
= peer
->tx_shutdown_message
;
3968 if (!msg
&& peer_group_active(peer
))
3969 msg
= peer
->group
->conf
3970 ->tx_shutdown_message
;
3971 msglen
= msg
? strlen(msg
) : 0;
3976 uint8_t msgbuf
[129];
3979 memcpy(msgbuf
+ 1, msg
, msglen
);
3981 bgp_notify_send_with_data(
3982 peer
, BGP_NOTIFY_CEASE
,
3983 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3984 msgbuf
, msglen
+ 1);
3987 peer
, BGP_NOTIFY_CEASE
,
3988 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3990 bgp_session_reset(peer
);
3992 peer
->v_start
= BGP_INIT_START_TIMER
;
3993 BGP_EVENT_ADD(peer
, BGP_Stop
);
3995 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3996 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3997 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3998 else if (flag
== PEER_FLAG_PASSIVE
)
3999 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
4000 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
4001 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
4003 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4004 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4006 bgp_session_reset(peer
);
4009 /* Change specified peer flag. */
4010 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
4014 bool invert
, member_invert
;
4015 struct peer
*member
;
4016 struct listnode
*node
, *nnode
;
4017 struct peer_flag_action action
;
4019 memset(&action
, 0, sizeof(struct peer_flag_action
));
4020 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
4022 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4023 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4026 /* Abort if no flag action exists. */
4028 return BGP_ERR_INVALID_FLAG
;
4030 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4031 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4032 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4033 return BGP_ERR_PEER_FLAG_CONFLICT
;
4035 /* Handle flag updates where desired state matches current state. */
4036 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4037 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4038 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4042 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4043 COND_FLAG(peer
->flags_override
, flag
, invert
);
4048 /* Inherit from peer-group or set/unset flags accordingly. */
4049 if (peer_group_active(peer
) && set
== invert
)
4050 peer_flag_inherit(peer
, flag
);
4052 COND_FLAG(peer
->flags
, flag
, set
);
4054 /* Check if handling a regular peer. */
4055 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4056 /* Update flag override state accordingly. */
4057 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4059 /* Execute flag action on peer. */
4060 if (action
.type
== peer_change_reset
)
4061 peer_flag_modify_action(peer
, flag
);
4063 /* Skip peer-group mechanics for regular peers. */
4067 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4068 bgp_nht_register_enhe_capability_interfaces(peer
);
4071 * Update peer-group members, unless they are explicitely overriding
4072 * peer-group configuration.
4074 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4075 /* Skip peers with overridden configuration. */
4076 if (CHECK_FLAG(member
->flags_override
, flag
))
4079 /* Check if only member without group is inverted. */
4081 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4083 /* Skip peers with equivalent configuration. */
4084 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4087 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4090 /* Update flag on peer-group member. */
4091 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4093 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4094 bgp_nht_register_enhe_capability_interfaces(member
);
4096 /* Execute flag action on peer-group member. */
4097 if (action
.type
== peer_change_reset
)
4098 peer_flag_modify_action(member
, flag
);
4104 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4106 return peer_flag_modify(peer
, flag
, 1);
4109 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4111 return peer_flag_modify(peer
, flag
, 0);
4114 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4115 uint32_t flag
, bool set
)
4119 bool invert
, member_invert
;
4120 struct peer
*member
;
4121 struct listnode
*node
, *nnode
;
4122 struct peer_flag_action action
;
4124 memset(&action
, 0, sizeof(struct peer_flag_action
));
4125 size
= sizeof peer_af_flag_action_list
4126 / sizeof(struct peer_flag_action
);
4128 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4129 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4132 /* Abort if flag action exists. */
4134 return BGP_ERR_INVALID_FLAG
;
4136 /* Special check for reflector client. */
4137 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4138 && peer_sort(peer
) != BGP_PEER_IBGP
)
4139 return BGP_ERR_NOT_INTERNAL_PEER
;
4141 /* Special check for remove-private-AS. */
4142 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4143 && peer_sort(peer
) == BGP_PEER_IBGP
)
4144 return BGP_ERR_REMOVE_PRIVATE_AS
;
4146 /* as-override is not allowed for IBGP peers */
4147 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4148 return BGP_ERR_AS_OVERRIDE
;
4150 /* Handle flag updates where desired state matches current state. */
4151 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4152 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4153 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4158 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4159 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4166 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4167 * if we are setting/unsetting flags which conflict with this flag
4168 * handle accordingly
4170 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4174 * if we are setting NEXTHOP_SELF, we need to unset the
4175 * NEXTHOP_UNCHANGED flag
4177 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4178 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4179 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4180 PEER_FLAG_NEXTHOP_UNCHANGED
);
4184 * if we are unsetting NEXTHOP_SELF, we need to set the
4185 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4187 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4188 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4189 SET_FLAG(peer
->af_flags
[afi
][safi
],
4190 PEER_FLAG_NEXTHOP_UNCHANGED
);
4194 /* Inherit from peer-group or set/unset flags accordingly. */
4195 if (peer_group_active(peer
) && set
== invert
)
4196 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4198 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4200 /* Execute action when peer is established. */
4201 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4202 && peer
->status
== Established
) {
4203 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4204 bgp_clear_adj_in(peer
, afi
, safi
);
4206 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4207 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4208 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4209 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4210 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4211 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4212 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4213 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4215 peer_change_action(peer
, afi
, safi
, action
.type
);
4219 /* Check if handling a regular peer. */
4220 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4221 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4225 * Update peer-group members, unless they are explicitely
4226 * overriding peer-group configuration.
4228 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4230 /* Skip peers with overridden configuration. */
4231 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4235 /* Check if only member without group is inverted. */
4237 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4241 /* Skip peers with equivalent configuration. */
4242 if (set
!= member_invert
4243 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4246 if (set
== member_invert
4247 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4250 /* Update flag on peer-group member. */
4251 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4252 set
!= member_invert
);
4254 /* Execute flag action on peer-group member. */
4255 if (member
->status
== Established
) {
4256 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4257 bgp_clear_adj_in(member
, afi
, safi
);
4259 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4260 member
->last_reset
=
4261 PEER_DOWN_RR_CLIENT_CHANGE
;
4263 == PEER_FLAG_RSERVER_CLIENT
)
4264 member
->last_reset
=
4265 PEER_DOWN_RS_CLIENT_CHANGE
;
4267 == PEER_FLAG_ORF_PREFIX_SM
)
4268 member
->last_reset
=
4269 PEER_DOWN_CAPABILITY_CHANGE
;
4271 == PEER_FLAG_ORF_PREFIX_RM
)
4272 member
->last_reset
=
4273 PEER_DOWN_CAPABILITY_CHANGE
;
4275 peer_change_action(member
, afi
, safi
,
4285 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4287 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4290 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4292 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4296 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4298 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4299 peer
->tx_shutdown_message
=
4300 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4304 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4306 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4311 /* EBGP multihop configuration. */
4312 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4314 struct peer_group
*group
;
4315 struct listnode
*node
, *nnode
;
4318 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4321 /* see comment in peer_ttl_security_hops_set() */
4322 if (ttl
!= MAXTTL
) {
4323 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4324 group
= peer
->group
;
4325 if (group
->conf
->gtsm_hops
!= 0)
4326 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4328 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4330 if (peer1
->sort
== BGP_PEER_IBGP
)
4333 if (peer1
->gtsm_hops
!= 0)
4334 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4337 if (peer
->gtsm_hops
!= 0)
4338 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4344 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4345 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4346 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4347 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4348 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4350 bgp_session_reset(peer
);
4353 group
= peer
->group
;
4354 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4355 if (peer
->sort
== BGP_PEER_IBGP
)
4358 peer
->ttl
= group
->conf
->ttl
;
4360 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4361 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4362 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4364 bgp_session_reset(peer
);
4370 int peer_ebgp_multihop_unset(struct peer
*peer
)
4372 struct peer_group
*group
;
4373 struct listnode
*node
, *nnode
;
4375 if (peer
->sort
== BGP_PEER_IBGP
)
4378 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4379 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4381 if (peer_group_active(peer
))
4382 peer
->ttl
= peer
->group
->conf
->ttl
;
4384 peer
->ttl
= BGP_DEFAULT_TTL
;
4386 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4387 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4388 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4389 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4391 bgp_session_reset(peer
);
4393 group
= peer
->group
;
4394 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4395 if (peer
->sort
== BGP_PEER_IBGP
)
4398 peer
->ttl
= BGP_DEFAULT_TTL
;
4400 if (peer
->fd
>= 0) {
4401 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4403 peer
, BGP_NOTIFY_CEASE
,
4404 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4406 bgp_session_reset(peer
);
4413 /* Neighbor description. */
4414 int peer_description_set(struct peer
*peer
, const char *desc
)
4416 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4418 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4423 int peer_description_unset(struct peer
*peer
)
4425 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4432 /* Neighbor update-source. */
4433 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4435 struct peer
*member
;
4436 struct listnode
*node
, *nnode
;
4438 /* Set flag and configuration on peer. */
4439 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4440 if (peer
->update_if
) {
4441 if (strcmp(peer
->update_if
, ifname
) == 0)
4443 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4445 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4446 sockunion_free(peer
->update_source
);
4447 peer
->update_source
= NULL
;
4449 /* Check if handling a regular peer. */
4450 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4451 /* Send notification or reset peer depending on state. */
4452 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4453 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4454 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4455 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4457 bgp_session_reset(peer
);
4459 /* Skip peer-group mechanics for regular peers. */
4464 * Set flag and configuration on all peer-group members, unless they are
4465 * explicitely overriding peer-group configuration.
4467 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4468 /* Skip peers with overridden configuration. */
4469 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4472 /* Skip peers with the same configuration. */
4473 if (member
->update_if
) {
4474 if (strcmp(member
->update_if
, ifname
) == 0)
4476 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4479 /* Set flag and configuration on peer-group member. */
4480 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4481 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4482 sockunion_free(member
->update_source
);
4483 member
->update_source
= NULL
;
4485 /* Send notification or reset peer depending on state. */
4486 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4487 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4488 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4489 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4491 bgp_session_reset(member
);
4497 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4499 struct peer
*member
;
4500 struct listnode
*node
, *nnode
;
4502 /* Set flag and configuration on peer. */
4503 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4504 if (peer
->update_source
) {
4505 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4507 sockunion_free(peer
->update_source
);
4509 peer
->update_source
= sockunion_dup(su
);
4510 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4512 /* Check if handling a regular peer. */
4513 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4514 /* Send notification or reset peer depending on state. */
4515 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4516 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4517 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4518 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4520 bgp_session_reset(peer
);
4522 /* Skip peer-group mechanics for regular peers. */
4527 * Set flag and configuration on all peer-group members, unless they are
4528 * explicitely overriding peer-group configuration.
4530 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4531 /* Skip peers with overridden configuration. */
4532 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4535 /* Skip peers with the same configuration. */
4536 if (member
->update_source
) {
4537 if (sockunion_cmp(member
->update_source
, su
) == 0)
4539 sockunion_free(member
->update_source
);
4542 /* Set flag and configuration on peer-group member. */
4543 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4544 member
->update_source
= sockunion_dup(su
);
4545 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4547 /* Send notification or reset peer depending on state. */
4548 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4549 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4550 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4551 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4553 bgp_session_reset(member
);
4559 int peer_update_source_unset(struct peer
*peer
)
4561 struct peer
*member
;
4562 struct listnode
*node
, *nnode
;
4564 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4567 /* Inherit configuration from peer-group if peer is member. */
4568 if (peer_group_active(peer
)) {
4569 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4570 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4571 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4572 MTYPE_PEER_UPDATE_SOURCE
);
4574 /* Otherwise remove flag and configuration from peer. */
4575 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4576 sockunion_free(peer
->update_source
);
4577 peer
->update_source
= NULL
;
4578 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4581 /* Check if handling a regular peer. */
4582 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4583 /* Send notification or reset peer depending on state. */
4584 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4585 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4586 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4587 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4589 bgp_session_reset(peer
);
4591 /* Skip peer-group mechanics for regular peers. */
4596 * Set flag and configuration on all peer-group members, unless they are
4597 * explicitely overriding peer-group configuration.
4599 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4600 /* Skip peers with overridden configuration. */
4601 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4604 /* Skip peers with the same configuration. */
4605 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4606 && !member
->update_source
&& !member
->update_if
)
4609 /* Remove flag and configuration on peer-group member. */
4610 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4611 sockunion_free(member
->update_source
);
4612 member
->update_source
= NULL
;
4613 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4615 /* Send notification or reset peer depending on state. */
4616 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4617 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4618 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4619 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4621 bgp_session_reset(member
);
4627 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4628 const char *rmap
, struct route_map
*route_map
)
4630 struct peer
*member
;
4631 struct listnode
*node
, *nnode
;
4633 /* Set flag and configuration on peer. */
4634 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4636 if (!peer
->default_rmap
[afi
][safi
].name
4637 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4638 if (peer
->default_rmap
[afi
][safi
].name
)
4639 XFREE(MTYPE_ROUTE_MAP_NAME
,
4640 peer
->default_rmap
[afi
][safi
].name
);
4642 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4643 peer
->default_rmap
[afi
][safi
].name
=
4644 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4645 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4646 route_map_counter_increment(route_map
);
4649 if (peer
->default_rmap
[afi
][safi
].name
)
4650 XFREE(MTYPE_ROUTE_MAP_NAME
,
4651 peer
->default_rmap
[afi
][safi
].name
);
4653 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4654 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4655 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4658 /* Check if handling a regular peer. */
4659 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4660 /* Update peer route announcements. */
4661 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4662 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4663 bgp_default_originate(peer
, afi
, safi
, 0);
4664 bgp_announce_route(peer
, afi
, safi
);
4667 /* Skip peer-group mechanics for regular peers. */
4672 * Set flag and configuration on all peer-group members, unless they are
4673 * explicitely overriding peer-group configuration.
4675 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4676 /* Skip peers with overridden configuration. */
4677 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4678 PEER_FLAG_DEFAULT_ORIGINATE
))
4681 /* Set flag and configuration on peer-group member. */
4682 SET_FLAG(member
->af_flags
[afi
][safi
],
4683 PEER_FLAG_DEFAULT_ORIGINATE
);
4685 if (member
->default_rmap
[afi
][safi
].name
)
4686 XFREE(MTYPE_ROUTE_MAP_NAME
,
4687 member
->default_rmap
[afi
][safi
].name
);
4688 route_map_counter_decrement(
4689 member
->default_rmap
[afi
][safi
].map
);
4690 member
->default_rmap
[afi
][safi
].name
=
4691 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4692 member
->default_rmap
[afi
][safi
].map
= route_map
;
4693 route_map_counter_increment(route_map
);
4696 /* Update peer route announcements. */
4697 if (member
->status
== Established
4698 && member
->afc_nego
[afi
][safi
]) {
4699 update_group_adjust_peer(
4700 peer_af_find(member
, afi
, safi
));
4701 bgp_default_originate(member
, afi
, safi
, 0);
4702 bgp_announce_route(member
, afi
, safi
);
4709 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4711 struct peer
*member
;
4712 struct listnode
*node
, *nnode
;
4714 /* Inherit configuration from peer-group if peer is member. */
4715 if (peer_group_active(peer
)) {
4716 peer_af_flag_inherit(peer
, afi
, safi
,
4717 PEER_FLAG_DEFAULT_ORIGINATE
);
4718 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4719 default_rmap
[afi
][safi
].name
,
4720 MTYPE_ROUTE_MAP_NAME
);
4721 PEER_ATTR_INHERIT(peer
, peer
->group
,
4722 default_rmap
[afi
][safi
].map
);
4724 /* Otherwise remove flag and configuration from peer. */
4725 peer_af_flag_unset(peer
, afi
, safi
,
4726 PEER_FLAG_DEFAULT_ORIGINATE
);
4727 if (peer
->default_rmap
[afi
][safi
].name
)
4728 XFREE(MTYPE_ROUTE_MAP_NAME
,
4729 peer
->default_rmap
[afi
][safi
].name
);
4730 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4731 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4732 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4735 /* Check if handling a regular peer. */
4736 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4737 /* Update peer route announcements. */
4738 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4739 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4740 bgp_default_originate(peer
, afi
, safi
, 1);
4741 bgp_announce_route(peer
, afi
, safi
);
4744 /* Skip peer-group mechanics for regular peers. */
4749 * Remove flag and configuration from all peer-group members, unless
4750 * they are explicitely overriding peer-group configuration.
4752 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4753 /* Skip peers with overridden configuration. */
4754 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4755 PEER_FLAG_DEFAULT_ORIGINATE
))
4758 /* Remove flag and configuration on peer-group member. */
4759 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4760 PEER_FLAG_DEFAULT_ORIGINATE
);
4761 if (peer
->default_rmap
[afi
][safi
].name
)
4762 XFREE(MTYPE_ROUTE_MAP_NAME
,
4763 peer
->default_rmap
[afi
][safi
].name
);
4764 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4765 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4766 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4768 /* Update peer route announcements. */
4769 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4770 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4771 bgp_default_originate(peer
, afi
, safi
, 1);
4772 bgp_announce_route(peer
, afi
, safi
);
4779 int peer_port_set(struct peer
*peer
, uint16_t port
)
4785 int peer_port_unset(struct peer
*peer
)
4787 peer
->port
= BGP_PORT_DEFAULT
;
4792 * Helper function that is called after the name of the policy
4793 * being used by a peer has changed (AF specific). Automatically
4794 * initiates inbound or outbound processing as needed.
4796 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4800 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4801 if (peer
->status
== Established
)
4802 bgp_announce_route(peer
, afi
, safi
);
4804 if (peer
->status
!= Established
)
4807 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4808 PEER_FLAG_SOFT_RECONFIG
))
4809 bgp_soft_reconfig_in(peer
, afi
, safi
);
4810 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4811 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4812 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4817 /* neighbor weight. */
4818 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4820 struct peer
*member
;
4821 struct listnode
*node
, *nnode
;
4823 /* Set flag and configuration on peer. */
4824 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4825 if (peer
->weight
[afi
][safi
] != weight
) {
4826 peer
->weight
[afi
][safi
] = weight
;
4827 peer_on_policy_change(peer
, afi
, safi
, 0);
4830 /* Skip peer-group mechanics for regular peers. */
4831 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4835 * Set flag and configuration on all peer-group members, unless they are
4836 * explicitely overriding peer-group configuration.
4838 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4839 /* Skip peers with overridden configuration. */
4840 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4844 /* Set flag and configuration on peer-group member. */
4845 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4846 if (member
->weight
[afi
][safi
] != weight
) {
4847 member
->weight
[afi
][safi
] = weight
;
4848 peer_on_policy_change(member
, afi
, safi
, 0);
4855 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4857 struct peer
*member
;
4858 struct listnode
*node
, *nnode
;
4860 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4863 /* Inherit configuration from peer-group if peer is member. */
4864 if (peer_group_active(peer
)) {
4865 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4866 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4868 peer_on_policy_change(peer
, afi
, safi
, 0);
4872 /* Remove flag and configuration from peer. */
4873 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4874 peer
->weight
[afi
][safi
] = 0;
4875 peer_on_policy_change(peer
, afi
, safi
, 0);
4877 /* Skip peer-group mechanics for regular peers. */
4878 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4882 * Remove flag and configuration from all peer-group members, unless
4883 * they are explicitely overriding peer-group configuration.
4885 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4886 /* Skip peers with overridden configuration. */
4887 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4891 /* Skip peers where flag is already disabled. */
4892 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4895 /* Remove flag and configuration on peer-group member. */
4896 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4897 member
->weight
[afi
][safi
] = 0;
4898 peer_on_policy_change(member
, afi
, safi
, 0);
4904 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4906 struct peer
*member
;
4907 struct listnode
*node
, *nnode
;
4909 if (keepalive
> 65535)
4910 return BGP_ERR_INVALID_VALUE
;
4912 if (holdtime
> 65535)
4913 return BGP_ERR_INVALID_VALUE
;
4915 if (holdtime
< 3 && holdtime
!= 0)
4916 return BGP_ERR_INVALID_VALUE
;
4918 /* Set flag and configuration on peer. */
4919 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4920 peer
->holdtime
= holdtime
;
4921 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4923 /* Skip peer-group mechanics for regular peers. */
4924 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4928 * Set flag and configuration on all peer-group members, unless they are
4929 * explicitely overriding peer-group configuration.
4931 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4932 /* Skip peers with overridden configuration. */
4933 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4936 /* Set flag and configuration on peer-group member. */
4937 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4938 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4939 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4945 int peer_timers_unset(struct peer
*peer
)
4947 struct peer
*member
;
4948 struct listnode
*node
, *nnode
;
4950 /* Inherit configuration from peer-group if peer is member. */
4951 if (peer_group_active(peer
)) {
4952 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4953 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4954 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4956 /* Otherwise remove flag and configuration from peer. */
4957 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4959 peer
->keepalive
= 0;
4962 /* Skip peer-group mechanics for regular peers. */
4963 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4967 * Remove flag and configuration from all peer-group members, unless
4968 * they are explicitely overriding peer-group configuration.
4970 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4971 /* Skip peers with overridden configuration. */
4972 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4975 /* Remove flag and configuration on peer-group member. */
4976 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4977 member
->holdtime
= 0;
4978 member
->keepalive
= 0;
4984 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4986 struct peer
*member
;
4987 struct listnode
*node
, *nnode
;
4989 if (connect
> 65535)
4990 return BGP_ERR_INVALID_VALUE
;
4992 /* Set flag and configuration on peer. */
4993 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4994 peer
->connect
= connect
;
4995 peer
->v_connect
= connect
;
4997 /* Skip peer-group mechanics for regular peers. */
4998 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5002 * Set flag and configuration on all peer-group members, unless they are
5003 * explicitely overriding peer-group configuration.
5005 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5006 /* Skip peers with overridden configuration. */
5007 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5010 /* Set flag and configuration on peer-group member. */
5011 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5012 member
->connect
= connect
;
5013 member
->v_connect
= connect
;
5019 int peer_timers_connect_unset(struct peer
*peer
)
5021 struct peer
*member
;
5022 struct listnode
*node
, *nnode
;
5024 /* Inherit configuration from peer-group if peer is member. */
5025 if (peer_group_active(peer
)) {
5026 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5027 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5029 /* Otherwise remove flag and configuration from peer. */
5030 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5034 /* Set timer with fallback to default value. */
5036 peer
->v_connect
= peer
->connect
;
5038 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5040 /* Skip peer-group mechanics for regular peers. */
5041 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5045 * Remove flag and configuration from all peer-group members, unless
5046 * they are explicitely overriding peer-group configuration.
5048 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5049 /* Skip peers with overridden configuration. */
5050 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5053 /* Remove flag and configuration on peer-group member. */
5054 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5055 member
->connect
= 0;
5056 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5062 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5064 struct peer
*member
;
5065 struct listnode
*node
, *nnode
;
5068 return BGP_ERR_INVALID_VALUE
;
5070 /* Set flag and configuration on peer. */
5071 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5072 peer
->routeadv
= routeadv
;
5073 peer
->v_routeadv
= routeadv
;
5075 /* Check if handling a regular peer. */
5076 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5077 /* Update peer route announcements. */
5078 update_group_adjust_peer_afs(peer
);
5079 if (peer
->status
== Established
)
5080 bgp_announce_route_all(peer
);
5082 /* Skip peer-group mechanics for regular peers. */
5087 * Set flag and configuration on all peer-group members, unless they are
5088 * explicitely overriding peer-group configuration.
5090 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5091 /* Skip peers with overridden configuration. */
5092 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5095 /* Set flag and configuration on peer-group member. */
5096 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5097 member
->routeadv
= routeadv
;
5098 member
->v_routeadv
= routeadv
;
5100 /* Update peer route announcements. */
5101 update_group_adjust_peer_afs(member
);
5102 if (member
->status
== Established
)
5103 bgp_announce_route_all(member
);
5109 int peer_advertise_interval_unset(struct peer
*peer
)
5111 struct peer
*member
;
5112 struct listnode
*node
, *nnode
;
5114 /* Inherit configuration from peer-group if peer is member. */
5115 if (peer_group_active(peer
)) {
5116 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5117 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5119 /* Otherwise remove flag and configuration from peer. */
5120 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5124 /* Set timer with fallback to default value. */
5126 peer
->v_routeadv
= peer
->routeadv
;
5128 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5129 ? BGP_DEFAULT_IBGP_ROUTEADV
5130 : BGP_DEFAULT_EBGP_ROUTEADV
;
5132 /* Check if handling a regular peer. */
5133 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5134 /* Update peer route announcements. */
5135 update_group_adjust_peer_afs(peer
);
5136 if (peer
->status
== Established
)
5137 bgp_announce_route_all(peer
);
5139 /* Skip peer-group mechanics for regular peers. */
5144 * Remove flag and configuration from all peer-group members, unless
5145 * they are explicitely overriding peer-group configuration.
5147 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5148 /* Skip peers with overridden configuration. */
5149 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5152 /* Remove flag and configuration on peer-group member. */
5153 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5154 member
->routeadv
= 0;
5155 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5156 ? BGP_DEFAULT_IBGP_ROUTEADV
5157 : BGP_DEFAULT_EBGP_ROUTEADV
;
5159 /* Update peer route announcements. */
5160 update_group_adjust_peer_afs(member
);
5161 if (member
->status
== Established
)
5162 bgp_announce_route_all(member
);
5168 /* neighbor interface */
5169 void peer_interface_set(struct peer
*peer
, const char *str
)
5171 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5172 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5175 void peer_interface_unset(struct peer
*peer
)
5177 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5178 peer
->ifname
= NULL
;
5182 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5183 int allow_num
, int origin
)
5185 struct peer
*member
;
5186 struct listnode
*node
, *nnode
;
5188 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5189 return BGP_ERR_INVALID_VALUE
;
5191 /* Set flag and configuration on peer. */
5192 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5194 if (peer
->allowas_in
[afi
][safi
] != 0
5195 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5196 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5197 peer_af_flag_set(peer
, afi
, safi
,
5198 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5199 peer
->allowas_in
[afi
][safi
] = 0;
5200 peer_on_policy_change(peer
, afi
, safi
, 0);
5203 if (peer
->allowas_in
[afi
][safi
] != allow_num
5204 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5205 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5207 peer_af_flag_unset(peer
, afi
, safi
,
5208 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5209 peer
->allowas_in
[afi
][safi
] = allow_num
;
5210 peer_on_policy_change(peer
, afi
, safi
, 0);
5214 /* Skip peer-group mechanics for regular peers. */
5215 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5219 * Set flag and configuration on all peer-group members, unless
5220 * they are explicitely overriding peer-group configuration.
5222 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5223 /* Skip peers with overridden configuration. */
5224 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5225 PEER_FLAG_ALLOWAS_IN
))
5228 /* Set flag and configuration on peer-group member. */
5229 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5231 if (member
->allowas_in
[afi
][safi
] != 0
5232 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5233 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5234 SET_FLAG(member
->af_flags
[afi
][safi
],
5235 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5236 member
->allowas_in
[afi
][safi
] = 0;
5237 peer_on_policy_change(peer
, afi
, safi
, 0);
5240 if (member
->allowas_in
[afi
][safi
] != allow_num
5241 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5242 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5243 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5244 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5245 member
->allowas_in
[afi
][safi
] = allow_num
;
5246 peer_on_policy_change(peer
, afi
, safi
, 0);
5254 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5256 struct peer
*member
;
5257 struct listnode
*node
, *nnode
;
5259 /* Skip peer if flag is already disabled. */
5260 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5263 /* Inherit configuration from peer-group if peer is member. */
5264 if (peer_group_active(peer
)) {
5265 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5266 peer_af_flag_inherit(peer
, afi
, safi
,
5267 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5268 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5269 peer_on_policy_change(peer
, afi
, safi
, 0);
5274 /* Remove flag and configuration from peer. */
5275 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5276 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5277 peer
->allowas_in
[afi
][safi
] = 0;
5278 peer_on_policy_change(peer
, afi
, safi
, 0);
5280 /* Skip peer-group mechanics if handling a regular peer. */
5281 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5285 * Remove flags and configuration from all peer-group members, unless
5286 * they are explicitely overriding peer-group configuration.
5288 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5289 /* Skip peers with overridden configuration. */
5290 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5291 PEER_FLAG_ALLOWAS_IN
))
5294 /* Skip peers where flag is already disabled. */
5295 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5296 PEER_FLAG_ALLOWAS_IN
))
5299 /* Remove flags and configuration on peer-group member. */
5300 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5301 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5302 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5303 member
->allowas_in
[afi
][safi
] = 0;
5304 peer_on_policy_change(member
, afi
, safi
, 0);
5310 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5313 bool old_no_prepend
, old_replace_as
;
5314 struct bgp
*bgp
= peer
->bgp
;
5315 struct peer
*member
;
5316 struct listnode
*node
, *nnode
;
5318 if (peer_sort(peer
) != BGP_PEER_EBGP
5319 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5320 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5323 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5326 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5328 /* Save previous flag states. */
5330 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5332 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5334 /* Set flag and configuration on peer. */
5335 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5336 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5337 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5339 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5340 && old_replace_as
== replace_as
)
5342 peer
->change_local_as
= as
;
5344 /* Check if handling a regular peer. */
5345 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5346 /* Send notification or reset peer depending on state. */
5347 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5348 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5349 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5350 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5352 bgp_session_reset(peer
);
5354 /* Skip peer-group mechanics for regular peers. */
5359 * Set flag and configuration on all peer-group members, unless they are
5360 * explicitely overriding peer-group configuration.
5362 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5363 /* Skip peers with overridden configuration. */
5364 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5367 /* Skip peers with the same configuration. */
5368 old_no_prepend
= CHECK_FLAG(member
->flags
,
5369 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5370 old_replace_as
= CHECK_FLAG(member
->flags
,
5371 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5372 if (member
->change_local_as
== as
5373 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5374 && old_no_prepend
== no_prepend
5375 && old_replace_as
== replace_as
)
5378 /* Set flag and configuration on peer-group member. */
5379 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5380 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5382 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5384 member
->change_local_as
= as
;
5386 /* Send notification or stop peer depending on state. */
5387 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5388 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5389 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5390 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5392 BGP_EVENT_ADD(member
, BGP_Stop
);
5398 int peer_local_as_unset(struct peer
*peer
)
5400 struct peer
*member
;
5401 struct listnode
*node
, *nnode
;
5403 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5406 /* Inherit configuration from peer-group if peer is member. */
5407 if (peer_group_active(peer
)) {
5408 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5409 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5410 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5411 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5413 /* Otherwise remove flag and configuration from peer. */
5414 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5415 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5416 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5417 peer
->change_local_as
= 0;
5420 /* Check if handling a regular peer. */
5421 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5422 /* Send notification or stop peer depending on state. */
5423 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5424 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5425 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5426 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5428 BGP_EVENT_ADD(peer
, BGP_Stop
);
5430 /* Skip peer-group mechanics for regular peers. */
5435 * Remove flag and configuration from all peer-group members, unless
5436 * they are explicitely overriding peer-group configuration.
5438 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5439 /* Skip peers with overridden configuration. */
5440 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5443 /* Remove flag and configuration on peer-group member. */
5444 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5445 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5446 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5447 member
->change_local_as
= 0;
5449 /* Send notification or stop peer depending on state. */
5450 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5451 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5452 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5453 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5455 bgp_session_reset(member
);
5461 /* Set password for authenticating with the peer. */
5462 int peer_password_set(struct peer
*peer
, const char *password
)
5464 struct peer
*member
;
5465 struct listnode
*node
, *nnode
;
5466 int len
= password
? strlen(password
) : 0;
5467 int ret
= BGP_SUCCESS
;
5469 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5470 return BGP_ERR_INVALID_VALUE
;
5472 /* Set flag and configuration on peer. */
5473 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5474 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5476 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5477 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5479 /* Check if handling a regular peer. */
5480 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5481 /* Send notification or reset peer depending on state. */
5482 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5483 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5484 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5486 bgp_session_reset(peer
);
5489 * Attempt to install password on socket and skip peer-group
5492 if (BGP_PEER_SU_UNSPEC(peer
))
5494 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5495 : BGP_ERR_TCPSIG_FAILED
;
5499 * Set flag and configuration on all peer-group members, unless they are
5500 * explicitely overriding peer-group configuration.
5502 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5503 /* Skip peers with overridden configuration. */
5504 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5507 /* Skip peers with the same password. */
5508 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5511 /* Set flag and configuration on peer-group member. */
5512 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5513 if (member
->password
)
5514 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5515 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5517 /* Send notification or reset peer depending on state. */
5518 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5519 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5520 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5522 bgp_session_reset(member
);
5524 /* Attempt to install password on socket. */
5525 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5526 ret
= BGP_ERR_TCPSIG_FAILED
;
5529 /* Set flag and configuration on all peer-group listen ranges */
5530 struct listnode
*ln
;
5533 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5534 bgp_md5_set_prefix(lr
, password
);
5535 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5536 bgp_md5_set_prefix(lr
, password
);
5541 int peer_password_unset(struct peer
*peer
)
5543 struct peer
*member
;
5544 struct listnode
*node
, *nnode
;
5546 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5549 /* Inherit configuration from peer-group if peer is member. */
5550 if (peer_group_active(peer
)) {
5551 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5552 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5553 MTYPE_PEER_PASSWORD
);
5555 /* Otherwise remove flag and configuration from peer. */
5556 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5557 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5560 /* Check if handling a regular peer. */
5561 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5562 /* Send notification or reset peer depending on state. */
5563 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5564 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5565 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5567 bgp_session_reset(peer
);
5569 /* Attempt to uninstall password on socket. */
5570 if (!BGP_PEER_SU_UNSPEC(peer
))
5571 bgp_md5_unset(peer
);
5573 /* Skip peer-group mechanics for regular peers. */
5578 * Remove flag and configuration from all peer-group members, unless
5579 * they are explicitely overriding peer-group configuration.
5581 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5582 /* Skip peers with overridden configuration. */
5583 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5586 /* Remove flag and configuration on peer-group member. */
5587 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5588 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5590 /* Send notification or reset peer depending on state. */
5591 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5592 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5593 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5595 bgp_session_reset(member
);
5597 /* Attempt to uninstall password on socket. */
5598 if (!BGP_PEER_SU_UNSPEC(member
))
5599 bgp_md5_unset(member
);
5602 /* Set flag and configuration on all peer-group listen ranges */
5603 struct listnode
*ln
;
5606 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5607 bgp_md5_unset_prefix(lr
);
5608 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5609 bgp_md5_unset_prefix(lr
);
5615 /* Set distribute list to the peer. */
5616 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5619 struct peer
*member
;
5620 struct bgp_filter
*filter
;
5621 struct listnode
*node
, *nnode
;
5623 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5624 return BGP_ERR_INVALID_VALUE
;
5626 /* Set configuration on peer. */
5627 filter
= &peer
->filter
[afi
][safi
];
5628 if (filter
->plist
[direct
].name
)
5629 return BGP_ERR_PEER_FILTER_CONFLICT
;
5630 if (filter
->dlist
[direct
].name
)
5631 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5632 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5633 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5635 /* Check if handling a regular peer. */
5636 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5637 /* Set override-flag and process peer route updates. */
5638 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5639 PEER_FT_DISTRIBUTE_LIST
);
5640 peer_on_policy_change(peer
, afi
, safi
,
5641 (direct
== FILTER_OUT
) ? 1 : 0);
5643 /* Skip peer-group mechanics for regular peers. */
5648 * Set configuration on all peer-group members, un less they are
5649 * explicitely overriding peer-group configuration.
5651 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5652 /* Skip peers with overridden configuration. */
5653 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5654 PEER_FT_DISTRIBUTE_LIST
))
5657 /* Set configuration on peer-group member. */
5658 filter
= &member
->filter
[afi
][safi
];
5659 if (filter
->dlist
[direct
].name
)
5660 XFREE(MTYPE_BGP_FILTER_NAME
,
5661 filter
->dlist
[direct
].name
);
5662 filter
->dlist
[direct
].name
=
5663 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5664 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5666 /* Process peer route updates. */
5667 peer_on_policy_change(member
, afi
, safi
,
5668 (direct
== FILTER_OUT
) ? 1 : 0);
5674 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5676 struct peer
*member
;
5677 struct bgp_filter
*filter
;
5678 struct listnode
*node
, *nnode
;
5680 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5681 return BGP_ERR_INVALID_VALUE
;
5683 /* Unset override-flag unconditionally. */
5684 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5685 PEER_FT_DISTRIBUTE_LIST
);
5687 /* Inherit configuration from peer-group if peer is member. */
5688 if (peer_group_active(peer
)) {
5689 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5690 filter
[afi
][safi
].dlist
[direct
].name
,
5691 MTYPE_BGP_FILTER_NAME
);
5692 PEER_ATTR_INHERIT(peer
, peer
->group
,
5693 filter
[afi
][safi
].dlist
[direct
].alist
);
5695 /* Otherwise remove configuration from peer. */
5696 filter
= &peer
->filter
[afi
][safi
];
5697 if (filter
->dlist
[direct
].name
)
5698 XFREE(MTYPE_BGP_FILTER_NAME
,
5699 filter
->dlist
[direct
].name
);
5700 filter
->dlist
[direct
].name
= NULL
;
5701 filter
->dlist
[direct
].alist
= NULL
;
5704 /* Check if handling a regular peer. */
5705 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5706 /* Process peer route updates. */
5707 peer_on_policy_change(peer
, afi
, safi
,
5708 (direct
== FILTER_OUT
) ? 1 : 0);
5710 /* Skip peer-group mechanics for regular peers. */
5715 * Remove configuration on all peer-group members, unless they are
5716 * explicitely overriding peer-group configuration.
5718 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5719 /* Skip peers with overridden configuration. */
5720 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5721 PEER_FT_DISTRIBUTE_LIST
))
5724 /* Remove configuration on peer-group member. */
5725 filter
= &member
->filter
[afi
][safi
];
5726 if (filter
->dlist
[direct
].name
)
5727 XFREE(MTYPE_BGP_FILTER_NAME
,
5728 filter
->dlist
[direct
].name
);
5729 filter
->dlist
[direct
].name
= NULL
;
5730 filter
->dlist
[direct
].alist
= NULL
;
5732 /* Process peer route updates. */
5733 peer_on_policy_change(member
, afi
, safi
,
5734 (direct
== FILTER_OUT
) ? 1 : 0);
5740 /* Update distribute list. */
5741 static void peer_distribute_update(struct access_list
*access
)
5746 struct listnode
*mnode
, *mnnode
;
5747 struct listnode
*node
, *nnode
;
5750 struct peer_group
*group
;
5751 struct bgp_filter
*filter
;
5753 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5755 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5756 access
->name
, 0, 0);
5757 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5758 FOREACH_AFI_SAFI (afi
, safi
) {
5759 filter
= &peer
->filter
[afi
][safi
];
5761 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5763 if (filter
->dlist
[direct
].name
)
5764 filter
->dlist
[direct
]
5765 .alist
= access_list_lookup(
5767 filter
->dlist
[direct
]
5770 filter
->dlist
[direct
].alist
=
5775 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5776 FOREACH_AFI_SAFI (afi
, safi
) {
5777 filter
= &group
->conf
->filter
[afi
][safi
];
5779 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5781 if (filter
->dlist
[direct
].name
)
5782 filter
->dlist
[direct
]
5783 .alist
= access_list_lookup(
5785 filter
->dlist
[direct
]
5788 filter
->dlist
[direct
].alist
=
5794 vnc_prefix_list_update(bgp
);
5799 /* Set prefix list to the peer. */
5800 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5803 struct peer
*member
;
5804 struct bgp_filter
*filter
;
5805 struct listnode
*node
, *nnode
;
5807 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5808 return BGP_ERR_INVALID_VALUE
;
5810 /* Set configuration on peer. */
5811 filter
= &peer
->filter
[afi
][safi
];
5812 if (filter
->dlist
[direct
].name
)
5813 return BGP_ERR_PEER_FILTER_CONFLICT
;
5814 if (filter
->plist
[direct
].name
)
5815 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5816 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5817 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5819 /* Check if handling a regular peer. */
5820 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5821 /* Set override-flag and process peer route updates. */
5822 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5823 PEER_FT_PREFIX_LIST
);
5824 peer_on_policy_change(peer
, afi
, safi
,
5825 (direct
== FILTER_OUT
) ? 1 : 0);
5827 /* Skip peer-group mechanics for regular peers. */
5832 * Set configuration on all peer-group members, unless they are
5833 * explicitely overriding peer-group configuration.
5835 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5836 /* Skip peers with overridden configuration. */
5837 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5838 PEER_FT_PREFIX_LIST
))
5841 /* Set configuration on peer-group member. */
5842 filter
= &member
->filter
[afi
][safi
];
5843 if (filter
->plist
[direct
].name
)
5844 XFREE(MTYPE_BGP_FILTER_NAME
,
5845 filter
->plist
[direct
].name
);
5846 filter
->plist
[direct
].name
=
5847 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5848 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5850 /* Process peer route updates. */
5851 peer_on_policy_change(member
, afi
, safi
,
5852 (direct
== FILTER_OUT
) ? 1 : 0);
5858 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5861 struct peer
*member
;
5862 struct bgp_filter
*filter
;
5863 struct listnode
*node
, *nnode
;
5865 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5866 return BGP_ERR_INVALID_VALUE
;
5868 /* Unset override-flag unconditionally. */
5869 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5870 PEER_FT_PREFIX_LIST
);
5872 /* Inherit configuration from peer-group if peer is member. */
5873 if (peer_group_active(peer
)) {
5874 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5875 filter
[afi
][safi
].plist
[direct
].name
,
5876 MTYPE_BGP_FILTER_NAME
);
5877 PEER_ATTR_INHERIT(peer
, peer
->group
,
5878 filter
[afi
][safi
].plist
[direct
].plist
);
5880 /* Otherwise remove configuration from peer. */
5881 filter
= &peer
->filter
[afi
][safi
];
5882 if (filter
->plist
[direct
].name
)
5883 XFREE(MTYPE_BGP_FILTER_NAME
,
5884 filter
->plist
[direct
].name
);
5885 filter
->plist
[direct
].name
= NULL
;
5886 filter
->plist
[direct
].plist
= NULL
;
5889 /* Check if handling a regular peer. */
5890 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5891 /* Process peer route updates. */
5892 peer_on_policy_change(peer
, afi
, safi
,
5893 (direct
== FILTER_OUT
) ? 1 : 0);
5895 /* Skip peer-group mechanics for regular peers. */
5900 * Remove configuration on all peer-group members, unless they are
5901 * explicitely overriding peer-group configuration.
5903 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5904 /* Skip peers with overridden configuration. */
5905 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5906 PEER_FT_PREFIX_LIST
))
5909 /* Remove configuration on peer-group member. */
5910 filter
= &member
->filter
[afi
][safi
];
5911 if (filter
->plist
[direct
].name
)
5912 XFREE(MTYPE_BGP_FILTER_NAME
,
5913 filter
->plist
[direct
].name
);
5914 filter
->plist
[direct
].name
= NULL
;
5915 filter
->plist
[direct
].plist
= NULL
;
5917 /* Process peer route updates. */
5918 peer_on_policy_change(member
, afi
, safi
,
5919 (direct
== FILTER_OUT
) ? 1 : 0);
5925 /* Update prefix-list list. */
5926 static void peer_prefix_list_update(struct prefix_list
*plist
)
5928 struct listnode
*mnode
, *mnnode
;
5929 struct listnode
*node
, *nnode
;
5932 struct peer_group
*group
;
5933 struct bgp_filter
*filter
;
5938 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5941 * Update the prefix-list on update groups.
5943 update_group_policy_update(
5944 bgp
, BGP_POLICY_PREFIX_LIST
,
5945 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5947 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5948 FOREACH_AFI_SAFI (afi
, safi
) {
5949 filter
= &peer
->filter
[afi
][safi
];
5951 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5953 if (filter
->plist
[direct
].name
)
5954 filter
->plist
[direct
]
5955 .plist
= prefix_list_lookup(
5957 filter
->plist
[direct
]
5960 filter
->plist
[direct
].plist
=
5965 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5966 FOREACH_AFI_SAFI (afi
, safi
) {
5967 filter
= &group
->conf
->filter
[afi
][safi
];
5969 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5971 if (filter
->plist
[direct
].name
)
5972 filter
->plist
[direct
]
5973 .plist
= prefix_list_lookup(
5975 filter
->plist
[direct
]
5978 filter
->plist
[direct
].plist
=
5986 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5989 struct peer
*member
;
5990 struct bgp_filter
*filter
;
5991 struct listnode
*node
, *nnode
;
5993 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5994 return BGP_ERR_INVALID_VALUE
;
5996 /* Set configuration on peer. */
5997 filter
= &peer
->filter
[afi
][safi
];
5998 if (filter
->aslist
[direct
].name
)
5999 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
6000 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6001 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6003 /* Check if handling a regular peer. */
6004 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6005 /* Set override-flag and process peer route updates. */
6006 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6007 PEER_FT_FILTER_LIST
);
6008 peer_on_policy_change(peer
, afi
, safi
,
6009 (direct
== FILTER_OUT
) ? 1 : 0);
6011 /* Skip peer-group mechanics for regular peers. */
6016 * Set configuration on all peer-group members, unless they are
6017 * explicitely overriding peer-group configuration.
6019 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6020 /* Skip peers with overridden configuration. */
6021 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6022 PEER_FT_FILTER_LIST
))
6025 /* Set configuration on peer-group member. */
6026 filter
= &member
->filter
[afi
][safi
];
6027 if (filter
->aslist
[direct
].name
)
6028 XFREE(MTYPE_BGP_FILTER_NAME
,
6029 filter
->aslist
[direct
].name
);
6030 filter
->aslist
[direct
].name
=
6031 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6032 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6034 /* Process peer route updates. */
6035 peer_on_policy_change(member
, afi
, safi
,
6036 (direct
== FILTER_OUT
) ? 1 : 0);
6042 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6044 struct peer
*member
;
6045 struct bgp_filter
*filter
;
6046 struct listnode
*node
, *nnode
;
6048 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6049 return BGP_ERR_INVALID_VALUE
;
6051 /* Unset override-flag unconditionally. */
6052 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6053 PEER_FT_FILTER_LIST
);
6055 /* Inherit configuration from peer-group if peer is member. */
6056 if (peer_group_active(peer
)) {
6057 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6058 filter
[afi
][safi
].aslist
[direct
].name
,
6059 MTYPE_BGP_FILTER_NAME
);
6060 PEER_ATTR_INHERIT(peer
, peer
->group
,
6061 filter
[afi
][safi
].aslist
[direct
].aslist
);
6063 /* Otherwise remove configuration from peer. */
6064 filter
= &peer
->filter
[afi
][safi
];
6065 if (filter
->aslist
[direct
].name
)
6066 XFREE(MTYPE_BGP_FILTER_NAME
,
6067 filter
->aslist
[direct
].name
);
6068 filter
->aslist
[direct
].name
= NULL
;
6069 filter
->aslist
[direct
].aslist
= NULL
;
6072 /* Check if handling a regular peer. */
6073 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6074 /* Process peer route updates. */
6075 peer_on_policy_change(peer
, afi
, safi
,
6076 (direct
== FILTER_OUT
) ? 1 : 0);
6078 /* Skip peer-group mechanics for regular peers. */
6083 * Remove configuration on all peer-group members, unless they are
6084 * explicitely overriding peer-group configuration.
6086 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6087 /* Skip peers with overridden configuration. */
6088 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6089 PEER_FT_FILTER_LIST
))
6092 /* Remove configuration on peer-group member. */
6093 filter
= &member
->filter
[afi
][safi
];
6094 if (filter
->aslist
[direct
].name
)
6095 XFREE(MTYPE_BGP_FILTER_NAME
,
6096 filter
->aslist
[direct
].name
);
6097 filter
->aslist
[direct
].name
= NULL
;
6098 filter
->aslist
[direct
].aslist
= NULL
;
6100 /* Process peer route updates. */
6101 peer_on_policy_change(member
, afi
, safi
,
6102 (direct
== FILTER_OUT
) ? 1 : 0);
6108 static void peer_aslist_update(const char *aslist_name
)
6113 struct listnode
*mnode
, *mnnode
;
6114 struct listnode
*node
, *nnode
;
6117 struct peer_group
*group
;
6118 struct bgp_filter
*filter
;
6120 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6121 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6124 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6125 FOREACH_AFI_SAFI (afi
, safi
) {
6126 filter
= &peer
->filter
[afi
][safi
];
6128 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6130 if (filter
->aslist
[direct
].name
)
6131 filter
->aslist
[direct
]
6132 .aslist
= as_list_lookup(
6133 filter
->aslist
[direct
]
6136 filter
->aslist
[direct
].aslist
=
6141 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6142 FOREACH_AFI_SAFI (afi
, safi
) {
6143 filter
= &group
->conf
->filter
[afi
][safi
];
6145 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6147 if (filter
->aslist
[direct
].name
)
6148 filter
->aslist
[direct
]
6149 .aslist
= as_list_lookup(
6150 filter
->aslist
[direct
]
6153 filter
->aslist
[direct
].aslist
=
6161 static void peer_aslist_add(char *aslist_name
)
6163 peer_aslist_update(aslist_name
);
6164 route_map_notify_dependencies((char *)aslist_name
,
6165 RMAP_EVENT_ASLIST_ADDED
);
6168 static void peer_aslist_del(const char *aslist_name
)
6170 peer_aslist_update(aslist_name
);
6171 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6175 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6176 const char *name
, struct route_map
*route_map
)
6178 struct peer
*member
;
6179 struct bgp_filter
*filter
;
6180 struct listnode
*node
, *nnode
;
6182 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6183 return BGP_ERR_INVALID_VALUE
;
6185 /* Set configuration on peer. */
6186 filter
= &peer
->filter
[afi
][safi
];
6187 if (filter
->map
[direct
].name
) {
6188 /* If the neighbor is configured with the same route-map
6189 * again then, ignore the duplicate configuration.
6191 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6194 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6196 route_map_counter_decrement(filter
->map
[direct
].map
);
6197 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6198 filter
->map
[direct
].map
= route_map
;
6199 route_map_counter_increment(route_map
);
6201 /* Check if handling a regular peer. */
6202 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6203 /* Set override-flag and process peer route updates. */
6204 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6206 peer_on_policy_change(peer
, afi
, safi
,
6207 (direct
== RMAP_OUT
) ? 1 : 0);
6209 /* Skip peer-group mechanics for regular peers. */
6214 * Set configuration on all peer-group members, unless they are
6215 * explicitely overriding peer-group configuration.
6217 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6218 /* Skip peers with overridden configuration. */
6219 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6223 /* Set configuration on peer-group member. */
6224 filter
= &member
->filter
[afi
][safi
];
6225 if (filter
->map
[direct
].name
)
6226 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6227 route_map_counter_decrement(filter
->map
[direct
].map
);
6228 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6229 filter
->map
[direct
].map
= route_map
;
6230 route_map_counter_increment(route_map
);
6232 /* Process peer route updates. */
6233 peer_on_policy_change(member
, afi
, safi
,
6234 (direct
== RMAP_OUT
) ? 1 : 0);
6239 /* Unset route-map from the peer. */
6240 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6242 struct peer
*member
;
6243 struct bgp_filter
*filter
;
6244 struct listnode
*node
, *nnode
;
6246 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6247 return BGP_ERR_INVALID_VALUE
;
6249 /* Unset override-flag unconditionally. */
6250 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6252 /* Inherit configuration from peer-group if peer is member. */
6253 if (peer_group_active(peer
)) {
6254 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6255 filter
[afi
][safi
].map
[direct
].name
,
6256 MTYPE_BGP_FILTER_NAME
);
6257 PEER_ATTR_INHERIT(peer
, peer
->group
,
6258 filter
[afi
][safi
].map
[direct
].map
);
6260 /* Otherwise remove configuration from peer. */
6261 filter
= &peer
->filter
[afi
][safi
];
6262 if (filter
->map
[direct
].name
)
6263 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6264 route_map_counter_decrement(filter
->map
[direct
].map
);
6265 filter
->map
[direct
].name
= NULL
;
6266 filter
->map
[direct
].map
= NULL
;
6269 /* Check if handling a regular peer. */
6270 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6271 /* Process peer route updates. */
6272 peer_on_policy_change(peer
, afi
, safi
,
6273 (direct
== RMAP_OUT
) ? 1 : 0);
6275 /* Skip peer-group mechanics for regular peers. */
6280 * Remove configuration on all peer-group members, unless they are
6281 * explicitely overriding peer-group configuration.
6283 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6284 /* Skip peers with overridden configuration. */
6285 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6289 /* Remove configuration on peer-group member. */
6290 filter
= &member
->filter
[afi
][safi
];
6291 if (filter
->map
[direct
].name
)
6292 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6293 route_map_counter_decrement(filter
->map
[direct
].map
);
6294 filter
->map
[direct
].name
= NULL
;
6295 filter
->map
[direct
].map
= NULL
;
6297 /* Process peer route updates. */
6298 peer_on_policy_change(member
, afi
, safi
,
6299 (direct
== RMAP_OUT
) ? 1 : 0);
6305 /* Set unsuppress-map to the peer. */
6306 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6307 const char *name
, struct route_map
*route_map
)
6309 struct peer
*member
;
6310 struct bgp_filter
*filter
;
6311 struct listnode
*node
, *nnode
;
6313 /* Set configuration on peer. */
6314 filter
= &peer
->filter
[afi
][safi
];
6315 if (filter
->usmap
.name
)
6316 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6317 route_map_counter_decrement(filter
->usmap
.map
);
6318 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6319 filter
->usmap
.map
= route_map
;
6320 route_map_counter_increment(route_map
);
6322 /* Check if handling a regular peer. */
6323 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6324 /* Set override-flag and process peer route updates. */
6325 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6326 PEER_FT_UNSUPPRESS_MAP
);
6327 peer_on_policy_change(peer
, afi
, safi
, 1);
6329 /* Skip peer-group mechanics for regular peers. */
6334 * Set configuration on all peer-group members, unless they are
6335 * explicitely overriding peer-group configuration.
6337 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6338 /* Skip peers with overridden configuration. */
6339 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6340 PEER_FT_UNSUPPRESS_MAP
))
6343 /* Set configuration on peer-group member. */
6344 filter
= &member
->filter
[afi
][safi
];
6345 if (filter
->usmap
.name
)
6346 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6347 route_map_counter_decrement(filter
->usmap
.map
);
6348 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6349 filter
->usmap
.map
= route_map
;
6350 route_map_counter_increment(route_map
);
6352 /* Process peer route updates. */
6353 peer_on_policy_change(member
, afi
, safi
, 1);
6359 /* Unset route-map from the peer. */
6360 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6362 struct peer
*member
;
6363 struct bgp_filter
*filter
;
6364 struct listnode
*node
, *nnode
;
6366 /* Unset override-flag unconditionally. */
6367 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6369 /* Inherit configuration from peer-group if peer is member. */
6370 if (peer_group_active(peer
)) {
6371 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6372 filter
[afi
][safi
].usmap
.name
,
6373 MTYPE_BGP_FILTER_NAME
);
6374 PEER_ATTR_INHERIT(peer
, peer
->group
,
6375 filter
[afi
][safi
].usmap
.map
);
6377 /* Otherwise remove configuration from peer. */
6378 filter
= &peer
->filter
[afi
][safi
];
6379 if (filter
->usmap
.name
)
6380 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6381 route_map_counter_decrement(filter
->usmap
.map
);
6382 filter
->usmap
.name
= NULL
;
6383 filter
->usmap
.map
= NULL
;
6386 /* Check if handling a regular peer. */
6387 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6388 /* Process peer route updates. */
6389 peer_on_policy_change(peer
, afi
, safi
, 1);
6391 /* Skip peer-group mechanics for regular peers. */
6396 * Remove configuration on all peer-group members, unless they are
6397 * explicitely overriding peer-group configuration.
6399 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6400 /* Skip peers with overridden configuration. */
6401 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6402 PEER_FT_UNSUPPRESS_MAP
))
6405 /* Remove configuration on peer-group member. */
6406 filter
= &member
->filter
[afi
][safi
];
6407 if (filter
->usmap
.name
)
6408 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6409 route_map_counter_decrement(filter
->usmap
.map
);
6410 filter
->usmap
.name
= NULL
;
6411 filter
->usmap
.map
= NULL
;
6413 /* Process peer route updates. */
6414 peer_on_policy_change(member
, afi
, safi
, 1);
6420 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6421 uint32_t max
, uint8_t threshold
, int warning
,
6424 struct peer
*member
;
6425 struct listnode
*node
, *nnode
;
6427 /* Set flags and configuration on peer. */
6428 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6430 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6432 peer_af_flag_unset(peer
, afi
, safi
,
6433 PEER_FLAG_MAX_PREFIX_WARNING
);
6435 peer
->pmax
[afi
][safi
] = max
;
6436 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6437 peer
->pmax_restart
[afi
][safi
] = restart
;
6439 /* Check if handling a regular peer. */
6440 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6441 /* Re-check if peer violates maximum-prefix. */
6442 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6443 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6445 /* Skip peer-group mechanics for regular peers. */
6450 * Set flags and configuration on all peer-group members, unless they
6451 * are explicitely overriding peer-group configuration.
6453 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6454 /* Skip peers with overridden configuration. */
6455 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6456 PEER_FLAG_MAX_PREFIX
))
6459 /* Set flag and configuration on peer-group member. */
6460 member
->pmax
[afi
][safi
] = max
;
6461 member
->pmax_threshold
[afi
][safi
] = threshold
;
6462 member
->pmax_restart
[afi
][safi
] = restart
;
6464 SET_FLAG(member
->af_flags
[afi
][safi
],
6465 PEER_FLAG_MAX_PREFIX_WARNING
);
6467 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6468 PEER_FLAG_MAX_PREFIX_WARNING
);
6470 /* Re-check if peer violates maximum-prefix. */
6471 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6472 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6478 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6480 /* Inherit configuration from peer-group if peer is member. */
6481 if (peer_group_active(peer
)) {
6482 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6483 peer_af_flag_inherit(peer
, afi
, safi
,
6484 PEER_FLAG_MAX_PREFIX_WARNING
);
6485 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6486 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6487 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6492 /* Remove flags and configuration from peer. */
6493 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6494 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6495 peer
->pmax
[afi
][safi
] = 0;
6496 peer
->pmax_threshold
[afi
][safi
] = 0;
6497 peer
->pmax_restart
[afi
][safi
] = 0;
6500 * Remove flags and configuration from all peer-group members, unless
6501 * they are explicitely overriding peer-group configuration.
6503 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6504 struct peer
*member
;
6505 struct listnode
*node
;
6507 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6508 /* Skip peers with overridden configuration. */
6509 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6510 PEER_FLAG_MAX_PREFIX
))
6513 /* Remove flag and configuration on peer-group member.
6515 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6516 PEER_FLAG_MAX_PREFIX
);
6517 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6518 PEER_FLAG_MAX_PREFIX_WARNING
);
6519 member
->pmax
[afi
][safi
] = 0;
6520 member
->pmax_threshold
[afi
][safi
] = 0;
6521 member
->pmax_restart
[afi
][safi
] = 0;
6528 int is_ebgp_multihop_configured(struct peer
*peer
)
6530 struct peer_group
*group
;
6531 struct listnode
*node
, *nnode
;
6534 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6535 group
= peer
->group
;
6536 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6537 && (group
->conf
->ttl
!= 1))
6540 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6541 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6542 && (peer1
->ttl
!= 1))
6546 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6552 /* Set # of hops between us and BGP peer. */
6553 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6555 struct peer_group
*group
;
6556 struct listnode
*node
, *nnode
;
6559 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6560 gtsm_hops
, peer
->host
);
6562 /* We cannot configure ttl-security hops when ebgp-multihop is already
6563 set. For non peer-groups, the check is simple. For peer-groups,
6565 slightly messy, because we need to check both the peer-group
6567 and all peer-group members for any trace of ebgp-multihop
6569 before actually applying the ttl-security rules. Cisco really made a
6570 mess of this configuration parameter, and OpenBGPD got it right.
6573 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6574 if (is_ebgp_multihop_configured(peer
))
6575 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6577 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6578 peer
->gtsm_hops
= gtsm_hops
;
6580 /* Calling ebgp multihop also resets the session.
6581 * On restart, NHT will get setup correctly as will the
6582 * min & max ttls on the socket. The return value is
6585 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6590 group
= peer
->group
;
6591 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6593 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6595 /* Calling ebgp multihop also resets the
6597 * On restart, NHT will get setup correctly as
6599 * min & max ttls on the socket. The return
6603 peer_ebgp_multihop_set(peer
, MAXTTL
);
6607 /* Post the first gtsm setup or if its ibgp, maxttl setting
6609 * necessary, just set the minttl.
6611 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6612 peer
->gtsm_hops
= gtsm_hops
;
6615 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6616 MAXTTL
+ 1 - gtsm_hops
);
6617 if ((peer
->status
< Established
) && peer
->doppelganger
6618 && (peer
->doppelganger
->fd
>= 0))
6619 sockopt_minttl(peer
->su
.sa
.sa_family
,
6620 peer
->doppelganger
->fd
,
6621 MAXTTL
+ 1 - gtsm_hops
);
6623 group
= peer
->group
;
6624 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6626 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6628 /* Change setting of existing peer
6629 * established then change value (may break
6631 * not established yet (teardown session and
6633 * no session then do nothing (will get
6634 * handled by next connection)
6636 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6638 peer
->su
.sa
.sa_family
, peer
->fd
,
6639 MAXTTL
+ 1 - peer
->gtsm_hops
);
6640 if ((peer
->status
< Established
)
6641 && peer
->doppelganger
6642 && (peer
->doppelganger
->fd
>= 0))
6643 sockopt_minttl(peer
->su
.sa
.sa_family
,
6644 peer
->doppelganger
->fd
,
6645 MAXTTL
+ 1 - gtsm_hops
);
6653 int peer_ttl_security_hops_unset(struct peer
*peer
)
6655 struct peer_group
*group
;
6656 struct listnode
*node
, *nnode
;
6659 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6662 /* if a peer-group member, then reset to peer-group default rather than
6664 if (peer_group_active(peer
))
6665 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6667 peer
->gtsm_hops
= 0;
6669 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6670 /* Invoking ebgp_multihop_set will set the TTL back to the
6672 * value as well as restting the NHT and such. The session is
6675 if (peer
->sort
== BGP_PEER_EBGP
)
6676 ret
= peer_ebgp_multihop_unset(peer
);
6679 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6682 if ((peer
->status
< Established
) && peer
->doppelganger
6683 && (peer
->doppelganger
->fd
>= 0))
6684 sockopt_minttl(peer
->su
.sa
.sa_family
,
6685 peer
->doppelganger
->fd
, 0);
6688 group
= peer
->group
;
6689 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6690 peer
->gtsm_hops
= 0;
6691 if (peer
->sort
== BGP_PEER_EBGP
)
6692 ret
= peer_ebgp_multihop_unset(peer
);
6695 sockopt_minttl(peer
->su
.sa
.sa_family
,
6698 if ((peer
->status
< Established
)
6699 && peer
->doppelganger
6700 && (peer
->doppelganger
->fd
>= 0))
6701 sockopt_minttl(peer
->su
.sa
.sa_family
,
6702 peer
->doppelganger
->fd
,
6712 * If peer clear is invoked in a loop for all peers on the BGP instance,
6713 * it may end up freeing the doppelganger, and if this was the next node
6714 * to the current node, we would end up accessing the freed next node.
6715 * Pass along additional parameter which can be updated if next node
6716 * is freed; only required when walking the peer list on BGP instance.
6718 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6720 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6721 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6722 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6723 if (peer
->t_pmax_restart
) {
6724 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6725 if (bgp_debug_neighbor_events(peer
))
6727 "%s Maximum-prefix restart timer canceled",
6730 BGP_EVENT_ADD(peer
, BGP_Start
);
6734 peer
->v_start
= BGP_INIT_START_TIMER
;
6735 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6736 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6737 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6739 bgp_session_reset_safe(peer
, nnode
);
6744 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6745 enum bgp_clear_type stype
)
6747 struct peer_af
*paf
;
6749 if (peer
->status
!= Established
)
6752 if (!peer
->afc
[afi
][safi
])
6753 return BGP_ERR_AF_UNCONFIGURED
;
6755 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6757 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6758 /* Clear the "neighbor x.x.x.x default-originate" flag */
6759 paf
= peer_af_find(peer
, afi
, safi
);
6760 if (paf
&& paf
->subgroup
6761 && CHECK_FLAG(paf
->subgroup
->sflags
,
6762 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6763 UNSET_FLAG(paf
->subgroup
->sflags
,
6764 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6766 bgp_announce_route(peer
, afi
, safi
);
6769 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6770 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6771 PEER_CAP_ORF_PREFIX_SM_ADV
)
6772 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6773 PEER_CAP_ORF_PREFIX_RM_RCV
)
6774 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6775 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6776 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6777 uint8_t prefix_type
;
6779 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6780 PEER_CAP_ORF_PREFIX_RM_RCV
))
6781 prefix_type
= ORF_TYPE_PREFIX
;
6783 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6785 if (filter
->plist
[FILTER_IN
].plist
) {
6786 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6787 PEER_STATUS_ORF_PREFIX_SEND
))
6788 bgp_route_refresh_send(
6789 peer
, afi
, safi
, prefix_type
,
6791 bgp_route_refresh_send(peer
, afi
, safi
,
6793 REFRESH_IMMEDIATE
, 0);
6795 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6796 PEER_STATUS_ORF_PREFIX_SEND
))
6797 bgp_route_refresh_send(
6798 peer
, afi
, safi
, prefix_type
,
6799 REFRESH_IMMEDIATE
, 1);
6801 bgp_route_refresh_send(peer
, afi
, safi
,
6808 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6809 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6810 /* If neighbor has soft reconfiguration inbound flag.
6811 Use Adj-RIB-In database. */
6812 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6813 PEER_FLAG_SOFT_RECONFIG
))
6814 bgp_soft_reconfig_in(peer
, afi
, safi
);
6816 /* If neighbor has route refresh capability, send route
6818 message to the peer. */
6819 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6820 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6821 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6824 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6830 /* Display peer uptime.*/
6831 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6834 time_t uptime1
, epoch_tbuf
;
6837 /* If there is no connection has been done before print `never'. */
6840 json_object_string_add(json
, "peerUptime", "never");
6841 json_object_int_add(json
, "peerUptimeMsec", 0);
6843 snprintf(buf
, len
, "never");
6847 /* Get current time. */
6848 uptime1
= bgp_clock();
6850 tm
= gmtime(&uptime1
);
6852 if (uptime1
< ONE_DAY_SECOND
)
6853 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6855 else if (uptime1
< ONE_WEEK_SECOND
)
6856 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6858 else if (uptime1
< ONE_YEAR_SECOND
)
6859 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6860 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6862 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6864 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6867 epoch_tbuf
= time(NULL
) - uptime1
;
6868 json_object_string_add(json
, "peerUptime", buf
);
6869 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6870 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6877 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6878 afi_t afi
, safi_t safi
)
6880 struct bgp_filter
*filter
;
6884 filter
= &peer
->filter
[afi
][safi
];
6886 /* distribute-list. */
6887 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6889 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6890 filter
->dlist
[FILTER_IN
].name
);
6892 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6894 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6895 filter
->dlist
[FILTER_OUT
].name
);
6898 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6900 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6901 filter
->plist
[FILTER_IN
].name
);
6903 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6905 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6906 filter
->plist
[FILTER_OUT
].name
);
6909 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6910 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6911 filter
->map
[RMAP_IN
].name
);
6913 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6915 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6916 filter
->map
[RMAP_OUT
].name
);
6918 /* unsuppress-map */
6919 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6920 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6921 filter
->usmap
.name
);
6924 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6926 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6927 filter
->aslist
[FILTER_IN
].name
);
6929 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6931 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6932 filter
->aslist
[FILTER_OUT
].name
);
6935 /* BGP peer configuration display function. */
6936 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6939 struct peer
*g_peer
= NULL
;
6940 char buf
[SU_ADDRSTRLEN
];
6942 int if_pg_printed
= false;
6943 int if_ras_printed
= false;
6945 /* Skip dynamic neighbors. */
6946 if (peer_dynamic_neighbor(peer
))
6950 addr
= peer
->conf_if
;
6954 /************************************
6955 ****** Global to the neighbor ******
6956 ************************************/
6957 if (peer
->conf_if
) {
6958 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6959 vty_out(vty
, " neighbor %s interface v6only", addr
);
6961 vty_out(vty
, " neighbor %s interface", addr
);
6963 if (peer_group_active(peer
)) {
6964 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6965 if_pg_printed
= true;
6966 } else if (peer
->as_type
== AS_SPECIFIED
) {
6967 vty_out(vty
, " remote-as %u", peer
->as
);
6968 if_ras_printed
= true;
6969 } else if (peer
->as_type
== AS_INTERNAL
) {
6970 vty_out(vty
, " remote-as internal");
6971 if_ras_printed
= true;
6972 } else if (peer
->as_type
== AS_EXTERNAL
) {
6973 vty_out(vty
, " remote-as external");
6974 if_ras_printed
= true;
6980 /* remote-as and peer-group */
6981 /* peer is a member of a peer-group */
6982 if (peer_group_active(peer
)) {
6983 g_peer
= peer
->group
->conf
;
6985 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6986 if (peer
->as_type
== AS_SPECIFIED
) {
6987 vty_out(vty
, " neighbor %s remote-as %u\n",
6989 } else if (peer
->as_type
== AS_INTERNAL
) {
6991 " neighbor %s remote-as internal\n",
6993 } else if (peer
->as_type
== AS_EXTERNAL
) {
6995 " neighbor %s remote-as external\n",
7000 /* For swpX peers we displayed the peer-group
7001 * via 'neighbor swpX interface peer-group PGNAME' */
7003 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
7007 /* peer is NOT a member of a peer-group */
7009 /* peer is a peer-group, declare the peer-group */
7010 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
7011 vty_out(vty
, " neighbor %s peer-group\n", addr
);
7014 if (!if_ras_printed
) {
7015 if (peer
->as_type
== AS_SPECIFIED
) {
7016 vty_out(vty
, " neighbor %s remote-as %u\n",
7018 } else if (peer
->as_type
== AS_INTERNAL
) {
7020 " neighbor %s remote-as internal\n",
7022 } else if (peer
->as_type
== AS_EXTERNAL
) {
7024 " neighbor %s remote-as external\n",
7031 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
7032 vty_out(vty
, " neighbor %s local-as %u", addr
,
7033 peer
->change_local_as
);
7034 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
7035 vty_out(vty
, " no-prepend");
7036 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
7037 vty_out(vty
, " replace-as");
7043 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
7047 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
7048 if (peer
->tx_shutdown_message
)
7049 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
7050 peer
->tx_shutdown_message
);
7052 vty_out(vty
, " neighbor %s shutdown\n", addr
);
7056 if (peer
->bfd_info
) {
7057 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
7058 bgp_bfd_peer_config_write(vty
, peer
, addr
);
7063 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
7064 vty_out(vty
, " neighbor %s password %s\n", addr
,
7068 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
7069 if (!peer_group_active(peer
)) {
7070 vty_out(vty
, " neighbor %s solo\n", addr
);
7075 if (peer
->port
!= BGP_PORT_DEFAULT
) {
7076 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
7079 /* Local interface name */
7081 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
7085 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
7086 vty_out(vty
, " neighbor %s passive\n", addr
);
7089 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
7090 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
7091 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
7092 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
7097 /* ttl-security hops */
7098 if (peer
->gtsm_hops
!= 0) {
7099 if (!peer_group_active(peer
)
7100 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
7101 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
7102 addr
, peer
->gtsm_hops
);
7106 /* disable-connected-check */
7107 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
7108 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
7110 /* enforce-first-as */
7111 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
7112 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
7115 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
7116 if (peer
->update_source
)
7117 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7118 sockunion2str(peer
->update_source
, buf
,
7120 else if (peer
->update_if
)
7121 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7125 /* advertisement-interval */
7126 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7127 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7131 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7132 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7133 peer
->keepalive
, peer
->holdtime
);
7135 /* timers connect */
7136 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7137 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7140 /* capability dynamic */
7141 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7142 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7144 /* capability extended-nexthop */
7145 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7146 if (!peer
->conf_if
) {
7147 if (CHECK_FLAG(peer
->flags_invert
,
7148 PEER_FLAG_CAPABILITY_ENHE
))
7150 " no neighbor %s capability extended-nexthop\n",
7154 " neighbor %s capability extended-nexthop\n",
7159 /* dont-capability-negotiation */
7160 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7161 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7163 /* override-capability */
7164 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7165 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7167 /* strict-capability-match */
7168 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7169 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7171 /* Sender side AS path loop detection. */
7172 if (peer
->as_path_loop_detection
)
7173 vty_out(vty
, " neighbor %s sender-as-path-loop-detection\n",
7177 /* BGP peer configuration display function. */
7178 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7179 struct peer
*peer
, afi_t afi
, safi_t safi
)
7181 struct peer
*g_peer
= NULL
;
7183 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7185 /* Skip dynamic neighbors. */
7186 if (peer_dynamic_neighbor(peer
))
7190 addr
= peer
->conf_if
;
7194 /************************************
7195 ****** Per AF to the neighbor ******
7196 ************************************/
7197 if (peer_group_active(peer
)) {
7198 g_peer
= peer
->group
->conf
;
7200 /* If the peer-group is active but peer is not, print a 'no
7202 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7203 vty_out(vty
, " no neighbor %s activate\n", addr
);
7206 /* If the peer-group is not active but peer is, print an
7208 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7209 vty_out(vty
, " neighbor %s activate\n", addr
);
7212 if (peer
->afc
[afi
][safi
]) {
7213 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7214 if (bgp_flag_check(bgp
,
7215 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7216 vty_out(vty
, " neighbor %s activate\n",
7220 vty_out(vty
, " neighbor %s activate\n", addr
);
7222 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7223 if (!bgp_flag_check(bgp
,
7224 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7226 " no neighbor %s activate\n",
7233 /* addpath TX knobs */
7234 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7235 switch (peer
->addpath_type
[afi
][safi
]) {
7236 case BGP_ADDPATH_ALL
:
7237 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7240 case BGP_ADDPATH_BEST_PER_AS
:
7242 " neighbor %s addpath-tx-bestpath-per-AS\n",
7245 case BGP_ADDPATH_MAX
:
7246 case BGP_ADDPATH_NONE
:
7251 /* ORF capability. */
7252 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7253 || peergroup_af_flag_check(peer
, afi
, safi
,
7254 PEER_FLAG_ORF_PREFIX_RM
)) {
7255 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7257 if (peergroup_af_flag_check(peer
, afi
, safi
,
7258 PEER_FLAG_ORF_PREFIX_SM
)
7259 && peergroup_af_flag_check(peer
, afi
, safi
,
7260 PEER_FLAG_ORF_PREFIX_RM
))
7261 vty_out(vty
, " both");
7262 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7263 PEER_FLAG_ORF_PREFIX_SM
))
7264 vty_out(vty
, " send");
7266 vty_out(vty
, " receive");
7270 /* Route reflector client. */
7271 if (peergroup_af_flag_check(peer
, afi
, safi
,
7272 PEER_FLAG_REFLECTOR_CLIENT
)) {
7273 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7276 /* next-hop-self force */
7277 if (peergroup_af_flag_check(peer
, afi
, safi
,
7278 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7279 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7283 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7284 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7287 /* remove-private-AS */
7288 if (peergroup_af_flag_check(peer
, afi
, safi
,
7289 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7290 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7294 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7295 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7296 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7300 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7301 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7302 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7305 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7306 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7307 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7311 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7312 vty_out(vty
, " neighbor %s as-override\n", addr
);
7315 /* send-community print. */
7316 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7317 PEER_FLAG_SEND_COMMUNITY
);
7318 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7319 PEER_FLAG_SEND_EXT_COMMUNITY
);
7320 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7321 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7323 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7324 vty_out(vty
, " no neighbor %s send-community all\n", addr
);
7327 vty_out(vty
, " no neighbor %s send-community\n", addr
);
7330 " no neighbor %s send-community extended\n",
7334 vty_out(vty
, " no neighbor %s send-community large\n",
7338 /* Default information */
7339 if (peergroup_af_flag_check(peer
, afi
, safi
,
7340 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7341 vty_out(vty
, " neighbor %s default-originate", addr
);
7343 if (peer
->default_rmap
[afi
][safi
].name
)
7344 vty_out(vty
, " route-map %s",
7345 peer
->default_rmap
[afi
][safi
].name
);
7350 /* Soft reconfiguration inbound. */
7351 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7352 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7356 /* maximum-prefix. */
7357 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7358 vty_out(vty
, " neighbor %s maximum-prefix %" PRIu32
, addr
,
7359 peer
->pmax
[afi
][safi
]);
7361 if (peer
->pmax_threshold
[afi
][safi
]
7362 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7363 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7364 if (peer_af_flag_check(peer
, afi
, safi
,
7365 PEER_FLAG_MAX_PREFIX_WARNING
))
7366 vty_out(vty
, " warning-only");
7367 if (peer
->pmax_restart
[afi
][safi
])
7368 vty_out(vty
, " restart %u",
7369 peer
->pmax_restart
[afi
][safi
]);
7374 /* Route server client. */
7375 if (peergroup_af_flag_check(peer
, afi
, safi
,
7376 PEER_FLAG_RSERVER_CLIENT
)) {
7377 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7380 /* Nexthop-local unchanged. */
7381 if (peergroup_af_flag_check(peer
, afi
, safi
,
7382 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7383 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7386 /* allowas-in <1-10> */
7387 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7388 if (peer_af_flag_check(peer
, afi
, safi
,
7389 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7390 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7391 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7392 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7394 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7395 peer
->allowas_in
[afi
][safi
]);
7400 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7401 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7402 peer
->weight
[afi
][safi
]);
7405 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7407 /* atribute-unchanged. */
7408 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7409 || (safi
!= SAFI_EVPN
7410 && peer_af_flag_check(peer
, afi
, safi
,
7411 PEER_FLAG_NEXTHOP_UNCHANGED
))
7412 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7414 if (!peer_group_active(peer
)
7415 || peergroup_af_flag_check(peer
, afi
, safi
,
7416 PEER_FLAG_AS_PATH_UNCHANGED
)
7417 || peergroup_af_flag_check(peer
, afi
, safi
,
7418 PEER_FLAG_NEXTHOP_UNCHANGED
)
7419 || peergroup_af_flag_check(peer
, afi
, safi
,
7420 PEER_FLAG_MED_UNCHANGED
)) {
7423 " neighbor %s attribute-unchanged%s%s%s\n",
7425 peer_af_flag_check(peer
, afi
, safi
,
7426 PEER_FLAG_AS_PATH_UNCHANGED
)
7429 peer_af_flag_check(peer
, afi
, safi
,
7430 PEER_FLAG_NEXTHOP_UNCHANGED
)
7433 peer_af_flag_check(peer
, afi
, safi
,
7434 PEER_FLAG_MED_UNCHANGED
)
7441 /* Address family based peer configuration display. */
7442 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7446 struct peer_group
*group
;
7447 struct listnode
*node
, *nnode
;
7450 vty_frame(vty
, " !\n address-family ");
7451 if (afi
== AFI_IP
) {
7452 if (safi
== SAFI_UNICAST
)
7453 vty_frame(vty
, "ipv4 unicast");
7454 else if (safi
== SAFI_LABELED_UNICAST
)
7455 vty_frame(vty
, "ipv4 labeled-unicast");
7456 else if (safi
== SAFI_MULTICAST
)
7457 vty_frame(vty
, "ipv4 multicast");
7458 else if (safi
== SAFI_MPLS_VPN
)
7459 vty_frame(vty
, "ipv4 vpn");
7460 else if (safi
== SAFI_ENCAP
)
7461 vty_frame(vty
, "ipv4 encap");
7462 else if (safi
== SAFI_FLOWSPEC
)
7463 vty_frame(vty
, "ipv4 flowspec");
7464 } else if (afi
== AFI_IP6
) {
7465 if (safi
== SAFI_UNICAST
)
7466 vty_frame(vty
, "ipv6 unicast");
7467 else if (safi
== SAFI_LABELED_UNICAST
)
7468 vty_frame(vty
, "ipv6 labeled-unicast");
7469 else if (safi
== SAFI_MULTICAST
)
7470 vty_frame(vty
, "ipv6 multicast");
7471 else if (safi
== SAFI_MPLS_VPN
)
7472 vty_frame(vty
, "ipv6 vpn");
7473 else if (safi
== SAFI_ENCAP
)
7474 vty_frame(vty
, "ipv6 encap");
7475 else if (safi
== SAFI_FLOWSPEC
)
7476 vty_frame(vty
, "ipv6 flowspec");
7477 } else if (afi
== AFI_L2VPN
) {
7478 if (safi
== SAFI_EVPN
)
7479 vty_frame(vty
, "l2vpn evpn");
7481 vty_frame(vty
, "\n");
7483 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7485 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7487 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7489 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7490 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7492 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7493 /* Skip dynamic neighbors. */
7494 if (peer_dynamic_neighbor(peer
))
7497 /* Do not display doppelganger peers */
7498 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7499 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7502 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7503 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7505 if (safi
== SAFI_EVPN
)
7506 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7508 if (safi
== SAFI_FLOWSPEC
)
7509 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7511 if (safi
== SAFI_UNICAST
) {
7512 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7513 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7514 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7516 vty_out(vty
, " export vpn\n");
7518 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7519 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7521 vty_out(vty
, " import vpn\n");
7523 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7524 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7527 for (ALL_LIST_ELEMENTS_RO(
7528 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7530 vty_out(vty
, " import vrf %s\n", name
);
7534 vty_endframe(vty
, " exit-address-family\n");
7537 int bgp_config_write(struct vty
*vty
)
7540 struct peer_group
*group
;
7542 struct listnode
*node
, *nnode
;
7543 struct listnode
*mnode
, *mnnode
;
7545 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7546 vty_out(vty
, "bgp route-map delay-timer %u\n",
7547 bm
->rmap_update_timer
);
7549 /* BGP configuration. */
7550 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7552 /* skip all auto created vrf as they dont have user config */
7553 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7556 /* Router bgp ASN */
7557 vty_out(vty
, "router bgp %u", bgp
->as
);
7560 vty_out(vty
, " %s %s",
7561 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
)
7562 ? "view" : "vrf", bgp
->name
);
7565 /* BGP fast-external-failover. */
7566 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7567 vty_out(vty
, " no bgp fast-external-failover\n");
7569 /* BGP router ID. */
7570 if (bgp
->router_id_static
.s_addr
!= 0)
7571 vty_out(vty
, " bgp router-id %s\n",
7572 inet_ntoa(bgp
->router_id_static
));
7574 /* BGP log-neighbor-changes. */
7575 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7576 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7577 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7579 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7583 /* BGP configuration. */
7584 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7585 vty_out(vty
, " bgp always-compare-med\n");
7587 /* RFC8212 default eBGP policy. */
7588 if (bgp
->ebgp_requires_policy
7589 == DEFAULT_EBGP_POLICY_ENABLED
)
7590 vty_out(vty
, " bgp ebgp-requires-policy\n");
7592 /* draft-ietf-idr-deprecate-as-set-confed-set */
7593 if (bgp
->reject_as_sets
== BGP_REJECT_AS_SETS_ENABLED
)
7594 vty_out(vty
, " bgp reject-as-sets\n");
7596 /* BGP default ipv4-unicast. */
7597 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7598 vty_out(vty
, " no bgp default ipv4-unicast\n");
7600 /* BGP default local-preference. */
7601 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7602 vty_out(vty
, " bgp default local-preference %u\n",
7603 bgp
->default_local_pref
);
7605 /* BGP default show-hostname */
7606 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7607 != DFLT_BGP_SHOW_HOSTNAME
)
7608 vty_out(vty
, " %sbgp default show-hostname\n",
7609 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7613 /* BGP default subgroup-pkt-queue-max. */
7614 if (bgp
->default_subgroup_pkt_queue_max
7615 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7616 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7617 bgp
->default_subgroup_pkt_queue_max
);
7619 /* BGP client-to-client reflection. */
7620 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7621 vty_out(vty
, " no bgp client-to-client reflection\n");
7623 /* BGP cluster ID. */
7624 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7625 vty_out(vty
, " bgp cluster-id %s\n",
7626 inet_ntoa(bgp
->cluster_id
));
7628 /* Disable ebgp connected nexthop check */
7629 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7631 " bgp disable-ebgp-connected-route-check\n");
7633 /* Confederation identifier*/
7634 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7635 vty_out(vty
, " bgp confederation identifier %u\n",
7638 /* Confederation peer */
7639 if (bgp
->confed_peers_cnt
> 0) {
7642 vty_out(vty
, " bgp confederation peers");
7644 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7645 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7650 /* BGP deterministic-med. */
7651 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7652 != DFLT_BGP_DETERMINISTIC_MED
)
7653 vty_out(vty
, " %sbgp deterministic-med\n",
7654 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7658 /* BGP update-delay. */
7659 bgp_config_write_update_delay(vty
, bgp
);
7661 if (bgp
->v_maxmed_onstartup
7662 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7663 vty_out(vty
, " bgp max-med on-startup %u",
7664 bgp
->v_maxmed_onstartup
);
7665 if (bgp
->maxmed_onstartup_value
7666 != BGP_MAXMED_VALUE_DEFAULT
)
7668 bgp
->maxmed_onstartup_value
);
7671 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7672 vty_out(vty
, " bgp max-med administrative");
7673 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7674 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7679 bgp_config_write_wpkt_quanta(vty
, bgp
);
7681 bgp_config_write_rpkt_quanta(vty
, bgp
);
7684 bgp_config_write_coalesce_time(vty
, bgp
);
7686 /* BGP graceful-restart. */
7687 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7689 " bgp graceful-restart stalepath-time %u\n",
7690 bgp
->stalepath_time
);
7691 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7692 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7694 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7695 vty_out(vty
, " bgp graceful-restart\n");
7697 /* BGP graceful-shutdown */
7698 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7699 vty_out(vty
, " bgp graceful-shutdown\n");
7701 /* BGP graceful-restart Preserve State F bit. */
7702 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7704 " bgp graceful-restart preserve-fw-state\n");
7706 /* BGP bestpath method. */
7707 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7708 vty_out(vty
, " bgp bestpath as-path ignore\n");
7709 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7710 vty_out(vty
, " bgp bestpath as-path confed\n");
7712 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7713 if (bgp_flag_check(bgp
,
7714 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7716 " bgp bestpath as-path multipath-relax as-set\n");
7719 " bgp bestpath as-path multipath-relax\n");
7723 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7725 " bgp route-reflector allow-outbound-policy\n");
7727 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7728 vty_out(vty
, " bgp bestpath compare-routerid\n");
7729 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7730 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7731 vty_out(vty
, " bgp bestpath med");
7732 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7733 vty_out(vty
, " confed");
7734 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7735 vty_out(vty
, " missing-as-worst");
7739 /* BGP network import check. */
7740 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7741 != DFLT_BGP_IMPORT_CHECK
)
7742 vty_out(vty
, " %sbgp network import-check\n",
7743 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7747 /* BGP flag dampening. */
7748 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7749 BGP_CONFIG_DAMPENING
))
7750 bgp_config_write_damp(vty
);
7752 /* BGP timers configuration. */
7753 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7754 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7755 vty_out(vty
, " timers bgp %u %u\n",
7756 bgp
->default_keepalive
, bgp
->default_holdtime
);
7759 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7760 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7763 /* Normal neighbor configuration. */
7764 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7765 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7766 bgp_config_write_peer_global(vty
, bgp
, peer
);
7769 /* listen range and limit for dynamic BGP neighbors */
7770 bgp_config_write_listen(vty
, bgp
);
7773 * BGP default autoshutdown neighbors
7775 * This must be placed after any peer and peer-group
7776 * configuration, to avoid setting all peers to shutdown after
7777 * a daemon restart, which is undesired behavior. (see #2286)
7779 if (bgp
->autoshutdown
)
7780 vty_out(vty
, " bgp default shutdown\n");
7782 /* IPv4 unicast configuration. */
7783 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7785 /* IPv4 multicast configuration. */
7786 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7788 /* IPv4 labeled-unicast configuration. */
7789 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7791 /* IPv4 VPN configuration. */
7792 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7794 /* ENCAPv4 configuration. */
7795 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7797 /* FLOWSPEC v4 configuration. */
7798 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7800 /* IPv6 unicast configuration. */
7801 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7803 /* IPv6 multicast configuration. */
7804 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7806 /* IPv6 labeled-unicast configuration. */
7807 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7808 SAFI_LABELED_UNICAST
);
7810 /* IPv6 VPN configuration. */
7811 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7813 /* ENCAPv6 configuration. */
7814 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7816 /* FLOWSPEC v6 configuration. */
7817 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7819 /* EVPN configuration. */
7820 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7822 hook_call(bgp_inst_config_write
, bgp
, vty
);
7825 bgp_rfapi_cfg_write(vty
, bgp
);
7828 vty_out(vty
, "!\n");
7833 void bgp_master_init(struct thread_master
*master
, const int buffer_size
)
7837 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7840 bm
->bgp
= list_new();
7841 bm
->listen_sockets
= list_new();
7842 bm
->port
= BGP_PORT_DEFAULT
;
7843 bm
->master
= master
;
7844 bm
->start_time
= bgp_clock();
7845 bm
->t_rmap_update
= NULL
;
7846 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7847 bm
->terminating
= false;
7848 bm
->socket_buffer
= buffer_size
;
7850 bgp_process_queue_init();
7853 /* init the rd id space.
7854 assign 0th index in the bitfield,
7855 so that we start with id 1
7857 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7858 bf_assign_zero_index(bm
->rd_idspace
);
7860 /* mpls label dynamic allocation pool */
7861 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7863 QOBJ_REG(bm
, bgp_master
);
7867 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7868 * instance delete (non-default only) or BGP exit.
7870 static void bgp_if_finish(struct bgp
*bgp
)
7873 struct interface
*ifp
;
7875 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
7877 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7880 FOR_ALL_INTERFACES (vrf
, ifp
) {
7881 struct listnode
*c_node
, *c_nnode
;
7882 struct connected
*c
;
7884 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7885 bgp_connected_delete(bgp
, c
);
7889 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7891 struct vrf
*vrf
= NULL
;
7892 struct listnode
*next
;
7895 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7896 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7898 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7899 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7902 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7906 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
7908 struct listnode
*next
, *next2
;
7909 struct bgp
*bgp
, *bgp2
;
7912 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7914 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
7915 if (bgp2
->as
== bgp
->as
)
7923 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
7924 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
7928 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7929 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7930 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
7931 {.completions
= NULL
},
7934 struct frr_pthread
*bgp_pth_io
;
7935 struct frr_pthread
*bgp_pth_ka
;
7937 static void bgp_pthreads_init(void)
7939 assert(!bgp_pth_io
);
7940 assert(!bgp_pth_ka
);
7942 struct frr_pthread_attr io
= {
7943 .start
= frr_pthread_attr_default
.start
,
7944 .stop
= frr_pthread_attr_default
.stop
,
7946 struct frr_pthread_attr ka
= {
7947 .start
= bgp_keepalives_start
,
7948 .stop
= bgp_keepalives_stop
,
7950 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7951 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7954 void bgp_pthreads_run(void)
7956 frr_pthread_run(bgp_pth_io
, NULL
);
7957 frr_pthread_run(bgp_pth_ka
, NULL
);
7959 /* Wait until threads are ready. */
7960 frr_pthread_wait_running(bgp_pth_io
);
7961 frr_pthread_wait_running(bgp_pth_ka
);
7964 void bgp_pthreads_finish(void)
7966 frr_pthread_stop_all();
7969 void bgp_init(unsigned short instance
)
7972 /* allocates some vital data structures used by peer commands in
7975 /* pre-init pthreads */
7976 bgp_pthreads_init();
7979 bgp_zebra_init(bm
->master
, instance
);
7982 vnc_zebra_init(bm
->master
);
7985 /* BGP VTY commands installation. */
7993 bgp_route_map_init();
7994 bgp_scan_vty_init();
7999 bgp_ethernetvpn_init();
8000 bgp_flowspec_vty_init();
8002 /* Access list initialize. */
8004 access_list_add_hook(peer_distribute_update
);
8005 access_list_delete_hook(peer_distribute_update
);
8007 /* Filter list initialize. */
8009 as_list_add_hook(peer_aslist_add
);
8010 as_list_delete_hook(peer_aslist_del
);
8012 /* Prefix list initialize.*/
8014 prefix_list_add_hook(peer_prefix_list_update
);
8015 prefix_list_delete_hook(peer_prefix_list_update
);
8017 /* Community list initialize. */
8018 bgp_clist
= community_list_init();
8023 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
8026 void bgp_terminate(void)
8030 struct listnode
*node
, *nnode
;
8031 struct listnode
*mnode
, *mnnode
;
8035 /* Close the listener sockets first as this prevents peers from
8037 * to reconnect on receiving the peer unconfig message. In the presence
8038 * of a large number of peers this will ensure that no peer is left with
8039 * a dangling connection
8041 /* reverse bgp_master_init */
8044 if (bm
->listen_sockets
)
8045 list_delete(&bm
->listen_sockets
);
8047 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
8048 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
8049 if (peer
->status
== Established
8050 || peer
->status
== OpenSent
8051 || peer
->status
== OpenConfirm
)
8052 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
8053 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
8055 if (bm
->process_main_queue
)
8056 work_queue_free_and_null(&bm
->process_main_queue
);
8058 if (bm
->t_rmap_update
)
8059 BGP_TIMER_OFF(bm
->t_rmap_update
);
8064 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
8065 const char *ip_str
, bool use_json
)
8071 /* Get peer sockunion. */
8072 ret
= str2sockunion(ip_str
, &su
);
8074 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
8076 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
8080 json_object
*json_no
= NULL
;
8081 json_no
= json_object_new_object();
8082 json_object_string_add(
8084 "malformedAddressOrName",
8086 vty_out(vty
, "%s\n",
8087 json_object_to_json_string_ext(
8089 JSON_C_TO_STRING_PRETTY
));
8090 json_object_free(json_no
);
8093 "%% Malformed address or name: %s\n",
8101 /* Peer structure lookup. */
8102 peer
= peer_lookup(bgp
, &su
);
8105 json_object
*json_no
= NULL
;
8106 json_no
= json_object_new_object();
8107 json_object_string_add(json_no
, "warning",
8108 "No such neighbor in this view/vrf");
8109 vty_out(vty
, "%s\n",
8110 json_object_to_json_string_ext(
8111 json_no
, JSON_C_TO_STRING_PRETTY
));
8112 json_object_free(json_no
);
8114 vty_out(vty
, "No such neighbor in this view/vrf\n");