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_community.h"
56 #include "bgpd/bgp_attr.h"
57 #include "bgpd/bgp_regex.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_fsm.h"
60 #include "bgpd/bgp_packet.h"
61 #include "bgpd/bgp_zebra.h"
62 #include "bgpd/bgp_open.h"
63 #include "bgpd/bgp_filter.h"
64 #include "bgpd/bgp_nexthop.h"
65 #include "bgpd/bgp_damp.h"
66 #include "bgpd/bgp_mplsvpn.h"
68 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
69 #include "bgpd/rfapi/rfapi_backend.h"
71 #include "bgpd/bgp_evpn.h"
72 #include "bgpd/bgp_advertise.h"
73 #include "bgpd/bgp_network.h"
74 #include "bgpd/bgp_vty.h"
75 #include "bgpd/bgp_mpath.h"
76 #include "bgpd/bgp_nht.h"
77 #include "bgpd/bgp_updgrp.h"
78 #include "bgpd/bgp_bfd.h"
79 #include "bgpd/bgp_memory.h"
80 #include "bgpd/bgp_evpn_vty.h"
81 #include "bgpd/bgp_keepalives.h"
82 #include "bgpd/bgp_io.h"
83 #include "bgpd/bgp_ecommunity.h"
84 #include "bgpd/bgp_flowspec.h"
85 #include "bgpd/bgp_labelpool.h"
86 #include "bgpd/bgp_pbr.h"
88 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
89 DEFINE_QOBJ_TYPE(bgp_master
)
91 DEFINE_QOBJ_TYPE(peer
)
93 /* BGP process wide configuration. */
94 static struct bgp_master bgp_master
;
96 /* BGP process wide configuration pointer to export. */
97 struct bgp_master
*bm
;
99 /* BGP community-list. */
100 struct community_list_handler
*bgp_clist
;
102 unsigned int multipath_num
= MULTIPATH_NUM
;
104 static void bgp_if_finish(struct bgp
*bgp
);
106 extern struct zclient
*zclient
;
108 /* handle main socket creation or deletion */
109 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
111 static int bgp_server_main_created
;
112 struct listnode
*bgpnode
, *nbgpnode
;
113 struct bgp
*bgp_temp
;
115 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
&&
116 vrf_is_mapped_on_netns(bgp
->vrf_id
))
118 if (create
== true) {
119 if (bgp_server_main_created
)
121 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
122 return BGP_ERR_INVALID_VALUE
;
123 bgp_server_main_created
= 1;
126 if (!bgp_server_main_created
)
128 /* only delete socket on some cases */
129 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp_temp
)) {
130 /* do not count with current bgp */
133 /* if other instance non VRF, do not delete socket */
134 if (bgp_temp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
136 /* vrf lite, do not delete socket */
137 if (!vrf_is_mapped_on_netns(bgp_temp
->vrf_id
))
141 bgp_server_main_created
= 0;
145 void bgp_session_reset(struct peer
*peer
)
147 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
148 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
149 peer_delete(peer
->doppelganger
);
151 BGP_EVENT_ADD(peer
, BGP_Stop
);
155 * During session reset, we may delete the doppelganger peer, which would
156 * be the next node to the current node. If the session reset was invoked
157 * during walk of peer list, we would end up accessing the freed next
158 * node. This function moves the next node along.
160 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
165 n
= (nnode
) ? *nnode
: NULL
;
166 npeer
= (n
) ? listgetdata(n
) : NULL
;
168 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
169 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
170 PEER_FLAG_CONFIG_NODE
))) {
171 if (peer
->doppelganger
== npeer
)
172 /* nnode and *nnode are confirmed to be non-NULL here */
173 *nnode
= (*nnode
)->next
;
174 peer_delete(peer
->doppelganger
);
177 BGP_EVENT_ADD(peer
, BGP_Stop
);
180 /* BGP global flag manipulation. */
181 int bgp_option_set(int flag
)
185 case BGP_OPT_MULTIPLE_INSTANCE
:
186 case BGP_OPT_CONFIG_CISCO
:
187 case BGP_OPT_NO_LISTEN
:
188 SET_FLAG(bm
->options
, flag
);
191 return BGP_ERR_INVALID_FLAG
;
196 int bgp_option_unset(int flag
)
199 case BGP_OPT_MULTIPLE_INSTANCE
:
200 if (listcount(bm
->bgp
) > 1)
201 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
204 case BGP_OPT_CONFIG_CISCO
:
205 UNSET_FLAG(bm
->options
, flag
);
208 return BGP_ERR_INVALID_FLAG
;
213 int bgp_option_check(int flag
)
215 return CHECK_FLAG(bm
->options
, flag
);
218 /* BGP flag manipulation. */
219 int bgp_flag_set(struct bgp
*bgp
, int flag
)
221 SET_FLAG(bgp
->flags
, flag
);
225 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
227 UNSET_FLAG(bgp
->flags
, flag
);
231 int bgp_flag_check(struct bgp
*bgp
, int flag
)
233 return CHECK_FLAG(bgp
->flags
, flag
);
236 /* Internal function to set BGP structure configureation flag. */
237 static void bgp_config_set(struct bgp
*bgp
, int config
)
239 SET_FLAG(bgp
->config
, config
);
242 static void bgp_config_unset(struct bgp
*bgp
, int config
)
244 UNSET_FLAG(bgp
->config
, config
);
247 static int bgp_config_check(struct bgp
*bgp
, int config
)
249 return CHECK_FLAG(bgp
->config
, config
);
252 /* Set BGP router identifier. */
253 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
256 struct listnode
*node
, *nnode
;
258 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
261 /* EVPN uses router id in RD, withdraw them */
262 if (is_evpn_enabled())
263 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
265 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
267 /* Set all peer's local identifier with this value. */
268 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
269 IPV4_ADDR_COPY(&peer
->local_id
, id
);
271 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
272 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
273 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
274 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
278 /* EVPN uses router id in RD, update them */
279 if (is_evpn_enabled())
280 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
285 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
287 struct listnode
*node
, *nnode
;
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
)
297 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
298 if (!bgp
->router_id_static
.s_addr
)
299 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
302 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
304 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
306 if (!bgp
->router_id_static
.s_addr
)
307 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
312 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
314 bgp
->router_id_static
= id
;
315 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
319 /* BGP's cluster-id control. */
320 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
323 struct listnode
*node
, *nnode
;
325 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
326 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
329 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
330 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
332 /* Clear all IBGP peer. */
333 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
334 if (peer
->sort
!= BGP_PEER_IBGP
)
337 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
338 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
339 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
340 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
346 int bgp_cluster_id_unset(struct bgp
*bgp
)
349 struct listnode
*node
, *nnode
;
351 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
354 bgp
->cluster_id
.s_addr
= 0;
355 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
357 /* Clear all IBGP peer. */
358 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
359 if (peer
->sort
!= BGP_PEER_IBGP
)
362 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
363 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
364 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
365 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
371 /* time_t value that is monotonicly increasing
372 * and uneffected by adjustments to system clock
374 time_t bgp_clock(void)
382 /* BGP timer configuration. */
383 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
385 bgp
->default_keepalive
=
386 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
387 bgp
->default_holdtime
= holdtime
;
392 int bgp_timers_unset(struct bgp
*bgp
)
394 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
395 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
400 /* BGP confederation configuration. */
401 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
404 struct listnode
*node
, *nnode
;
408 return BGP_ERR_INVALID_AS
;
410 /* Remember - were we doing confederation before? */
411 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
413 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
415 /* If we were doing confederation already, this is just an external
416 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
417 were not doing confederation before, reset all EBGP sessions. */
418 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
419 /* We're looking for peers who's AS is not local or part of our
421 if (already_confed
) {
422 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
424 if (BGP_IS_VALID_STATE_FOR_NOTIF(
427 PEER_DOWN_CONFED_ID_CHANGE
;
429 peer
, BGP_NOTIFY_CEASE
,
430 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
432 bgp_session_reset_safe(peer
, &nnode
);
435 /* Not doign confederation before, so reset every
438 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
439 /* Reset the local_as to be our EBGP one */
440 if (peer_sort(peer
) == BGP_PEER_EBGP
)
442 if (BGP_IS_VALID_STATE_FOR_NOTIF(
445 PEER_DOWN_CONFED_ID_CHANGE
;
447 peer
, BGP_NOTIFY_CEASE
,
448 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
450 bgp_session_reset_safe(peer
, &nnode
);
457 int bgp_confederation_id_unset(struct bgp
*bgp
)
460 struct listnode
*node
, *nnode
;
463 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
465 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
466 /* We're looking for peers who's AS is not local */
467 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
468 peer
->local_as
= bgp
->as
;
469 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
470 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
471 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
472 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
476 bgp_session_reset_safe(peer
, &nnode
);
482 /* Is an AS part of the confed or not? */
483 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
490 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
491 if (bgp
->confed_peers
[i
] == as
)
497 /* Add an AS to the confederation set. */
498 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
501 struct listnode
*node
, *nnode
;
504 return BGP_ERR_INVALID_BGP
;
507 return BGP_ERR_INVALID_AS
;
509 if (bgp_confederation_peers_check(bgp
, as
))
512 if (bgp
->confed_peers
)
514 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
515 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
518 XMALLOC(MTYPE_BGP_CONFED_LIST
,
519 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
521 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
522 bgp
->confed_peers_cnt
++;
524 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
525 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
526 if (peer
->as
== as
) {
527 peer
->local_as
= bgp
->as
;
528 if (BGP_IS_VALID_STATE_FOR_NOTIF(
531 PEER_DOWN_CONFED_PEER_CHANGE
;
533 peer
, BGP_NOTIFY_CEASE
,
534 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
536 bgp_session_reset_safe(peer
, &nnode
);
543 /* Delete an AS from the confederation set. */
544 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
549 struct listnode
*node
, *nnode
;
554 if (!bgp_confederation_peers_check(bgp
, as
))
557 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
558 if (bgp
->confed_peers
[i
] == as
)
559 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
560 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
562 bgp
->confed_peers_cnt
--;
564 if (bgp
->confed_peers_cnt
== 0) {
565 if (bgp
->confed_peers
)
566 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
567 bgp
->confed_peers
= NULL
;
570 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
571 bgp
->confed_peers_cnt
* sizeof(as_t
));
573 /* Now reset any peer who's remote AS has just been removed from the
575 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
576 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
577 if (peer
->as
== as
) {
578 peer
->local_as
= bgp
->confed_id
;
579 if (BGP_IS_VALID_STATE_FOR_NOTIF(
582 PEER_DOWN_CONFED_PEER_CHANGE
;
584 peer
, BGP_NOTIFY_CEASE
,
585 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
587 bgp_session_reset_safe(peer
, &nnode
);
595 /* Local preference configuration. */
596 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
601 bgp
->default_local_pref
= local_pref
;
606 int bgp_default_local_preference_unset(struct bgp
*bgp
)
611 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
616 /* Local preference configuration. */
617 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
622 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
627 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
631 bgp
->default_subgroup_pkt_queue_max
=
632 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
637 /* Listen limit configuration. */
638 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
643 bgp
->dynamic_neighbors_limit
= listen_limit
;
648 int bgp_listen_limit_unset(struct bgp
*bgp
)
653 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
658 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
659 afi_t
*afi
, safi_t
*safi
)
661 /* Map from IANA values to internal values, return error if
662 * values are unrecognized.
664 *afi
= afi_iana2int(pkt_afi
);
665 *safi
= safi_iana2int(pkt_safi
);
666 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
672 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
673 iana_safi_t
*pkt_safi
)
675 /* Map from internal values to IANA values, return error if
676 * internal values are bad (unexpected).
678 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
680 *pkt_afi
= afi_int2iana(afi
);
681 *pkt_safi
= safi_int2iana(safi
);
685 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
693 afid
= afindex(afi
, safi
);
694 if (afid
>= BGP_AF_MAX
)
697 assert(peer
->peer_af_array
[afid
] == NULL
);
699 /* Allocate new peer af */
700 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
703 zlog_err("Could not create af structure for peer %s",
708 peer
->peer_af_array
[afid
] = af
;
717 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
724 afid
= afindex(afi
, safi
);
725 if (afid
>= BGP_AF_MAX
)
728 return peer
->peer_af_array
[afid
];
731 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
739 afid
= afindex(afi
, safi
);
740 if (afid
>= BGP_AF_MAX
)
743 af
= peer
->peer_af_array
[afid
];
747 bgp_stop_announce_route_timer(af
);
749 if (PAF_SUBGRP(af
)) {
750 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
751 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
752 af
->subgroup
->update_group
->id
,
753 af
->subgroup
->id
, peer
->host
);
756 update_subgroup_remove_peer(af
->subgroup
, af
);
758 peer
->peer_af_array
[afid
] = NULL
;
759 XFREE(MTYPE_BGP_PEER_AF
, af
);
763 /* Peer comparison function for sorting. */
764 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
766 if (p1
->group
&& !p2
->group
)
769 if (!p1
->group
&& p2
->group
)
772 if (p1
->group
== p2
->group
) {
773 if (p1
->conf_if
&& !p2
->conf_if
)
776 if (!p1
->conf_if
&& p2
->conf_if
)
779 if (p1
->conf_if
&& p2
->conf_if
)
780 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
782 return strcmp(p1
->group
->name
, p2
->group
->name
);
784 return sockunion_cmp(&p1
->su
, &p2
->su
);
787 static unsigned int peer_hash_key_make(void *p
)
789 struct peer
*peer
= p
;
790 return sockunion_hash(&peer
->su
);
793 static int peer_hash_same(const void *p1
, const void *p2
)
795 const struct peer
*peer1
= p1
;
796 const struct peer
*peer2
= p2
;
797 return (sockunion_same(&peer1
->su
, &peer2
->su
)
798 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
799 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
802 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
804 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
807 /* Return true if flag is set for the peer but not the peer-group */
808 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
811 struct peer
*g_peer
= NULL
;
813 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
814 if (peer_group_active(peer
)) {
815 g_peer
= peer
->group
->conf
;
817 /* If this flag is not set for the peer's peer-group
818 * then return true */
819 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
824 /* peer is not in a peer-group but the flag is set to return
834 /* Reset all address family specific configuration. */
835 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
838 struct bgp_filter
*filter
;
839 char orf_name
[BUFSIZ
];
841 filter
= &peer
->filter
[afi
][safi
];
843 /* Clear neighbor filter and route-map */
844 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
845 if (filter
->dlist
[i
].name
) {
846 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
847 filter
->dlist
[i
].name
= NULL
;
849 if (filter
->plist
[i
].name
) {
850 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
851 filter
->plist
[i
].name
= NULL
;
853 if (filter
->aslist
[i
].name
) {
854 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
855 filter
->aslist
[i
].name
= NULL
;
858 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
859 if (filter
->map
[i
].name
) {
860 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
861 filter
->map
[i
].name
= NULL
;
865 /* Clear unsuppress map. */
866 if (filter
->usmap
.name
)
867 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
868 filter
->usmap
.name
= NULL
;
869 filter
->usmap
.map
= NULL
;
871 /* Clear neighbor's all address family flags. */
872 peer
->af_flags
[afi
][safi
] = 0;
874 /* Clear neighbor's all address family sflags. */
875 peer
->af_sflags
[afi
][safi
] = 0;
877 /* Clear neighbor's all address family capabilities. */
878 peer
->af_cap
[afi
][safi
] = 0;
881 peer
->orf_plist
[afi
][safi
] = NULL
;
882 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
883 prefix_bgp_orf_remove_all(afi
, orf_name
);
885 /* Set default neighbor send-community. */
886 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
887 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
888 SET_FLAG(peer
->af_flags
[afi
][safi
],
889 PEER_FLAG_SEND_EXT_COMMUNITY
);
890 SET_FLAG(peer
->af_flags
[afi
][safi
],
891 PEER_FLAG_SEND_LARGE_COMMUNITY
);
894 /* Clear neighbor default_originate_rmap */
895 if (peer
->default_rmap
[afi
][safi
].name
)
896 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
897 peer
->default_rmap
[afi
][safi
].name
= NULL
;
898 peer
->default_rmap
[afi
][safi
].map
= NULL
;
900 /* Clear neighbor maximum-prefix */
901 peer
->pmax
[afi
][safi
] = 0;
902 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
905 /* peer global config reset */
906 static void peer_global_config_reset(struct peer
*peer
)
910 peer
->change_local_as
= 0;
911 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
912 if (peer
->update_source
) {
913 sockunion_free(peer
->update_source
);
914 peer
->update_source
= NULL
;
916 if (peer
->update_if
) {
917 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
918 peer
->update_if
= NULL
;
921 if (peer_sort(peer
) == BGP_PEER_IBGP
)
922 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
924 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
926 /* These are per-peer specific flags and so we must preserve them */
927 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
928 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
);
930 SET_FLAG(peer
->flags
, saved_flags
);
936 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
938 /* Reset some other configs back to defaults. */
939 peer
->v_start
= BGP_INIT_START_TIMER
;
940 peer
->password
= NULL
;
941 peer
->local_id
= peer
->bgp
->router_id
;
942 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
943 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
945 bfd_info_free(&(peer
->bfd_info
));
947 /* Set back the CONFIG_NODE flag. */
948 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
951 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
952 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
959 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
960 if (peer
->as_type
== AS_INTERNAL
)
961 return BGP_PEER_IBGP
;
963 else if (peer
->as_type
== AS_EXTERNAL
)
964 return BGP_PEER_EBGP
;
966 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
967 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
972 peer1
= listnode_head(peer
->group
->peer
);
977 return BGP_PEER_INTERNAL
;
981 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
982 if (peer
->local_as
== 0)
983 return BGP_PEER_INTERNAL
;
985 if (peer
->local_as
== peer
->as
) {
986 if (bgp
->as
== bgp
->confed_id
) {
987 if (peer
->local_as
== bgp
->as
)
988 return BGP_PEER_IBGP
;
990 return BGP_PEER_EBGP
;
992 if (peer
->local_as
== bgp
->confed_id
)
993 return BGP_PEER_EBGP
;
995 return BGP_PEER_IBGP
;
999 if (bgp_confederation_peers_check(bgp
, peer
->as
))
1000 return BGP_PEER_CONFED
;
1002 return BGP_PEER_EBGP
;
1004 if (peer
->as_type
!= AS_SPECIFIED
)
1005 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1008 return (peer
->local_as
== 0
1010 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1015 /* Calculate and cache the peer "sort" */
1016 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1018 peer
->sort
= peer_calc_sort(peer
);
1022 static void peer_free(struct peer
*peer
)
1024 assert(peer
->status
== Deleted
);
1028 /* this /ought/ to have been done already through bgp_stop earlier,
1029 * but just to be sure..
1031 bgp_timer_set(peer
);
1032 bgp_reads_off(peer
);
1033 bgp_writes_off(peer
);
1034 assert(!peer
->t_write
);
1035 assert(!peer
->t_read
);
1036 BGP_EVENT_FLUSH(peer
);
1038 pthread_mutex_destroy(&peer
->io_mtx
);
1040 /* Free connected nexthop, if present */
1041 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1042 && !peer_dynamic_neighbor(peer
))
1043 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1046 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1049 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1053 /* Free allocated host character. */
1055 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1059 if (peer
->domainname
) {
1060 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1061 peer
->domainname
= NULL
;
1065 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1066 peer
->ifname
= NULL
;
1069 /* Update source configuration. */
1070 if (peer
->update_source
) {
1071 sockunion_free(peer
->update_source
);
1072 peer
->update_source
= NULL
;
1075 if (peer
->update_if
) {
1076 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1077 peer
->update_if
= NULL
;
1080 if (peer
->notify
.data
)
1081 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1082 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1084 if (peer
->clear_node_queue
)
1085 work_queue_free_and_null(&peer
->clear_node_queue
);
1087 bgp_sync_delete(peer
);
1089 if (peer
->conf_if
) {
1090 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1091 peer
->conf_if
= NULL
;
1094 bfd_info_free(&(peer
->bfd_info
));
1096 bgp_unlock(peer
->bgp
);
1098 memset(peer
, 0, sizeof(struct peer
));
1100 XFREE(MTYPE_BGP_PEER
, peer
);
1103 /* increase reference count on a struct peer */
1104 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1106 assert(peer
&& (peer
->lock
>= 0));
1109 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1117 /* decrease reference count on a struct peer
1118 * struct peer is freed and NULL returned if last reference
1120 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1122 assert(peer
&& (peer
->lock
> 0));
1125 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1130 if (peer
->lock
== 0) {
1138 /* Allocate new peer object, implicitely locked. */
1139 struct peer
*peer_new(struct bgp
*bgp
)
1146 /* bgp argument is absolutely required */
1151 /* Allocate new peer. */
1152 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1154 /* Set default value. */
1156 peer
->v_start
= BGP_INIT_START_TIMER
;
1157 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1158 peer
->status
= Idle
;
1159 peer
->ostatus
= Idle
;
1160 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1161 peer
->bgp
= bgp_lock(bgp
);
1162 peer
= peer_lock(peer
); /* initial reference */
1163 peer
->password
= NULL
;
1165 /* Set default flags. */
1166 FOREACH_AFI_SAFI (afi
, safi
) {
1167 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1168 SET_FLAG(peer
->af_flags
[afi
][safi
],
1169 PEER_FLAG_SEND_COMMUNITY
);
1170 SET_FLAG(peer
->af_flags
[afi
][safi
],
1171 PEER_FLAG_SEND_EXT_COMMUNITY
);
1172 SET_FLAG(peer
->af_flags
[afi
][safi
],
1173 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1175 peer
->orf_plist
[afi
][safi
] = NULL
;
1177 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1179 /* Create buffers. */
1180 peer
->ibuf
= stream_fifo_new();
1181 peer
->obuf
= stream_fifo_new();
1182 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1184 /* We use a larger buffer for peer->obuf_work in the event that:
1185 * - We RX a BGP_UPDATE where the attributes alone are just
1186 * under BGP_MAX_PACKET_SIZE
1187 * - The user configures an outbound route-map that does many as-path
1188 * prepends or adds many communities. At most they can have
1189 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1190 * large they can make the attributes.
1192 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1193 * bounds checking for every single attribute as we construct an
1197 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1199 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1201 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1203 bgp_sync_init(peer
);
1205 /* Get service port number. */
1206 sp
= getservbyname("bgp", "tcp");
1207 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1209 QOBJ_REG(peer
, peer
);
1214 * This function is invoked when a duplicate peer structure associated with
1215 * a neighbor is being deleted. If this about-to-be-deleted structure is
1216 * the one with all the config, then we have to copy over the info.
1218 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1220 struct peer_af
*paf
;
1228 /* The following function is used by both peer group config copy to
1229 * individual peer and when we transfer config
1231 if (peer_src
->change_local_as
)
1232 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1234 /* peer flags apply */
1235 peer_dst
->flags
= peer_src
->flags
;
1236 peer_dst
->cap
= peer_src
->cap
;
1237 peer_dst
->config
= peer_src
->config
;
1239 peer_dst
->local_as
= peer_src
->local_as
;
1240 peer_dst
->port
= peer_src
->port
;
1241 (void)peer_sort(peer_dst
);
1242 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1245 peer_dst
->holdtime
= peer_src
->holdtime
;
1246 peer_dst
->keepalive
= peer_src
->keepalive
;
1247 peer_dst
->connect
= peer_src
->connect
;
1248 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1249 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1250 peer_dst
->routeadv
= peer_src
->routeadv
;
1251 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1253 /* password apply */
1254 if (peer_src
->password
&& !peer_dst
->password
)
1255 peer_dst
->password
=
1256 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1258 FOREACH_AFI_SAFI (afi
, safi
) {
1259 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1260 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1261 peer_dst
->allowas_in
[afi
][safi
] =
1262 peer_src
->allowas_in
[afi
][safi
];
1263 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1266 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1267 paf
= peer_src
->peer_af_array
[afidx
];
1269 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1272 /* update-source apply */
1273 if (peer_src
->update_source
) {
1274 if (peer_dst
->update_source
)
1275 sockunion_free(peer_dst
->update_source
);
1276 if (peer_dst
->update_if
) {
1277 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1278 peer_dst
->update_if
= NULL
;
1280 peer_dst
->update_source
=
1281 sockunion_dup(peer_src
->update_source
);
1282 } else if (peer_src
->update_if
) {
1283 if (peer_dst
->update_if
)
1284 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1285 if (peer_dst
->update_source
) {
1286 sockunion_free(peer_dst
->update_source
);
1287 peer_dst
->update_source
= NULL
;
1289 peer_dst
->update_if
=
1290 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1293 if (peer_src
->ifname
) {
1294 if (peer_dst
->ifname
)
1295 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1298 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1302 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1303 struct interface
*ifp
)
1305 struct connected
*ifc
;
1308 struct listnode
*node
;
1310 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1311 * IPv4 address of the other end.
1313 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1314 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1315 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1316 if (p
.prefixlen
== 30) {
1317 peer
->su
.sa
.sa_family
= AF_INET
;
1318 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1320 peer
->su
.sin
.sin_addr
.s_addr
=
1322 else if (addr
% 4 == 2)
1323 peer
->su
.sin
.sin_addr
.s_addr
=
1325 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1326 peer
->su
.sin
.sin_len
=
1327 sizeof(struct sockaddr_in
);
1328 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1330 } else if (p
.prefixlen
== 31) {
1331 peer
->su
.sa
.sa_family
= AF_INET
;
1332 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1334 peer
->su
.sin
.sin_addr
.s_addr
=
1337 peer
->su
.sin
.sin_addr
.s_addr
=
1339 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1340 peer
->su
.sin
.sin_len
=
1341 sizeof(struct sockaddr_in
);
1342 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1344 } else if (bgp_debug_neighbor_events(peer
))
1346 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1354 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1355 struct interface
*ifp
)
1357 struct nbr_connected
*ifc_nbr
;
1359 /* Have we learnt the peer's IPv6 link-local address? */
1360 if (ifp
->nbr_connected
1361 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1362 peer
->su
.sa
.sa_family
= AF_INET6
;
1363 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1364 sizeof(struct in6_addr
));
1366 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1368 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1376 * Set or reset the peer address socketunion structure based on the
1377 * learnt/derived peer address. If the address has changed, update the
1378 * password on the listen socket, if needed.
1380 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1382 struct interface
*ifp
;
1384 int peer_addr_updated
= 0;
1389 prev_family
= peer
->su
.sa
.sa_family
;
1390 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1392 /* If BGP unnumbered is not "v6only", we first see if we can
1394 * peer's IPv4 address.
1396 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1398 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1400 /* If "v6only" or we can't derive peer's IPv4 address, see if
1402 * learnt the peer's IPv6 link-local address. This is from the
1404 * IPv6 address in router advertisement.
1406 if (!peer_addr_updated
)
1408 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1410 /* If we could derive the peer address, we may need to install the
1412 * configured for the peer, if any, on the listen socket. Otherwise,
1414 * that peer's address is not available and uninstall the password, if
1417 if (peer_addr_updated
) {
1418 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1421 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1422 bgp_md5_unset(peer
);
1423 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1424 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1427 /* Since our su changed we need to del/add peer to the peerhash */
1428 hash_release(peer
->bgp
->peerhash
, peer
);
1429 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1432 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1435 struct bgp_node
*rn
, *nrn
;
1437 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1438 rn
= bgp_route_next(rn
)) {
1439 if (rn
->info
!= NULL
) {
1440 /* Special handling for 2-level routing
1442 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1443 || safi
== SAFI_EVPN
) {
1444 for (nrn
= bgp_table_top(
1445 (struct bgp_table
*)(rn
->info
));
1446 nrn
; nrn
= bgp_route_next(nrn
))
1447 bgp_process(bgp
, nrn
, afi
, safi
);
1449 bgp_process(bgp
, rn
, afi
, safi
);
1454 /* Force a bestpath recalculation for all prefixes. This is used
1455 * when 'bgp bestpath' commands are entered.
1457 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1462 FOREACH_AFI_SAFI (afi
, safi
) {
1463 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1467 /* Create new BGP peer. */
1468 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1469 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1470 int as_type
, afi_t afi
, safi_t safi
,
1471 struct peer_group
*group
)
1475 char buf
[SU_ADDRSTRLEN
];
1477 peer
= peer_new(bgp
);
1479 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1480 bgp_peer_conf_if_to_su_update(peer
);
1482 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1483 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1486 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1488 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1489 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1491 peer
->local_as
= local_as
;
1492 peer
->as
= remote_as
;
1493 peer
->as_type
= as_type
;
1494 peer
->local_id
= bgp
->router_id
;
1495 peer
->v_holdtime
= bgp
->default_holdtime
;
1496 peer
->v_keepalive
= bgp
->default_keepalive
;
1497 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1498 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1500 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1502 peer
= peer_lock(peer
); /* bgp peer list reference */
1503 peer
->group
= group
;
1504 listnode_add_sort(bgp
->peer
, peer
);
1505 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1507 /* Adjust update-group coalesce timer heuristics for # peers. */
1508 if (bgp
->heuristic_coalesce
) {
1509 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1511 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1512 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1515 active
= peer_active(peer
);
1517 /* Last read and reset time set */
1518 peer
->readtime
= peer
->resettime
= bgp_clock();
1520 /* Default TTL set. */
1521 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1523 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1526 peer
->afc
[afi
][safi
] = 1;
1527 peer_af_create(peer
, afi
, safi
);
1530 /* auto shutdown if configured */
1531 if (bgp
->autoshutdown
)
1532 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1533 /* Set up peer's events and timers. */
1534 else if (!active
&& peer_active(peer
))
1535 bgp_timer_set(peer
);
1540 /* Make accept BGP peer. This function is only called from the test code */
1541 struct peer
*peer_create_accept(struct bgp
*bgp
)
1545 peer
= peer_new(bgp
);
1547 peer
= peer_lock(peer
); /* bgp peer list reference */
1548 listnode_add_sort(bgp
->peer
, peer
);
1554 * Return true if we have a peer configured to use this afi/safi
1556 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1558 struct listnode
*node
;
1561 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1562 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1565 if (peer
->afc
[afi
][safi
])
1572 /* Change peer's AS number. */
1573 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1575 bgp_peer_sort_t type
;
1579 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1580 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1581 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1582 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1583 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1585 bgp_session_reset(peer
);
1587 type
= peer_sort(peer
);
1589 peer
->as_type
= as_specified
;
1591 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1592 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1593 && peer
->bgp
->as
!= as
)
1594 peer
->local_as
= peer
->bgp
->confed_id
;
1596 peer
->local_as
= peer
->bgp
->as
;
1598 /* Advertisement-interval reset */
1601 conf
= peer
->group
->conf
;
1603 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1604 peer
->v_routeadv
= conf
->routeadv
;
1606 /* Only go back to the default advertisement-interval if the user had
1608 * already configured it */
1609 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1610 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1611 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1613 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1616 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1618 else if (type
== BGP_PEER_IBGP
)
1621 /* reflector-client reset */
1622 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1623 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1624 PEER_FLAG_REFLECTOR_CLIENT
);
1625 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1626 PEER_FLAG_REFLECTOR_CLIENT
);
1627 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1628 PEER_FLAG_REFLECTOR_CLIENT
);
1629 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1630 PEER_FLAG_REFLECTOR_CLIENT
);
1631 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1632 PEER_FLAG_REFLECTOR_CLIENT
);
1633 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1634 PEER_FLAG_REFLECTOR_CLIENT
);
1635 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1636 PEER_FLAG_REFLECTOR_CLIENT
);
1637 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1638 PEER_FLAG_REFLECTOR_CLIENT
);
1639 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1640 PEER_FLAG_REFLECTOR_CLIENT
);
1641 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1642 PEER_FLAG_REFLECTOR_CLIENT
);
1643 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1644 PEER_FLAG_REFLECTOR_CLIENT
);
1645 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1646 PEER_FLAG_REFLECTOR_CLIENT
);
1647 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1648 PEER_FLAG_REFLECTOR_CLIENT
);
1651 /* local-as reset */
1652 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1653 peer
->change_local_as
= 0;
1654 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1655 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1659 /* If peer does not exist, create new one. If peer already exists,
1660 set AS number to the peer. */
1661 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1662 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1668 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1670 peer
= peer_lookup(bgp
, su
);
1673 /* Not allowed for a dynamic peer. */
1674 if (peer_dynamic_neighbor(peer
)) {
1676 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1679 /* When this peer is a member of peer-group. */
1681 if (peer
->group
->conf
->as
) {
1682 /* Return peer group's AS number. */
1683 *as
= peer
->group
->conf
->as
;
1684 return BGP_ERR_PEER_GROUP_MEMBER
;
1686 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1687 if ((as_type
!= AS_INTERNAL
)
1688 && (bgp
->as
!= *as
)) {
1690 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1693 if ((as_type
!= AS_EXTERNAL
)
1694 && (bgp
->as
== *as
)) {
1696 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1701 /* Existing peer's AS number change. */
1702 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1703 || (peer
->as_type
!= as_type
))
1704 peer_as_change(peer
, *as
, as_type
);
1707 return BGP_ERR_NO_INTERFACE_CONFIG
;
1709 /* If the peer is not part of our confederation, and its not an
1710 iBGP peer then spoof the source AS */
1711 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1712 && !bgp_confederation_peers_check(bgp
, *as
)
1714 local_as
= bgp
->confed_id
;
1718 /* If this is IPv4 unicast configuration and "no bgp default
1719 ipv4-unicast" is specified. */
1721 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1722 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1723 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1726 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1733 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1734 struct peer
*peer
, afi_t afi
,
1738 int out
= FILTER_OUT
;
1740 struct bgp_filter
*pfilter
;
1741 struct bgp_filter
*gfilter
;
1744 pfilter
= &peer
->filter
[afi
][safi
];
1745 gfilter
= &conf
->filter
[afi
][safi
];
1747 /* peer af_flags apply */
1748 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1750 /* maximum-prefix */
1751 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1752 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1753 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1756 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1759 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1761 /* default-originate route-map */
1762 if (conf
->default_rmap
[afi
][safi
].name
) {
1763 if (peer
->default_rmap
[afi
][safi
].name
)
1764 XFREE(MTYPE_BGP_FILTER_NAME
,
1765 peer
->default_rmap
[afi
][safi
].name
);
1766 peer
->default_rmap
[afi
][safi
].name
=
1767 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1768 conf
->default_rmap
[afi
][safi
].name
);
1769 peer
->default_rmap
[afi
][safi
].map
=
1770 conf
->default_rmap
[afi
][safi
].map
;
1773 /* inbound filter apply */
1774 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1775 if (pfilter
->dlist
[in
].name
)
1776 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1777 pfilter
->dlist
[in
].name
=
1778 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1779 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1782 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1783 if (pfilter
->plist
[in
].name
)
1784 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1785 pfilter
->plist
[in
].name
=
1786 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1787 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1790 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1791 if (pfilter
->aslist
[in
].name
)
1792 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1793 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1794 gfilter
->aslist
[in
].name
);
1795 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1798 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1799 if (pfilter
->map
[RMAP_IN
].name
)
1800 XFREE(MTYPE_BGP_FILTER_NAME
,
1801 pfilter
->map
[RMAP_IN
].name
);
1802 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1803 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1804 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1807 /* outbound filter apply */
1808 if (gfilter
->dlist
[out
].name
) {
1809 if (pfilter
->dlist
[out
].name
)
1810 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1811 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1812 gfilter
->dlist
[out
].name
);
1813 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1815 if (pfilter
->dlist
[out
].name
)
1816 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1817 pfilter
->dlist
[out
].name
= NULL
;
1818 pfilter
->dlist
[out
].alist
= NULL
;
1821 if (gfilter
->plist
[out
].name
) {
1822 if (pfilter
->plist
[out
].name
)
1823 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1824 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1825 gfilter
->plist
[out
].name
);
1826 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1828 if (pfilter
->plist
[out
].name
)
1829 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1830 pfilter
->plist
[out
].name
= NULL
;
1831 pfilter
->plist
[out
].plist
= NULL
;
1834 if (gfilter
->aslist
[out
].name
) {
1835 if (pfilter
->aslist
[out
].name
)
1836 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1837 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1838 gfilter
->aslist
[out
].name
);
1839 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1841 if (pfilter
->aslist
[out
].name
)
1842 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1843 pfilter
->aslist
[out
].name
= NULL
;
1844 pfilter
->aslist
[out
].aslist
= NULL
;
1847 if (gfilter
->map
[RMAP_OUT
].name
) {
1848 if (pfilter
->map
[RMAP_OUT
].name
)
1849 XFREE(MTYPE_BGP_FILTER_NAME
,
1850 pfilter
->map
[RMAP_OUT
].name
);
1851 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1852 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1853 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1855 if (pfilter
->map
[RMAP_OUT
].name
)
1856 XFREE(MTYPE_BGP_FILTER_NAME
,
1857 pfilter
->map
[RMAP_OUT
].name
);
1858 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1859 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1862 if (gfilter
->usmap
.name
) {
1863 if (pfilter
->usmap
.name
)
1864 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1865 pfilter
->usmap
.name
=
1866 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1867 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1869 if (pfilter
->usmap
.name
)
1870 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1871 pfilter
->usmap
.name
= NULL
;
1872 pfilter
->usmap
.map
= NULL
;
1876 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1880 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1881 zlog_err("%s was called for peer-group %s", __func__
,
1886 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1888 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1889 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1890 return BGP_ERR_PEER_SAFI_CONFLICT
;
1892 /* Nothing to do if we've already activated this peer */
1893 if (peer
->afc
[afi
][safi
])
1896 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1899 active
= peer_active(peer
);
1900 peer
->afc
[afi
][safi
] = 1;
1903 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1905 if (!active
&& peer_active(peer
)) {
1906 bgp_timer_set(peer
);
1908 if (peer
->status
== Established
) {
1909 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1910 peer
->afc_adv
[afi
][safi
] = 1;
1911 bgp_capability_send(peer
, afi
, safi
,
1913 CAPABILITY_ACTION_SET
);
1914 if (peer
->afc_recv
[afi
][safi
]) {
1915 peer
->afc_nego
[afi
][safi
] = 1;
1916 bgp_announce_route(peer
, afi
, safi
);
1919 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1920 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1921 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1924 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1925 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1926 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1927 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1934 /* Activate the peer or peer group for specified AFI and SAFI. */
1935 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1938 struct peer_group
*group
;
1939 struct listnode
*node
, *nnode
;
1940 struct peer
*tmp_peer
;
1943 /* Nothing to do if we've already activated this peer */
1944 if (peer
->afc
[afi
][safi
])
1949 /* This is a peer-group so activate all of the members of the
1950 * peer-group as well */
1951 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1953 /* Do not activate a peer for both SAFI_UNICAST and
1954 * SAFI_LABELED_UNICAST */
1955 if ((safi
== SAFI_UNICAST
1956 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1957 || (safi
== SAFI_LABELED_UNICAST
1958 && peer
->afc
[afi
][SAFI_UNICAST
]))
1959 return BGP_ERR_PEER_SAFI_CONFLICT
;
1961 peer
->afc
[afi
][safi
] = 1;
1962 group
= peer
->group
;
1964 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1965 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1968 ret
|= peer_activate_af(peer
, afi
, safi
);
1971 /* If this is the first peer to be activated for this
1972 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1973 if (safi
== SAFI_LABELED_UNICAST
1974 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1976 if (BGP_DEBUG(zebra
, ZEBRA
))
1978 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1980 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1981 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1984 if (safi
== SAFI_FLOWSPEC
) {
1985 /* connect to table manager */
1986 bgp_zebra_init_tm_connect();
1991 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1994 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1995 zlog_err("%s was called for peer-group %s", __func__
,
2000 /* Nothing to do if we've already deactivated this peer */
2001 if (!peer
->afc
[afi
][safi
])
2004 /* De-activate the address family configuration. */
2005 peer
->afc
[afi
][safi
] = 0;
2007 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2008 zlog_err("couldn't delete af structure for peer %s",
2013 if (peer
->status
== Established
) {
2014 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2015 peer
->afc_adv
[afi
][safi
] = 0;
2016 peer
->afc_nego
[afi
][safi
] = 0;
2018 if (peer_active_nego(peer
)) {
2019 bgp_capability_send(peer
, afi
, safi
,
2021 CAPABILITY_ACTION_UNSET
);
2022 bgp_clear_route(peer
, afi
, safi
);
2023 peer
->pcount
[afi
][safi
] = 0;
2025 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2026 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2027 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2030 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2031 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2032 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2039 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2042 struct peer_group
*group
;
2043 struct peer
*tmp_peer
;
2044 struct listnode
*node
, *nnode
;
2047 /* Nothing to do if we've already de-activated this peer */
2048 if (!peer
->afc
[afi
][safi
])
2051 /* This is a peer-group so de-activate all of the members of the
2052 * peer-group as well */
2053 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2054 peer
->afc
[afi
][safi
] = 0;
2055 group
= peer
->group
;
2057 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2058 zlog_err("couldn't delete af structure for peer %s",
2062 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2063 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2066 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2071 /* If this is the last peer to be deactivated for this
2072 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2073 if (safi
== SAFI_LABELED_UNICAST
2074 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2075 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2077 if (BGP_DEBUG(zebra
, ZEBRA
))
2079 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2081 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2082 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2087 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2090 return peer_activate(peer
, afi
, safi
);
2092 return peer_deactivate(peer
, afi
, safi
);
2095 static void peer_nsf_stop(struct peer
*peer
)
2100 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2101 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2103 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2104 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2105 peer
->nsf
[afi
][safi
] = 0;
2107 if (peer
->t_gr_restart
) {
2108 BGP_TIMER_OFF(peer
->t_gr_restart
);
2109 if (bgp_debug_neighbor_events(peer
))
2110 zlog_debug("%s graceful restart timer stopped",
2113 if (peer
->t_gr_stale
) {
2114 BGP_TIMER_OFF(peer
->t_gr_stale
);
2115 if (bgp_debug_neighbor_events(peer
))
2117 "%s graceful restart stalepath timer stopped",
2120 bgp_clear_route_all(peer
);
2123 /* Delete peer from confguration.
2125 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2126 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2128 * This function /should/ take care to be idempotent, to guard against
2129 * it being called multiple times through stray events that come in
2130 * that happen to result in this function being called again. That
2131 * said, getting here for a "Deleted" peer is a bug in the neighbour
2134 int peer_delete(struct peer
*peer
)
2140 struct bgp_filter
*filter
;
2141 struct listnode
*pn
;
2144 assert(peer
->status
!= Deleted
);
2147 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2149 bgp_reads_off(peer
);
2150 bgp_writes_off(peer
);
2151 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2152 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2154 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2155 peer_nsf_stop(peer
);
2157 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2159 /* If this peer belongs to peer group, clear up the
2162 if (peer_dynamic_neighbor(peer
))
2163 peer_drop_dynamic_neighbor(peer
);
2165 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2167 peer
); /* group->peer list reference */
2168 list_delete_node(peer
->group
->peer
, pn
);
2173 /* Withdraw all information from routing table. We can not use
2174 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2175 * executed after peer structure is deleted.
2177 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2179 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2181 if (peer
->doppelganger
) {
2182 peer
->doppelganger
->doppelganger
= NULL
;
2183 peer
->doppelganger
= NULL
;
2186 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2187 bgp_fsm_change_status(peer
, Deleted
);
2189 /* Remove from NHT */
2190 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2191 bgp_unlink_nexthop_by_peer(peer
);
2193 /* Password configuration */
2194 if (peer
->password
) {
2195 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2196 peer
->password
= NULL
;
2198 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2199 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2200 bgp_md5_unset(peer
);
2203 bgp_timer_set(peer
); /* stops all timers for Deleted */
2205 /* Delete from all peer list. */
2206 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2207 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2208 peer_unlock(peer
); /* bgp peer list reference */
2209 list_delete_node(bgp
->peer
, pn
);
2210 hash_release(bgp
->peerhash
, peer
);
2215 stream_fifo_free(peer
->ibuf
);
2220 stream_fifo_free(peer
->obuf
);
2224 if (peer
->ibuf_work
) {
2225 ringbuf_del(peer
->ibuf_work
);
2226 peer
->ibuf_work
= NULL
;
2229 if (peer
->obuf_work
) {
2230 stream_free(peer
->obuf_work
);
2231 peer
->obuf_work
= NULL
;
2234 if (peer
->scratch
) {
2235 stream_free(peer
->scratch
);
2236 peer
->scratch
= NULL
;
2239 /* Local and remote addresses. */
2240 if (peer
->su_local
) {
2241 sockunion_free(peer
->su_local
);
2242 peer
->su_local
= NULL
;
2245 if (peer
->su_remote
) {
2246 sockunion_free(peer
->su_remote
);
2247 peer
->su_remote
= NULL
;
2250 /* Free filter related memory. */
2251 FOREACH_AFI_SAFI (afi
, safi
) {
2252 filter
= &peer
->filter
[afi
][safi
];
2254 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2255 if (filter
->dlist
[i
].name
) {
2256 XFREE(MTYPE_BGP_FILTER_NAME
,
2257 filter
->dlist
[i
].name
);
2258 filter
->dlist
[i
].name
= NULL
;
2261 if (filter
->plist
[i
].name
) {
2262 XFREE(MTYPE_BGP_FILTER_NAME
,
2263 filter
->plist
[i
].name
);
2264 filter
->plist
[i
].name
= NULL
;
2267 if (filter
->aslist
[i
].name
) {
2268 XFREE(MTYPE_BGP_FILTER_NAME
,
2269 filter
->aslist
[i
].name
);
2270 filter
->aslist
[i
].name
= NULL
;
2274 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2275 if (filter
->map
[i
].name
) {
2276 XFREE(MTYPE_BGP_FILTER_NAME
,
2277 filter
->map
[i
].name
);
2278 filter
->map
[i
].name
= NULL
;
2282 if (filter
->usmap
.name
) {
2283 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2284 filter
->usmap
.name
= NULL
;
2287 if (peer
->default_rmap
[afi
][safi
].name
) {
2288 XFREE(MTYPE_ROUTE_MAP_NAME
,
2289 peer
->default_rmap
[afi
][safi
].name
);
2290 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2294 FOREACH_AFI_SAFI (afi
, safi
)
2295 peer_af_delete(peer
, afi
, safi
);
2297 if (peer
->hostname
) {
2298 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2299 peer
->hostname
= NULL
;
2302 if (peer
->domainname
) {
2303 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2304 peer
->domainname
= NULL
;
2307 peer_unlock(peer
); /* initial reference */
2312 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2314 return strcmp(g1
->name
, g2
->name
);
2317 /* Peer group cofiguration. */
2318 static struct peer_group
*peer_group_new(void)
2320 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2321 sizeof(struct peer_group
));
2324 static void peer_group_free(struct peer_group
*group
)
2326 XFREE(MTYPE_PEER_GROUP
, group
);
2329 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2331 struct peer_group
*group
;
2332 struct listnode
*node
, *nnode
;
2334 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2335 if (strcmp(group
->name
, name
) == 0)
2341 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2343 struct peer_group
*group
;
2346 group
= peer_group_lookup(bgp
, name
);
2350 group
= peer_group_new();
2353 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2354 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2355 group
->peer
= list_new();
2356 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2357 group
->listen_range
[afi
] = list_new();
2358 group
->conf
= peer_new(bgp
);
2359 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2360 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2361 if (group
->conf
->host
)
2362 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2363 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2364 group
->conf
->group
= group
;
2365 group
->conf
->as
= 0;
2366 group
->conf
->ttl
= 1;
2367 group
->conf
->gtsm_hops
= 0;
2368 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2369 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2370 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2371 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2372 group
->conf
->keepalive
= 0;
2373 group
->conf
->holdtime
= 0;
2374 group
->conf
->connect
= 0;
2375 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2376 listnode_add_sort(bgp
->group
, group
);
2381 static void peer_group2peer_config_copy(struct peer_group
*group
,
2385 int saved_flags
= 0;
2391 peer
->as
= conf
->as
;
2394 if (conf
->change_local_as
)
2395 peer
->change_local_as
= conf
->change_local_as
;
2398 peer
->ttl
= conf
->ttl
;
2401 peer
->gtsm_hops
= conf
->gtsm_hops
;
2403 /* These are per-peer specific flags and so we must preserve them */
2404 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2405 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
);
2406 peer
->flags
= conf
->flags
;
2407 SET_FLAG(peer
->flags
, saved_flags
);
2409 /* peer config apply */
2410 peer
->config
= conf
->config
;
2412 /* peer timers apply */
2413 peer
->holdtime
= conf
->holdtime
;
2414 peer
->keepalive
= conf
->keepalive
;
2415 peer
->connect
= conf
->connect
;
2416 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2417 peer
->v_connect
= conf
->connect
;
2419 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2421 /* advertisement-interval reset */
2422 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2423 peer
->v_routeadv
= conf
->routeadv
;
2424 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2425 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2427 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2429 /* password apply */
2430 if (conf
->password
&& !peer
->password
)
2431 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2433 if (!BGP_PEER_SU_UNSPEC(peer
))
2436 /* update-source apply */
2437 if (conf
->update_source
) {
2438 if (peer
->update_source
)
2439 sockunion_free(peer
->update_source
);
2440 if (peer
->update_if
) {
2441 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2442 peer
->update_if
= NULL
;
2444 peer
->update_source
= sockunion_dup(conf
->update_source
);
2445 } else if (conf
->update_if
) {
2446 if (peer
->update_if
)
2447 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2448 if (peer
->update_source
) {
2449 sockunion_free(peer
->update_source
);
2450 peer
->update_source
= NULL
;
2453 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2456 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2459 /* Peer group's remote AS configuration. */
2460 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2463 struct peer_group
*group
;
2465 struct listnode
*node
, *nnode
;
2467 group
= peer_group_lookup(bgp
, group_name
);
2471 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2475 /* When we setup peer-group AS number all peer group member's AS
2476 number must be updated to same number. */
2477 peer_as_change(group
->conf
, *as
, as_type
);
2479 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2480 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2481 || (peer
->as_type
!= as_type
))
2482 peer_as_change(peer
, *as
, as_type
);
2488 int peer_group_delete(struct peer_group
*group
)
2492 struct prefix
*prefix
;
2494 struct listnode
*node
, *nnode
;
2499 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2500 other
= peer
->doppelganger
;
2502 if (other
&& other
->status
!= Deleted
) {
2503 other
->group
= NULL
;
2507 list_delete_and_null(&group
->peer
);
2509 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2510 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2512 prefix_free(prefix
);
2514 list_delete_and_null(&group
->listen_range
[afi
]);
2517 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2520 bfd_info_free(&(group
->conf
->bfd_info
));
2522 group
->conf
->group
= NULL
;
2523 peer_delete(group
->conf
);
2525 /* Delete from all peer_group list. */
2526 listnode_delete(bgp
->group
, group
);
2528 peer_group_free(group
);
2533 int peer_group_remote_as_delete(struct peer_group
*group
)
2535 struct peer
*peer
, *other
;
2536 struct listnode
*node
, *nnode
;
2538 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2539 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2542 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2543 other
= peer
->doppelganger
;
2547 if (other
&& other
->status
!= Deleted
) {
2548 other
->group
= NULL
;
2552 list_delete_all_node(group
->peer
);
2554 group
->conf
->as
= 0;
2555 group
->conf
->as_type
= AS_UNSPECIFIED
;
2560 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2562 struct prefix
*prefix
;
2563 struct listnode
*node
, *nnode
;
2566 afi
= family2afi(range
->family
);
2568 /* Group needs remote AS configured. */
2569 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2570 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2572 /* Ensure no duplicates. Currently we don't care about overlaps. */
2573 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2574 if (prefix_same(range
, prefix
))
2578 prefix
= prefix_new();
2579 prefix_copy(prefix
, range
);
2580 listnode_add(group
->listen_range
[afi
], prefix
);
2584 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2586 struct prefix
*prefix
, prefix2
;
2587 struct listnode
*node
, *nnode
;
2590 char buf
[PREFIX2STR_BUFFER
];
2592 afi
= family2afi(range
->family
);
2594 /* Identify the listen range. */
2595 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2596 if (prefix_same(range
, prefix
))
2601 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2603 prefix2str(prefix
, buf
, sizeof(buf
));
2605 /* Dispose off any dynamic neighbors that exist due to this listen range
2607 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2608 if (!peer_dynamic_neighbor(peer
))
2611 sockunion2hostprefix(&peer
->su
, &prefix2
);
2612 if (prefix_match(prefix
, &prefix2
)) {
2613 if (bgp_debug_neighbor_events(peer
))
2615 "Deleting dynamic neighbor %s group %s upon "
2616 "delete of listen range %s",
2617 peer
->host
, group
->name
, buf
);
2622 /* Get rid of the listen range */
2623 listnode_delete(group
->listen_range
[afi
], prefix
);
2628 /* Bind specified peer to peer group. */
2629 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2630 struct peer_group
*group
, as_t
*as
)
2632 int first_member
= 0;
2635 int cap_enhe_preset
= 0;
2637 /* Lookup the peer. */
2639 peer
= peer_lookup(bgp
, su
);
2641 /* The peer exist, bind it to the peer-group */
2643 /* When the peer already belongs to a peer-group, check the
2645 if (peer_group_active(peer
)) {
2647 /* The peer is already bound to the peer-group,
2650 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2653 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2656 /* The peer has not specified a remote-as, inherit it from the
2658 if (peer
->as_type
== AS_UNSPECIFIED
) {
2659 peer
->as_type
= group
->conf
->as_type
;
2660 peer
->as
= group
->conf
->as
;
2663 if (!group
->conf
->as
) {
2664 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2665 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2668 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2671 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2675 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2676 cap_enhe_preset
= 1;
2678 peer_group2peer_config_copy(group
, peer
);
2681 * Capability extended-nexthop is enabled for an interface
2683 * default. So, fix that up here.
2685 if (peer
->conf_if
&& cap_enhe_preset
)
2686 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2688 FOREACH_AFI_SAFI (afi
, safi
) {
2689 if (group
->conf
->afc
[afi
][safi
]) {
2690 peer
->afc
[afi
][safi
] = 1;
2692 if (peer_af_find(peer
, afi
, safi
)
2693 || peer_af_create(peer
, afi
, safi
)) {
2694 peer_group2peer_config_copy_af(
2695 group
, peer
, afi
, safi
);
2697 } else if (peer
->afc
[afi
][safi
])
2698 peer_deactivate(peer
, afi
, safi
);
2702 assert(group
&& peer
->group
== group
);
2704 struct listnode
*pn
;
2705 pn
= listnode_lookup(bgp
->peer
, peer
);
2706 list_delete_node(bgp
->peer
, pn
);
2707 peer
->group
= group
;
2708 listnode_add_sort(bgp
->peer
, peer
);
2710 peer
= peer_lock(peer
); /* group->peer list reference */
2711 listnode_add(group
->peer
, peer
);
2715 /* Advertisement-interval reset */
2716 if (!CHECK_FLAG(group
->conf
->config
,
2717 PEER_CONFIG_ROUTEADV
)) {
2718 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2719 group
->conf
->v_routeadv
=
2720 BGP_DEFAULT_IBGP_ROUTEADV
;
2722 group
->conf
->v_routeadv
=
2723 BGP_DEFAULT_EBGP_ROUTEADV
;
2726 /* ebgp-multihop reset */
2727 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2728 group
->conf
->ttl
= MAXTTL
;
2730 /* local-as reset */
2731 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2732 group
->conf
->change_local_as
= 0;
2733 UNSET_FLAG(peer
->flags
,
2734 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2735 UNSET_FLAG(peer
->flags
,
2736 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2740 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2742 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2743 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2744 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2745 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2747 bgp_session_reset(peer
);
2751 /* Create a new peer. */
2753 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2754 && (!group
->conf
->as
)) {
2755 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2758 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2759 group
->conf
->as_type
, 0, 0, group
);
2761 peer
= peer_lock(peer
); /* group->peer list reference */
2762 listnode_add(group
->peer
, peer
);
2764 peer_group2peer_config_copy(group
, peer
);
2766 /* If the peer-group is active for this afi/safi then activate
2768 FOREACH_AFI_SAFI (afi
, safi
) {
2769 if (group
->conf
->afc
[afi
][safi
]) {
2770 peer
->afc
[afi
][safi
] = 1;
2771 peer_af_create(peer
, afi
, safi
);
2772 peer_group2peer_config_copy_af(group
, peer
, afi
,
2774 } else if (peer
->afc
[afi
][safi
])
2775 peer_deactivate(peer
, afi
, safi
);
2778 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2780 /* Set up peer's events and timers. */
2781 if (peer_active(peer
))
2782 bgp_timer_set(peer
);
2788 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2789 struct peer_group
*group
)
2795 if (group
!= peer
->group
)
2796 return BGP_ERR_PEER_GROUP_MISMATCH
;
2798 FOREACH_AFI_SAFI (afi
, safi
) {
2799 if (peer
->afc
[afi
][safi
]) {
2800 peer
->afc
[afi
][safi
] = 0;
2801 peer_af_flag_reset(peer
, afi
, safi
);
2803 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2805 "couldn't delete af structure for peer %s",
2811 assert(listnode_lookup(group
->peer
, peer
));
2812 peer_unlock(peer
); /* peer group list reference */
2813 listnode_delete(group
->peer
, peer
);
2815 other
= peer
->doppelganger
;
2817 if (group
->conf
->as
) {
2819 if (other
&& other
->status
!= Deleted
) {
2822 listnode_delete(group
->peer
, other
);
2824 other
->group
= NULL
;
2830 bgp_bfd_deregister_peer(peer
);
2831 peer_global_config_reset(peer
);
2833 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2834 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2835 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2836 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2838 bgp_session_reset(peer
);
2843 static int bgp_startup_timer_expire(struct thread
*thread
)
2847 bgp
= THREAD_ARG(thread
);
2848 bgp
->t_startup
= NULL
;
2853 /* BGP instance creation by `router bgp' commands. */
2854 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2855 enum bgp_instance_type inst_type
)
2861 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2864 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2865 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2866 zlog_debug("Creating Default VRF, AS %u", *as
);
2868 zlog_debug("Creating %s %s, AS %u",
2869 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2876 bgp
->heuristic_coalesce
= true;
2877 bgp
->inst_type
= inst_type
;
2878 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2880 bgp
->peer_self
= peer_new(bgp
);
2881 if (bgp
->peer_self
->host
)
2882 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2883 bgp
->peer_self
->host
=
2884 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2885 if (bgp
->peer_self
->hostname
!= NULL
) {
2886 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2887 bgp
->peer_self
->hostname
= NULL
;
2889 if (cmd_hostname_get())
2890 bgp
->peer_self
->hostname
=
2891 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2893 if (bgp
->peer_self
->domainname
!= NULL
) {
2894 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2895 bgp
->peer_self
->domainname
= NULL
;
2897 if (cmd_domainname_get())
2898 bgp
->peer_self
->domainname
=
2899 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2900 bgp
->peer
= list_new();
2901 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2902 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2904 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2906 bgp
->group
= list_new();
2907 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2909 FOREACH_AFI_SAFI (afi
, safi
) {
2910 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2911 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2912 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2914 /* Enable maximum-paths */
2915 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2917 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2921 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2922 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2923 bgp
->default_subgroup_pkt_queue_max
=
2924 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2925 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2926 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2927 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2928 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2929 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2930 bgp
->dynamic_neighbors_count
= 0;
2931 #if DFLT_BGP_IMPORT_CHECK
2932 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2934 #if DFLT_BGP_SHOW_HOSTNAME
2935 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2937 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2938 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2940 #if DFLT_BGP_DETERMINISTIC_MED
2941 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2943 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2948 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2949 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2951 assert(bgp
->rfapi_cfg
);
2953 #endif /* ENABLE_BGP_VNC */
2955 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2956 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2957 bgp
->vpn_policy
[afi
].afi
= afi
;
2958 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2959 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2962 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2963 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2966 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2968 /* TODO - The startup timer needs to be run for the whole of BGP
2970 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2971 bgp
->restart_time
, &bgp
->t_startup
);
2974 /* printable name we can use in debug messages */
2975 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2976 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2986 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2988 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2989 snprintf(bgp
->name_pretty
, len
, "%s %s",
2990 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2996 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2997 memory_order_relaxed
);
2998 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2999 memory_order_relaxed
);
3000 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3004 update_bgp_group_init(bgp
);
3006 /* assign a unique rd id for auto derivation of vrf's RD */
3007 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3014 /* Return the "default VRF" instance of BGP. */
3015 struct bgp
*bgp_get_default(void)
3018 struct listnode
*node
, *nnode
;
3020 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3021 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3026 /* Lookup BGP entry. */
3027 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3030 struct listnode
*node
, *nnode
;
3032 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3034 && ((bgp
->name
== NULL
&& name
== NULL
)
3035 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3040 /* Lookup BGP structure by view name. */
3041 struct bgp
*bgp_lookup_by_name(const char *name
)
3044 struct listnode
*node
, *nnode
;
3046 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3047 if ((bgp
->name
== NULL
&& name
== NULL
)
3048 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3053 /* Lookup BGP instance based on VRF id. */
3054 /* Note: Only to be used for incoming messages from Zebra. */
3055 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3059 /* Lookup VRF (in tree) and follow link. */
3060 vrf
= vrf_lookup_by_id(vrf_id
);
3063 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3066 /* handle socket creation or deletion, if necessary
3067 * this is called for all new BGP instances
3069 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3074 /* Create BGP server socket, if listen mode not disabled */
3075 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3077 if (bgp
->name
&& bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
&& vrf
) {
3079 * suppress vrf socket
3081 if (create
== FALSE
) {
3082 if (vrf_is_mapped_on_netns(vrf
->vrf_id
))
3083 bgp_close_vrf_socket(bgp
);
3085 ret
= bgp_check_main_socket(create
, bgp
);
3089 * if vrf_id did not change
3091 if (vrf
->vrf_id
== old_vrf_id
)
3093 if (old_vrf_id
!= VRF_UNKNOWN
) {
3094 /* look for old socket. close it. */
3095 bgp_close_vrf_socket(bgp
);
3097 /* if backend is not yet identified ( VRF_UNKNOWN) then
3098 * creation will be done later
3100 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3102 /* if BGP VRF instance requested
3103 * if backend is NETNS, create BGP server socket in the NETNS
3105 if (vrf_is_mapped_on_netns(bgp
->vrf_id
)) {
3106 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3108 return BGP_ERR_INVALID_VALUE
;
3112 /* if BGP VRF instance requested or VRF lite backend
3113 * if BGP non VRF instance, create it
3114 * if not already done
3116 return bgp_check_main_socket(create
, bgp
);
3119 /* Called from VTY commands. */
3120 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3121 enum bgp_instance_type inst_type
)
3124 struct vrf
*vrf
= NULL
;
3126 /* Multiple instance check. */
3127 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3129 bgp
= bgp_lookup_by_name(name
);
3131 bgp
= bgp_get_default();
3133 /* Already exists. */
3135 if (bgp
->as
!= *as
) {
3137 return BGP_ERR_INSTANCE_MISMATCH
;
3139 if (bgp
->inst_type
!= inst_type
)
3140 return BGP_ERR_INSTANCE_MISMATCH
;
3145 /* BGP instance name can not be specified for single instance.
3148 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3150 /* Get default BGP structure if exists. */
3151 bgp
= bgp_get_default();
3154 if (bgp
->as
!= *as
) {
3156 return BGP_ERR_AS_MISMATCH
;
3163 bgp
= bgp_create(as
, name
, inst_type
);
3164 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3165 bgp_address_init(bgp
);
3166 bgp_tip_hash_init(bgp
);
3170 bgp
->t_rmap_def_originate_eval
= NULL
;
3172 /* If Default instance or VRF, link to the VRF structure, if present. */
3173 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3174 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3175 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3177 bgp_vrf_link(bgp
, vrf
);
3179 /* BGP server socket already processed if BGP instance
3180 * already part of the list
3182 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3183 listnode_add(bm
->bgp
, bgp
);
3185 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3186 bgp_zebra_instance_register(bgp
);
3193 * Make BGP instance "up". Applies only to VRFs (non-default) and
3194 * implies the VRF has been learnt from Zebra.
3196 void bgp_instance_up(struct bgp
*bgp
)
3199 struct listnode
*node
, *next
;
3201 /* Register with zebra. */
3202 bgp_zebra_instance_register(bgp
);
3204 /* Kick off any peers that may have been configured. */
3205 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3206 if (!BGP_PEER_START_SUPPRESSED(peer
))
3207 BGP_EVENT_ADD(peer
, BGP_Start
);
3210 /* Process any networks that have been configured. */
3211 bgp_static_add(bgp
);
3215 * Make BGP instance "down". Applies only to VRFs (non-default) and
3216 * implies the VRF has been deleted by Zebra.
3218 void bgp_instance_down(struct bgp
*bgp
)
3221 struct listnode
*node
;
3222 struct listnode
*next
;
3225 if (bgp
->t_rmap_def_originate_eval
) {
3226 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3227 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3231 /* Bring down peers, so corresponding routes are purged. */
3232 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3233 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3234 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3235 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3237 bgp_session_reset(peer
);
3240 /* Purge network and redistributed routes. */
3241 bgp_purge_static_redist_routes(bgp
);
3243 /* Cleanup registered nexthops (flags) */
3244 bgp_cleanup_nexthops(bgp
);
3247 /* Delete BGP instance. */
3248 int bgp_delete(struct bgp
*bgp
)
3251 struct peer_group
*group
;
3252 struct listnode
*node
, *next
;
3257 THREAD_OFF(bgp
->t_startup
);
3259 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3260 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3261 zlog_debug("Deleting Default VRF");
3263 zlog_debug("Deleting %s %s",
3264 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3270 /* unmap from RT list */
3271 bgp_evpn_vrf_delete(bgp
);
3274 if (bgp
->t_rmap_def_originate_eval
) {
3275 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3276 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3280 /* Inform peers we're going down. */
3281 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3282 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3283 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3284 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3287 /* Delete static routes (networks). */
3288 bgp_static_delete(bgp
);
3290 /* Unset redistribution. */
3291 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3292 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3293 if (i
!= ZEBRA_ROUTE_BGP
)
3294 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3296 /* Free peers and peer-groups. */
3297 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3298 peer_group_delete(group
);
3300 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3303 if (bgp
->peer_self
) {
3304 peer_delete(bgp
->peer_self
);
3305 bgp
->peer_self
= NULL
;
3308 update_bgp_group_free(bgp
);
3310 /* TODO - Other memory may need to be freed - e.g., NHT */
3315 bgp_cleanup_routes(bgp
);
3317 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3318 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3321 &bgp
->vpn_policy
[afi
]
3322 .import_redirect_rtlist
);
3323 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3325 /* Remove visibility via the master list - there may however still be
3326 * routes to be processed still referencing the struct bgp.
3328 listnode_delete(bm
->bgp
, bgp
);
3330 /* Deregister from Zebra, if needed */
3331 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3332 bgp_zebra_instance_deregister(bgp
);
3334 /* Free interfaces in this instance. */
3337 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3338 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3340 bgp_vrf_unlink(bgp
, vrf
);
3342 thread_master_free_unused(bm
->master
);
3343 bgp_unlock(bgp
); /* initial reference */
3348 void bgp_free(struct bgp
*bgp
)
3352 struct bgp_table
*table
;
3353 struct bgp_node
*rn
;
3354 struct bgp_rmap
*rmap
;
3358 list_delete_and_null(&bgp
->group
);
3359 list_delete_and_null(&bgp
->peer
);
3361 if (bgp
->peerhash
) {
3362 hash_free(bgp
->peerhash
);
3363 bgp
->peerhash
= NULL
;
3366 FOREACH_AFI_SAFI (afi
, safi
) {
3367 /* Special handling for 2-level routing tables. */
3368 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3369 || safi
== SAFI_EVPN
) {
3370 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3371 rn
= bgp_route_next(rn
)) {
3372 table
= (struct bgp_table
*)rn
->info
;
3373 bgp_table_finish(&table
);
3376 if (bgp
->route
[afi
][safi
])
3377 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3378 if (bgp
->aggregate
[afi
][safi
])
3379 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3380 if (bgp
->rib
[afi
][safi
])
3381 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3382 rmap
= &bgp
->table_map
[afi
][safi
];
3384 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3387 * Yes this is per AFI, but
3388 * the list_delete_and_null nulls the pointer
3389 * and we'll not leak anything on going down
3390 * and the if test will fail on the second safi.
3392 if (bgp
->vpn_policy
[afi
].import_vrf
)
3393 list_delete_and_null(&bgp
->vpn_policy
[afi
].import_vrf
);
3394 if (bgp
->vpn_policy
[afi
].export_vrf
)
3395 list_delete_and_null(&bgp
->vpn_policy
[afi
].export_vrf
);
3398 bgp_scan_finish(bgp
);
3399 bgp_address_destroy(bgp
);
3400 bgp_tip_hash_destroy(bgp
);
3402 /* release the auto RD id */
3403 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3405 bgp_evpn_cleanup(bgp
);
3406 bgp_pbr_cleanup(bgp
);
3408 XFREE(MTYPE_BGP
, bgp
->name
);
3409 if (bgp
->name_pretty
)
3410 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3412 XFREE(MTYPE_BGP
, bgp
);
3415 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3418 struct listnode
*node
, *nnode
;
3424 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3425 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3426 && !CHECK_FLAG(peer
->sflags
,
3427 PEER_STATUS_ACCEPT_PEER
))
3429 } else if (bm
->bgp
!= NULL
) {
3430 struct listnode
*bgpnode
, *nbgpnode
;
3432 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3433 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3435 && !strcmp(peer
->conf_if
, conf_if
)
3436 && !CHECK_FLAG(peer
->sflags
,
3437 PEER_STATUS_ACCEPT_PEER
))
3443 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3446 struct listnode
*node
, *nnode
;
3452 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3453 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3454 && !CHECK_FLAG(peer
->sflags
,
3455 PEER_STATUS_ACCEPT_PEER
))
3457 } else if (bm
->bgp
!= NULL
) {
3458 struct listnode
*bgpnode
, *nbgpnode
;
3460 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3461 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3463 && !strcmp(peer
->hostname
, hostname
)
3464 && !CHECK_FLAG(peer
->sflags
,
3465 PEER_STATUS_ACCEPT_PEER
))
3471 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3473 struct peer
*peer
= NULL
;
3474 struct peer tmp_peer
;
3476 memset(&tmp_peer
, 0, sizeof(struct peer
));
3479 * We do not want to find the doppelganger peer so search for the peer
3481 * the hash that has PEER_FLAG_CONFIG_NODE
3483 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3488 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3489 } else if (bm
->bgp
!= NULL
) {
3490 struct listnode
*bgpnode
, *nbgpnode
;
3492 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3493 /* Skip VRFs Lite only, this function will not be
3494 * invoked without an instance
3495 * when examining VRFs.
3497 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3498 && !vrf_is_mapped_on_netns(bgp
->vrf_id
))
3501 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3511 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3512 union sockunion
*su
,
3513 struct peer_group
*group
)
3519 /* Create peer first; we've already checked group config is valid. */
3520 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3521 group
->conf
->as_type
, 0, 0, group
);
3526 peer
= peer_lock(peer
);
3527 listnode_add(group
->peer
, peer
);
3529 peer_group2peer_config_copy(group
, peer
);
3532 * Bind peer for all AFs configured for the group. We don't call
3533 * peer_group_bind as that is sub-optimal and does some stuff we don't
3536 FOREACH_AFI_SAFI (afi
, safi
) {
3537 if (!group
->conf
->afc
[afi
][safi
])
3539 peer
->afc
[afi
][safi
] = 1;
3541 if (!peer_af_find(peer
, afi
, safi
))
3542 peer_af_create(peer
, afi
, safi
);
3544 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3547 /* Mark as dynamic, but also as a "config node" for other things to
3549 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3550 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3556 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3557 struct prefix
*prefix
)
3559 struct listnode
*node
, *nnode
;
3560 struct prefix
*range
;
3563 afi
= family2afi(prefix
->family
);
3565 if (group
->listen_range
[afi
])
3566 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3568 if (prefix_match(range
, prefix
))
3575 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3576 struct prefix
**listen_range
)
3578 struct prefix
*range
= NULL
;
3579 struct peer_group
*group
= NULL
;
3580 struct listnode
*node
, *nnode
;
3582 *listen_range
= NULL
;
3584 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3585 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3588 } else if (bm
->bgp
!= NULL
) {
3589 struct listnode
*bgpnode
, *nbgpnode
;
3591 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3592 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3593 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3599 *listen_range
= range
;
3600 return (group
&& range
) ? group
: NULL
;
3603 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3605 struct peer_group
*group
;
3608 struct prefix prefix
;
3609 struct prefix
*listen_range
;
3611 char buf
[PREFIX2STR_BUFFER
];
3612 char buf1
[PREFIX2STR_BUFFER
];
3614 sockunion2hostprefix(su
, &prefix
);
3616 /* See if incoming connection matches a configured listen range. */
3617 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3628 prefix2str(&prefix
, buf
, sizeof(buf
));
3629 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3631 if (bgp_debug_neighbor_events(NULL
))
3633 "Dynamic Neighbor %s matches group %s listen range %s",
3634 buf
, group
->name
, buf1
);
3636 /* Are we within the listen limit? */
3637 dncount
= gbgp
->dynamic_neighbors_count
;
3639 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3640 if (bgp_debug_neighbor_events(NULL
))
3641 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3642 inet_sutop(su
, buf
),
3643 gbgp
->dynamic_neighbors_limit
);
3647 /* Ensure group is not disabled. */
3648 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3649 if (bgp_debug_neighbor_events(NULL
))
3651 "Dynamic Neighbor %s rejected - group %s disabled",
3656 /* Check that at least one AF is activated for the group. */
3657 if (!peer_group_af_configured(group
)) {
3658 if (bgp_debug_neighbor_events(NULL
))
3660 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3665 /* Create dynamic peer and bind to associated group. */
3666 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3669 gbgp
->dynamic_neighbors_count
= ++dncount
;
3671 if (bgp_debug_neighbor_events(peer
))
3672 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3673 peer
->host
, group
->name
, dncount
);
3678 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3681 if (peer
->group
&& peer
->group
->bgp
) {
3682 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3684 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3686 if (bgp_debug_neighbor_events(peer
))
3687 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3688 peer
->group
->name
, dncount
);
3692 /* If peer is configured at least one address family return 1. */
3693 int peer_active(struct peer
*peer
)
3695 if (BGP_PEER_SU_UNSPEC(peer
))
3697 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3698 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3699 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3700 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3701 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3702 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3703 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3704 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3705 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3706 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3707 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3712 /* If peer is negotiated at least one address family return 1. */
3713 int peer_active_nego(struct peer
*peer
)
3715 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3716 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3717 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3718 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3719 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3720 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3721 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3722 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3723 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3724 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3725 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3726 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3727 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3732 /* peer_flag_change_type. */
3733 enum peer_change_type
{
3736 peer_change_reset_in
,
3737 peer_change_reset_out
,
3740 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3741 enum peer_change_type type
)
3743 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3746 if (peer
->status
!= Established
)
3749 if (type
== peer_change_reset
) {
3750 /* If we're resetting session, we've to delete both peer struct
3752 if ((peer
->doppelganger
)
3753 && (peer
->doppelganger
->status
!= Deleted
)
3754 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3755 PEER_FLAG_CONFIG_NODE
)))
3756 peer_delete(peer
->doppelganger
);
3758 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3759 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3760 } else if (type
== peer_change_reset_in
) {
3761 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3762 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3763 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3765 if ((peer
->doppelganger
)
3766 && (peer
->doppelganger
->status
!= Deleted
)
3767 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3768 PEER_FLAG_CONFIG_NODE
)))
3769 peer_delete(peer
->doppelganger
);
3771 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3772 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3774 } else if (type
== peer_change_reset_out
) {
3775 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3776 bgp_announce_route(peer
, afi
, safi
);
3780 struct peer_flag_action
{
3784 /* This flag can be set for peer-group member. */
3785 uint8_t not_for_member
;
3787 /* Action when the flag is changed. */
3788 enum peer_change_type type
;
3790 /* Peer down cause */
3794 static const struct peer_flag_action peer_flag_action_list
[] = {
3795 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3796 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3797 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3798 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3799 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3800 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3801 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3802 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3805 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3806 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3807 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3808 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3809 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3810 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3811 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3812 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3813 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3814 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3815 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3816 // PEER_FLAG_DEFAULT_ORIGINATE
3817 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3818 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3819 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3820 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3821 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3822 // PEER_FLAG_MAX_PREFIX
3823 // PEER_FLAG_MAX_PREFIX_WARNING
3824 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3825 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3826 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3827 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3828 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3829 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3830 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3831 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3832 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3835 /* Proper action set. */
3836 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3837 int size
, struct peer_flag_action
*action
,
3844 const struct peer_flag_action
*match
= NULL
;
3846 /* Check peer's frag action. */
3847 for (i
= 0; i
< size
; i
++) {
3848 match
= &action_list
[i
];
3850 if (match
->flag
== 0)
3853 if (match
->flag
& flag
) {
3856 if (match
->type
== peer_change_reset_in
)
3858 if (match
->type
== peer_change_reset_out
)
3860 if (match
->type
== peer_change_reset
) {
3864 if (match
->not_for_member
)
3865 action
->not_for_member
= 1;
3869 /* Set peer clear type. */
3870 if (reset_in
&& reset_out
)
3871 action
->type
= peer_change_reset
;
3873 action
->type
= peer_change_reset_in
;
3875 action
->type
= peer_change_reset_out
;
3877 action
->type
= peer_change_none
;
3882 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3884 if (flag
== PEER_FLAG_SHUTDOWN
) {
3885 if (CHECK_FLAG(peer
->flags
, flag
)) {
3886 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3887 peer_nsf_stop(peer
);
3889 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3890 if (peer
->t_pmax_restart
) {
3891 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3892 if (bgp_debug_neighbor_events(peer
))
3894 "%s Maximum-prefix restart timer canceled",
3898 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3899 peer_nsf_stop(peer
);
3901 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3902 char *msg
= peer
->tx_shutdown_message
;
3905 if (!msg
&& peer_group_active(peer
))
3906 msg
= peer
->group
->conf
3907 ->tx_shutdown_message
;
3908 msglen
= msg
? strlen(msg
) : 0;
3913 uint8_t msgbuf
[129];
3916 memcpy(msgbuf
+ 1, msg
, msglen
);
3918 bgp_notify_send_with_data(
3919 peer
, BGP_NOTIFY_CEASE
,
3920 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3921 msgbuf
, msglen
+ 1);
3924 peer
, BGP_NOTIFY_CEASE
,
3925 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3927 bgp_session_reset(peer
);
3929 peer
->v_start
= BGP_INIT_START_TIMER
;
3930 BGP_EVENT_ADD(peer
, BGP_Stop
);
3932 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3933 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3934 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3935 else if (flag
== PEER_FLAG_PASSIVE
)
3936 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3937 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3938 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3940 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3941 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3943 bgp_session_reset(peer
);
3946 /* Change specified peer flag. */
3947 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3951 struct peer_group
*group
;
3952 struct peer
*tmp_peer
;
3953 struct listnode
*node
, *nnode
;
3954 struct peer_flag_action action
;
3956 memset(&action
, 0, sizeof(struct peer_flag_action
));
3957 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3959 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3962 /* No flag action is found. */
3964 return BGP_ERR_INVALID_FLAG
;
3966 /* When unset the peer-group member's flag we have to check
3967 peer-group configuration. */
3968 if (!set
&& peer_group_active(peer
))
3969 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3970 if (flag
== PEER_FLAG_SHUTDOWN
)
3971 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3974 /* Flag conflict check. */
3975 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3976 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3977 return BGP_ERR_PEER_FLAG_CONFLICT
;
3979 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3980 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3982 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3987 SET_FLAG(peer
->flags
, flag
);
3989 UNSET_FLAG(peer
->flags
, flag
);
3991 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3992 if (action
.type
== peer_change_reset
)
3993 peer_flag_modify_action(peer
, flag
);
3998 /* peer-group member updates. */
3999 group
= peer
->group
;
4001 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4003 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
4006 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
4010 SET_FLAG(tmp_peer
->flags
, flag
);
4012 UNSET_FLAG(tmp_peer
->flags
, flag
);
4014 if (action
.type
== peer_change_reset
)
4015 peer_flag_modify_action(tmp_peer
, flag
);
4020 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4022 return peer_flag_modify(peer
, flag
, 1);
4025 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4027 return peer_flag_modify(peer
, flag
, 0);
4030 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4031 uint32_t flag
, int set
)
4035 struct listnode
*node
, *nnode
;
4036 struct peer_group
*group
;
4037 struct peer_flag_action action
;
4038 struct peer
*tmp_peer
;
4040 int addpath_tx_used
;
4042 memset(&action
, 0, sizeof(struct peer_flag_action
));
4043 size
= sizeof peer_af_flag_action_list
4044 / sizeof(struct peer_flag_action
);
4046 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4049 /* No flag action is found. */
4051 return BGP_ERR_INVALID_FLAG
;
4053 /* Special check for reflector client. */
4054 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4055 && peer_sort(peer
) != BGP_PEER_IBGP
)
4056 return BGP_ERR_NOT_INTERNAL_PEER
;
4058 /* Special check for remove-private-AS. */
4059 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4060 && peer_sort(peer
) == BGP_PEER_IBGP
)
4061 return BGP_ERR_REMOVE_PRIVATE_AS
;
4063 /* as-override is not allowed for IBGP peers */
4064 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4065 return BGP_ERR_AS_OVERRIDE
;
4067 /* When current flag configuration is same as requested one. */
4068 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4069 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
4071 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
4076 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
4078 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
4080 /* Execute action when peer is established. */
4081 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4082 && peer
->status
== Established
) {
4083 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4084 bgp_clear_adj_in(peer
, afi
, safi
);
4086 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4087 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4088 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4089 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4090 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4091 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4092 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4093 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4095 peer_change_action(peer
, afi
, safi
, action
.type
);
4099 /* Peer group member updates. */
4100 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4101 group
= peer
->group
;
4103 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4105 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
4110 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
4114 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
4116 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
4118 if (tmp_peer
->status
== Established
) {
4119 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4120 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
4122 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4123 tmp_peer
->last_reset
=
4124 PEER_DOWN_RR_CLIENT_CHANGE
;
4126 == PEER_FLAG_RSERVER_CLIENT
)
4127 tmp_peer
->last_reset
=
4128 PEER_DOWN_RS_CLIENT_CHANGE
;
4130 == PEER_FLAG_ORF_PREFIX_SM
)
4131 tmp_peer
->last_reset
=
4132 PEER_DOWN_CAPABILITY_CHANGE
;
4134 == PEER_FLAG_ORF_PREFIX_RM
)
4135 tmp_peer
->last_reset
=
4136 PEER_DOWN_CAPABILITY_CHANGE
;
4138 peer_change_action(tmp_peer
, afi
, safi
,
4145 /* Track if addpath TX is in use */
4146 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4147 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4149 addpath_tx_used
= 0;
4152 addpath_tx_used
= 1;
4154 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4155 if (!bgp_flag_check(
4156 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4158 "%s: enabling bgp deterministic-med, this is required"
4159 " for addpath-tx-bestpath-per-AS",
4163 BGP_FLAG_DETERMINISTIC_MED
);
4164 bgp_recalculate_all_bestpaths(bgp
);
4168 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4170 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4171 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4173 tmp_peer
->af_flags
[afi
][safi
],
4174 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4175 addpath_tx_used
= 1;
4181 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4187 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4189 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4192 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4194 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4198 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4200 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4201 peer
->tx_shutdown_message
=
4202 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4206 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4208 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4213 /* EBGP multihop configuration. */
4214 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4216 struct peer_group
*group
;
4217 struct listnode
*node
, *nnode
;
4220 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4223 /* see comment in peer_ttl_security_hops_set() */
4224 if (ttl
!= MAXTTL
) {
4225 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4226 group
= peer
->group
;
4227 if (group
->conf
->gtsm_hops
!= 0)
4228 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4230 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4232 if (peer1
->sort
== BGP_PEER_IBGP
)
4235 if (peer1
->gtsm_hops
!= 0)
4236 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4239 if (peer
->gtsm_hops
!= 0)
4240 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4246 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4247 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4248 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4249 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4250 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4252 bgp_session_reset(peer
);
4255 group
= peer
->group
;
4256 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4257 if (peer
->sort
== BGP_PEER_IBGP
)
4260 peer
->ttl
= group
->conf
->ttl
;
4262 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4263 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4264 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4266 bgp_session_reset(peer
);
4272 int peer_ebgp_multihop_unset(struct peer
*peer
)
4274 struct peer_group
*group
;
4275 struct listnode
*node
, *nnode
;
4277 if (peer
->sort
== BGP_PEER_IBGP
)
4280 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4281 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4283 if (peer_group_active(peer
))
4284 peer
->ttl
= peer
->group
->conf
->ttl
;
4288 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4289 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4290 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4291 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4293 bgp_session_reset(peer
);
4295 group
= peer
->group
;
4296 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4297 if (peer
->sort
== BGP_PEER_IBGP
)
4302 if (peer
->fd
>= 0) {
4303 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4305 peer
, BGP_NOTIFY_CEASE
,
4306 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4308 bgp_session_reset(peer
);
4315 /* Neighbor description. */
4316 int peer_description_set(struct peer
*peer
, const char *desc
)
4319 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4321 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4326 int peer_description_unset(struct peer
*peer
)
4329 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4336 /* Neighbor update-source. */
4337 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4339 struct peer_group
*group
;
4340 struct listnode
*node
, *nnode
;
4342 if (peer
->update_if
) {
4343 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4344 && strcmp(peer
->update_if
, ifname
) == 0)
4347 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4348 peer
->update_if
= NULL
;
4351 if (peer
->update_source
) {
4352 sockunion_free(peer
->update_source
);
4353 peer
->update_source
= NULL
;
4356 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4358 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4359 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4360 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4361 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4362 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4364 bgp_session_reset(peer
);
4368 /* peer-group member updates. */
4369 group
= peer
->group
;
4370 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4371 if (peer
->update_if
) {
4372 if (strcmp(peer
->update_if
, ifname
) == 0)
4375 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4376 peer
->update_if
= NULL
;
4379 if (peer
->update_source
) {
4380 sockunion_free(peer
->update_source
);
4381 peer
->update_source
= NULL
;
4384 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4386 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4387 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4388 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4389 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4391 bgp_session_reset(peer
);
4396 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4398 struct peer_group
*group
;
4399 struct listnode
*node
, *nnode
;
4401 if (peer
->update_source
) {
4402 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4403 && sockunion_cmp(peer
->update_source
, su
) == 0)
4405 sockunion_free(peer
->update_source
);
4406 peer
->update_source
= NULL
;
4409 if (peer
->update_if
) {
4410 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4411 peer
->update_if
= NULL
;
4414 peer
->update_source
= sockunion_dup(su
);
4416 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4417 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4418 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4419 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4420 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4422 bgp_session_reset(peer
);
4426 /* peer-group member updates. */
4427 group
= peer
->group
;
4428 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4429 if (peer
->update_source
) {
4430 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4432 sockunion_free(peer
->update_source
);
4433 peer
->update_source
= NULL
;
4436 if (peer
->update_if
) {
4437 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4438 peer
->update_if
= NULL
;
4441 peer
->update_source
= sockunion_dup(su
);
4443 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4444 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4445 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4446 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4448 bgp_session_reset(peer
);
4453 int peer_update_source_unset(struct peer
*peer
)
4455 union sockunion
*su
;
4456 struct peer_group
*group
;
4457 struct listnode
*node
, *nnode
;
4459 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4460 && !peer
->update_if
)
4463 if (peer
->update_source
) {
4464 sockunion_free(peer
->update_source
);
4465 peer
->update_source
= NULL
;
4467 if (peer
->update_if
) {
4468 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4469 peer
->update_if
= NULL
;
4472 if (peer_group_active(peer
)) {
4473 group
= peer
->group
;
4475 if (group
->conf
->update_source
) {
4476 su
= sockunion_dup(group
->conf
->update_source
);
4477 peer
->update_source
= su
;
4478 } else if (group
->conf
->update_if
)
4479 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4480 group
->conf
->update_if
);
4483 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4484 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4485 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4486 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4487 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4489 bgp_session_reset(peer
);
4493 /* peer-group member updates. */
4494 group
= peer
->group
;
4495 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4496 if (!peer
->update_source
&& !peer
->update_if
)
4499 if (peer
->update_source
) {
4500 sockunion_free(peer
->update_source
);
4501 peer
->update_source
= NULL
;
4504 if (peer
->update_if
) {
4505 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4506 peer
->update_if
= NULL
;
4509 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4510 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4511 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4512 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4514 bgp_session_reset(peer
);
4519 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4522 struct peer_group
*group
;
4523 struct listnode
*node
, *nnode
;
4525 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4526 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4528 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4529 SET_FLAG(peer
->af_flags
[afi
][safi
],
4530 PEER_FLAG_DEFAULT_ORIGINATE
);
4533 if (peer
->default_rmap
[afi
][safi
].name
)
4534 XFREE(MTYPE_ROUTE_MAP_NAME
,
4535 peer
->default_rmap
[afi
][safi
].name
);
4536 peer
->default_rmap
[afi
][safi
].name
=
4537 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4538 peer
->default_rmap
[afi
][safi
].map
=
4539 route_map_lookup_by_name(rmap
);
4543 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4544 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4545 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4546 bgp_default_originate(peer
, afi
, safi
, 0);
4547 bgp_announce_route(peer
, afi
, safi
);
4552 /* peer-group member updates. */
4553 group
= peer
->group
;
4554 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4555 SET_FLAG(peer
->af_flags
[afi
][safi
],
4556 PEER_FLAG_DEFAULT_ORIGINATE
);
4559 if (peer
->default_rmap
[afi
][safi
].name
)
4560 XFREE(MTYPE_ROUTE_MAP_NAME
,
4561 peer
->default_rmap
[afi
][safi
].name
);
4562 peer
->default_rmap
[afi
][safi
].name
=
4563 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4564 peer
->default_rmap
[afi
][safi
].map
=
4565 route_map_lookup_by_name(rmap
);
4568 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4569 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4570 bgp_default_originate(peer
, afi
, safi
, 0);
4571 bgp_announce_route(peer
, afi
, safi
);
4577 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4579 struct peer_group
*group
;
4580 struct listnode
*node
, *nnode
;
4582 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4583 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4584 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4585 PEER_FLAG_DEFAULT_ORIGINATE
);
4587 if (peer
->default_rmap
[afi
][safi
].name
)
4588 XFREE(MTYPE_ROUTE_MAP_NAME
,
4589 peer
->default_rmap
[afi
][safi
].name
);
4590 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4591 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4594 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4595 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4596 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4597 bgp_default_originate(peer
, afi
, safi
, 1);
4598 bgp_announce_route(peer
, afi
, safi
);
4603 /* peer-group member updates. */
4604 group
= peer
->group
;
4605 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4606 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4607 PEER_FLAG_DEFAULT_ORIGINATE
);
4609 if (peer
->default_rmap
[afi
][safi
].name
)
4610 XFREE(MTYPE_ROUTE_MAP_NAME
,
4611 peer
->default_rmap
[afi
][safi
].name
);
4612 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4613 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4615 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4616 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4617 bgp_default_originate(peer
, afi
, safi
, 1);
4618 bgp_announce_route(peer
, afi
, safi
);
4624 int peer_port_set(struct peer
*peer
, uint16_t port
)
4630 int peer_port_unset(struct peer
*peer
)
4632 peer
->port
= BGP_PORT_DEFAULT
;
4637 * Helper function that is called after the name of the policy
4638 * being used by a peer has changed (AF specific). Automatically
4639 * initiates inbound or outbound processing as needed.
4641 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4645 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4646 if (peer
->status
== Established
)
4647 bgp_announce_route(peer
, afi
, safi
);
4649 if (peer
->status
!= Established
)
4652 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4653 PEER_FLAG_SOFT_RECONFIG
))
4654 bgp_soft_reconfig_in(peer
, afi
, safi
);
4655 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4656 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4657 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4662 /* neighbor weight. */
4663 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4665 struct peer_group
*group
;
4666 struct listnode
*node
, *nnode
;
4668 if (peer
->weight
[afi
][safi
] != weight
) {
4669 peer
->weight
[afi
][safi
] = weight
;
4670 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4671 peer_on_policy_change(peer
, afi
, safi
, 0);
4674 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4677 /* peer-group member updates. */
4678 group
= peer
->group
;
4679 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4680 if (peer
->weight
[afi
][safi
] != weight
) {
4681 peer
->weight
[afi
][safi
] = weight
;
4682 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4683 peer_on_policy_change(peer
, afi
, safi
, 0);
4689 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4691 struct peer_group
*group
;
4692 struct listnode
*node
, *nnode
;
4694 /* not the peer-group itself but a peer in a peer-group */
4695 if (peer_group_active(peer
)) {
4696 group
= peer
->group
;
4698 /* inherit weight from the peer-group */
4699 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4700 PEER_FLAG_WEIGHT
)) {
4701 peer
->weight
[afi
][safi
] =
4702 group
->conf
->weight
[afi
][safi
];
4703 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4704 peer_on_policy_change(peer
, afi
, safi
, 0);
4706 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4707 PEER_FLAG_WEIGHT
)) {
4708 peer
->weight
[afi
][safi
] = 0;
4709 peer_af_flag_unset(peer
, afi
, safi
,
4711 peer_on_policy_change(peer
, afi
, safi
, 0);
4717 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4718 peer
->weight
[afi
][safi
] = 0;
4719 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4720 peer_on_policy_change(peer
, afi
, safi
, 0);
4723 /* peer-group member updates. */
4724 group
= peer
->group
;
4727 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4729 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4730 PEER_FLAG_WEIGHT
)) {
4731 peer
->weight
[afi
][safi
] = 0;
4732 peer_af_flag_unset(peer
, afi
, safi
,
4734 peer_on_policy_change(peer
, afi
, safi
,
4743 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4745 struct peer_group
*group
;
4746 struct listnode
*node
, *nnode
;
4748 /* keepalive value check. */
4749 if (keepalive
> 65535)
4750 return BGP_ERR_INVALID_VALUE
;
4752 /* Holdtime value check. */
4753 if (holdtime
> 65535)
4754 return BGP_ERR_INVALID_VALUE
;
4756 /* Holdtime value must be either 0 or greater than 3. */
4757 if (holdtime
< 3 && holdtime
!= 0)
4758 return BGP_ERR_INVALID_VALUE
;
4760 /* Set value to the configuration. */
4761 peer
->holdtime
= holdtime
;
4762 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4764 /* First work on real peers with timers */
4765 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4766 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4767 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4769 /* Now work on the peer-group timers */
4770 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4772 /* peer-group member updates. */
4773 group
= peer
->group
;
4774 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4775 /* Skip peers that have their own timers */
4776 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4779 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4780 peer
->holdtime
= group
->conf
->holdtime
;
4781 peer
->keepalive
= group
->conf
->keepalive
;
4788 int peer_timers_unset(struct peer
*peer
)
4790 struct peer_group
*group
;
4791 struct listnode
*node
, *nnode
;
4793 /* First work on real peers vs the peer-group */
4794 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4795 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4796 peer
->keepalive
= 0;
4799 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4800 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4801 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4802 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4805 /* peer-group member updates. */
4806 group
= peer
->group
;
4807 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4808 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4809 UNSET_FLAG(peer
->config
,
4810 PEER_GROUP_CONFIG_TIMER
);
4812 peer
->keepalive
= 0;
4816 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4817 group
->conf
->holdtime
= 0;
4818 group
->conf
->keepalive
= 0;
4824 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4826 struct peer_group
*group
;
4827 struct listnode
*node
, *nnode
;
4829 if (connect
> 65535)
4830 return BGP_ERR_INVALID_VALUE
;
4832 /* Set value to the configuration. */
4833 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4834 peer
->connect
= connect
;
4836 /* Set value to timer setting. */
4837 peer
->v_connect
= connect
;
4839 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4842 /* peer-group member updates. */
4843 group
= peer
->group
;
4844 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4845 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4846 peer
->connect
= connect
;
4847 peer
->v_connect
= connect
;
4852 int peer_timers_connect_unset(struct peer
*peer
)
4854 struct peer_group
*group
;
4855 struct listnode
*node
, *nnode
;
4857 /* Clear configuration. */
4858 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4861 /* Set timer setting to default value. */
4862 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4864 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4867 /* peer-group member updates. */
4868 group
= peer
->group
;
4869 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4870 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4872 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4877 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4879 struct peer_group
*group
;
4880 struct listnode
*node
, *nnode
;
4883 return BGP_ERR_INVALID_VALUE
;
4885 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4886 peer
->routeadv
= routeadv
;
4887 peer
->v_routeadv
= routeadv
;
4889 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4890 update_group_adjust_peer_afs(peer
);
4891 if (peer
->status
== Established
)
4892 bgp_announce_route_all(peer
);
4896 /* peer-group member updates. */
4897 group
= peer
->group
;
4898 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4899 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4900 peer
->routeadv
= routeadv
;
4901 peer
->v_routeadv
= routeadv
;
4902 update_group_adjust_peer_afs(peer
);
4903 if (peer
->status
== Established
)
4904 bgp_announce_route_all(peer
);
4910 int peer_advertise_interval_unset(struct peer
*peer
)
4912 struct peer_group
*group
;
4913 struct listnode
*node
, *nnode
;
4915 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4918 if (peer
->sort
== BGP_PEER_IBGP
)
4919 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4921 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4923 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4924 update_group_adjust_peer_afs(peer
);
4925 if (peer
->status
== Established
)
4926 bgp_announce_route_all(peer
);
4930 /* peer-group member updates. */
4931 group
= peer
->group
;
4932 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4933 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4936 if (peer
->sort
== BGP_PEER_IBGP
)
4937 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4939 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4941 update_group_adjust_peer_afs(peer
);
4942 if (peer
->status
== Established
)
4943 bgp_announce_route_all(peer
);
4949 /* neighbor interface */
4950 void peer_interface_set(struct peer
*peer
, const char *str
)
4953 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4954 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4957 void peer_interface_unset(struct peer
*peer
)
4960 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4961 peer
->ifname
= NULL
;
4965 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4966 int allow_num
, int origin
)
4968 struct peer_group
*group
;
4969 struct listnode
*node
, *nnode
;
4972 if (peer
->allowas_in
[afi
][safi
]
4973 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4974 PEER_FLAG_ALLOWAS_IN
)
4975 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4976 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4977 peer
->allowas_in
[afi
][safi
] = 0;
4978 peer_af_flag_unset(peer
, afi
, safi
,
4979 PEER_FLAG_ALLOWAS_IN
);
4980 peer_af_flag_set(peer
, afi
, safi
,
4981 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4982 peer_on_policy_change(peer
, afi
, safi
, 0);
4985 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4988 group
= peer
->group
;
4989 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4990 if (peer
->allowas_in
[afi
][safi
]
4991 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4992 PEER_FLAG_ALLOWAS_IN
)
4993 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4994 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4995 peer
->allowas_in
[afi
][safi
] = 0;
4996 peer_af_flag_unset(peer
, afi
, safi
,
4997 PEER_FLAG_ALLOWAS_IN
);
4998 peer_af_flag_set(peer
, afi
, safi
,
4999 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5000 peer_on_policy_change(peer
, afi
, safi
, 0);
5004 if (allow_num
< 1 || allow_num
> 10)
5005 return BGP_ERR_INVALID_VALUE
;
5007 if (peer
->allowas_in
[afi
][safi
] != allow_num
5008 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5009 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5010 peer
->allowas_in
[afi
][safi
] = allow_num
;
5011 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5012 peer_af_flag_unset(peer
, afi
, safi
,
5013 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5014 peer_on_policy_change(peer
, afi
, safi
, 0);
5017 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5020 group
= peer
->group
;
5021 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5022 if (peer
->allowas_in
[afi
][safi
] != allow_num
5023 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5024 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5025 peer
->allowas_in
[afi
][safi
] = allow_num
;
5026 peer_af_flag_set(peer
, afi
, safi
,
5027 PEER_FLAG_ALLOWAS_IN
);
5028 peer_af_flag_unset(peer
, afi
, safi
,
5029 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5030 peer_on_policy_change(peer
, afi
, safi
, 0);
5038 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5040 struct peer_group
*group
;
5041 struct peer
*tmp_peer
;
5042 struct listnode
*node
, *nnode
;
5044 /* If this is a peer-group we must first clear the flags for all of the
5045 * peer-group members
5047 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5048 group
= peer
->group
;
5049 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
5050 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
5051 PEER_FLAG_ALLOWAS_IN
)
5052 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
5053 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5054 tmp_peer
->allowas_in
[afi
][safi
] = 0;
5055 peer_af_flag_unset(tmp_peer
, afi
, safi
,
5056 PEER_FLAG_ALLOWAS_IN
);
5057 peer_af_flag_unset(tmp_peer
, afi
, safi
,
5058 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5059 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
5064 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
5065 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5066 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5067 peer
->allowas_in
[afi
][safi
] = 0;
5068 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5069 peer_af_flag_unset(peer
, afi
, safi
,
5070 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5071 peer_on_policy_change(peer
, afi
, safi
, 0);
5077 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5080 struct bgp
*bgp
= peer
->bgp
;
5081 struct peer_group
*group
;
5082 struct listnode
*node
, *nnode
;
5084 if (peer_sort(peer
) != BGP_PEER_EBGP
5085 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5086 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5089 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5092 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5094 if (peer
->change_local_as
== as
5095 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
5097 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
5099 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
5101 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
5105 peer
->change_local_as
= as
;
5107 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5109 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5112 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5114 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5116 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5117 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5118 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5119 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5120 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5122 bgp_session_reset(peer
);
5126 group
= peer
->group
;
5127 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5128 peer
->change_local_as
= as
;
5130 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5132 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5135 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5137 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5139 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5140 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5141 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5142 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5144 BGP_EVENT_ADD(peer
, BGP_Stop
);
5150 int peer_local_as_unset(struct peer
*peer
)
5152 struct peer_group
*group
;
5153 struct listnode
*node
, *nnode
;
5155 if (!peer
->change_local_as
)
5158 peer
->change_local_as
= 0;
5159 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5160 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5162 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5163 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5164 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5165 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5166 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5168 BGP_EVENT_ADD(peer
, BGP_Stop
);
5173 group
= peer
->group
;
5174 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5175 peer
->change_local_as
= 0;
5176 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5177 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5179 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5180 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5181 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5182 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5184 bgp_session_reset(peer
);
5189 /* Set password for authenticating with the peer. */
5190 int peer_password_set(struct peer
*peer
, const char *password
)
5192 struct listnode
*nn
, *nnode
;
5193 int len
= password
? strlen(password
) : 0;
5194 int ret
= BGP_SUCCESS
;
5196 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5197 return BGP_ERR_INVALID_VALUE
;
5199 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5200 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5204 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5206 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5208 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5209 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5210 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5211 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5213 bgp_session_reset(peer
);
5215 if (BGP_PEER_SU_UNSPEC(peer
))
5218 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5219 : BGP_ERR_TCPSIG_FAILED
;
5222 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5223 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5227 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5229 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5231 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5232 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5233 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5235 bgp_session_reset(peer
);
5237 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5238 if (bgp_md5_set(peer
) < 0)
5239 ret
= BGP_ERR_TCPSIG_FAILED
;
5246 int peer_password_unset(struct peer
*peer
)
5248 struct listnode
*nn
, *nnode
;
5250 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5253 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5254 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5255 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5256 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5258 bgp_session_reset(peer
);
5261 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5263 peer
->password
= NULL
;
5265 if (!BGP_PEER_SU_UNSPEC(peer
))
5266 bgp_md5_unset(peer
);
5271 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5272 peer
->password
= NULL
;
5274 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5275 if (!peer
->password
)
5278 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5279 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5280 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5282 bgp_session_reset(peer
);
5284 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5285 peer
->password
= NULL
;
5287 if (!BGP_PEER_SU_UNSPEC(peer
))
5288 bgp_md5_unset(peer
);
5295 /* Set distribute list to the peer. */
5296 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5299 struct bgp_filter
*filter
;
5300 struct peer_group
*group
;
5301 struct listnode
*node
, *nnode
;
5303 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5304 return BGP_ERR_INVALID_VALUE
;
5306 filter
= &peer
->filter
[afi
][safi
];
5308 if (filter
->plist
[direct
].name
)
5309 return BGP_ERR_PEER_FILTER_CONFLICT
;
5311 if (filter
->dlist
[direct
].name
)
5312 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5313 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5314 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5316 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5317 peer_on_policy_change(peer
, afi
, safi
,
5318 (direct
== FILTER_OUT
) ? 1 : 0);
5322 group
= peer
->group
;
5323 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5324 filter
= &peer
->filter
[afi
][safi
];
5326 if (filter
->dlist
[direct
].name
)
5327 XFREE(MTYPE_BGP_FILTER_NAME
,
5328 filter
->dlist
[direct
].name
);
5329 filter
->dlist
[direct
].name
=
5330 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5331 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5332 peer_on_policy_change(peer
, afi
, safi
,
5333 (direct
== FILTER_OUT
) ? 1 : 0);
5339 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5341 struct bgp_filter
*filter
;
5342 struct bgp_filter
*gfilter
;
5343 struct peer_group
*group
;
5344 struct listnode
*node
, *nnode
;
5346 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5347 return BGP_ERR_INVALID_VALUE
;
5349 filter
= &peer
->filter
[afi
][safi
];
5351 /* apply peer-group filter */
5352 if (peer_group_active(peer
)) {
5353 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5355 if (gfilter
->dlist
[direct
].name
) {
5356 if (filter
->dlist
[direct
].name
)
5357 XFREE(MTYPE_BGP_FILTER_NAME
,
5358 filter
->dlist
[direct
].name
);
5359 filter
->dlist
[direct
].name
=
5360 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5361 gfilter
->dlist
[direct
].name
);
5362 filter
->dlist
[direct
].alist
=
5363 gfilter
->dlist
[direct
].alist
;
5364 peer_on_policy_change(peer
, afi
, safi
,
5365 (direct
== FILTER_OUT
) ? 1 : 0);
5370 if (filter
->dlist
[direct
].name
)
5371 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5372 filter
->dlist
[direct
].name
= NULL
;
5373 filter
->dlist
[direct
].alist
= NULL
;
5375 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5376 peer_on_policy_change(peer
, afi
, safi
,
5377 (direct
== FILTER_OUT
) ? 1 : 0);
5381 group
= peer
->group
;
5382 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5383 filter
= &peer
->filter
[afi
][safi
];
5385 if (filter
->dlist
[direct
].name
)
5386 XFREE(MTYPE_BGP_FILTER_NAME
,
5387 filter
->dlist
[direct
].name
);
5388 filter
->dlist
[direct
].name
= NULL
;
5389 filter
->dlist
[direct
].alist
= NULL
;
5390 peer_on_policy_change(peer
, afi
, safi
,
5391 (direct
== FILTER_OUT
) ? 1 : 0);
5397 /* Update distribute list. */
5398 static void peer_distribute_update(struct access_list
*access
)
5403 struct listnode
*mnode
, *mnnode
;
5404 struct listnode
*node
, *nnode
;
5407 struct peer_group
*group
;
5408 struct bgp_filter
*filter
;
5410 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5412 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5413 access
->name
, 0, 0);
5414 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5415 FOREACH_AFI_SAFI (afi
, safi
) {
5416 filter
= &peer
->filter
[afi
][safi
];
5418 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5420 if (filter
->dlist
[direct
].name
)
5421 filter
->dlist
[direct
]
5422 .alist
= access_list_lookup(
5424 filter
->dlist
[direct
]
5427 filter
->dlist
[direct
].alist
=
5432 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5433 FOREACH_AFI_SAFI (afi
, safi
) {
5434 filter
= &group
->conf
->filter
[afi
][safi
];
5436 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5438 if (filter
->dlist
[direct
].name
)
5439 filter
->dlist
[direct
]
5440 .alist
= access_list_lookup(
5442 filter
->dlist
[direct
]
5445 filter
->dlist
[direct
].alist
=
5451 vnc_prefix_list_update(bgp
);
5456 /* Set prefix list to the peer. */
5457 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5460 struct bgp_filter
*filter
;
5461 struct peer_group
*group
;
5462 struct listnode
*node
, *nnode
;
5464 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5465 return BGP_ERR_INVALID_VALUE
;
5467 filter
= &peer
->filter
[afi
][safi
];
5469 if (filter
->dlist
[direct
].name
)
5470 return BGP_ERR_PEER_FILTER_CONFLICT
;
5472 if (filter
->plist
[direct
].name
)
5473 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5474 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5475 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5477 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5478 peer_on_policy_change(peer
, afi
, safi
,
5479 (direct
== FILTER_OUT
) ? 1 : 0);
5483 group
= peer
->group
;
5484 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5485 filter
= &peer
->filter
[afi
][safi
];
5487 if (filter
->plist
[direct
].name
)
5488 XFREE(MTYPE_BGP_FILTER_NAME
,
5489 filter
->plist
[direct
].name
);
5490 filter
->plist
[direct
].name
=
5491 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5492 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5493 peer_on_policy_change(peer
, afi
, safi
,
5494 (direct
== FILTER_OUT
) ? 1 : 0);
5499 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5502 struct bgp_filter
*filter
;
5503 struct bgp_filter
*gfilter
;
5504 struct peer_group
*group
;
5505 struct listnode
*node
, *nnode
;
5507 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5508 return BGP_ERR_INVALID_VALUE
;
5510 filter
= &peer
->filter
[afi
][safi
];
5512 /* apply peer-group filter */
5513 if (peer_group_active(peer
)) {
5514 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5516 if (gfilter
->plist
[direct
].name
) {
5517 if (filter
->plist
[direct
].name
)
5518 XFREE(MTYPE_BGP_FILTER_NAME
,
5519 filter
->plist
[direct
].name
);
5520 filter
->plist
[direct
].name
=
5521 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5522 gfilter
->plist
[direct
].name
);
5523 filter
->plist
[direct
].plist
=
5524 gfilter
->plist
[direct
].plist
;
5525 peer_on_policy_change(peer
, afi
, safi
,
5526 (direct
== FILTER_OUT
) ? 1 : 0);
5531 if (filter
->plist
[direct
].name
)
5532 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5533 filter
->plist
[direct
].name
= NULL
;
5534 filter
->plist
[direct
].plist
= NULL
;
5536 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5537 peer_on_policy_change(peer
, afi
, safi
,
5538 (direct
== FILTER_OUT
) ? 1 : 0);
5542 group
= peer
->group
;
5543 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5544 filter
= &peer
->filter
[afi
][safi
];
5546 if (filter
->plist
[direct
].name
)
5547 XFREE(MTYPE_BGP_FILTER_NAME
,
5548 filter
->plist
[direct
].name
);
5549 filter
->plist
[direct
].name
= NULL
;
5550 filter
->plist
[direct
].plist
= NULL
;
5551 peer_on_policy_change(peer
, afi
, safi
,
5552 (direct
== FILTER_OUT
) ? 1 : 0);
5558 /* Update prefix-list list. */
5559 static void peer_prefix_list_update(struct prefix_list
*plist
)
5561 struct listnode
*mnode
, *mnnode
;
5562 struct listnode
*node
, *nnode
;
5565 struct peer_group
*group
;
5566 struct bgp_filter
*filter
;
5571 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5574 * Update the prefix-list on update groups.
5576 update_group_policy_update(
5577 bgp
, BGP_POLICY_PREFIX_LIST
,
5578 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5580 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5581 FOREACH_AFI_SAFI (afi
, safi
) {
5582 filter
= &peer
->filter
[afi
][safi
];
5584 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5586 if (filter
->plist
[direct
].name
)
5587 filter
->plist
[direct
]
5588 .plist
= prefix_list_lookup(
5590 filter
->plist
[direct
]
5593 filter
->plist
[direct
].plist
=
5598 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5599 FOREACH_AFI_SAFI (afi
, safi
) {
5600 filter
= &group
->conf
->filter
[afi
][safi
];
5602 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5604 if (filter
->plist
[direct
].name
)
5605 filter
->plist
[direct
]
5606 .plist
= prefix_list_lookup(
5608 filter
->plist
[direct
]
5611 filter
->plist
[direct
].plist
=
5619 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5622 struct bgp_filter
*filter
;
5623 struct peer_group
*group
;
5624 struct listnode
*node
, *nnode
;
5626 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5627 return BGP_ERR_INVALID_VALUE
;
5629 filter
= &peer
->filter
[afi
][safi
];
5631 if (filter
->aslist
[direct
].name
)
5632 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5633 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5634 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5636 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5637 peer_on_policy_change(peer
, afi
, safi
,
5638 (direct
== FILTER_OUT
) ? 1 : 0);
5642 group
= peer
->group
;
5643 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5644 filter
= &peer
->filter
[afi
][safi
];
5646 if (filter
->aslist
[direct
].name
)
5647 XFREE(MTYPE_BGP_FILTER_NAME
,
5648 filter
->aslist
[direct
].name
);
5649 filter
->aslist
[direct
].name
=
5650 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5651 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5652 peer_on_policy_change(peer
, afi
, safi
,
5653 (direct
== FILTER_OUT
) ? 1 : 0);
5658 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5660 struct bgp_filter
*filter
;
5661 struct bgp_filter
*gfilter
;
5662 struct peer_group
*group
;
5663 struct listnode
*node
, *nnode
;
5665 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5666 return BGP_ERR_INVALID_VALUE
;
5668 filter
= &peer
->filter
[afi
][safi
];
5670 /* apply peer-group filter */
5671 if (peer_group_active(peer
)) {
5672 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5674 if (gfilter
->aslist
[direct
].name
) {
5675 if (filter
->aslist
[direct
].name
)
5676 XFREE(MTYPE_BGP_FILTER_NAME
,
5677 filter
->aslist
[direct
].name
);
5678 filter
->aslist
[direct
].name
=
5679 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5680 gfilter
->aslist
[direct
].name
);
5681 filter
->aslist
[direct
].aslist
=
5682 gfilter
->aslist
[direct
].aslist
;
5683 peer_on_policy_change(peer
, afi
, safi
,
5684 (direct
== FILTER_OUT
) ? 1 : 0);
5689 if (filter
->aslist
[direct
].name
)
5690 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5691 filter
->aslist
[direct
].name
= NULL
;
5692 filter
->aslist
[direct
].aslist
= NULL
;
5694 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5695 peer_on_policy_change(peer
, afi
, safi
,
5696 (direct
== FILTER_OUT
) ? 1 : 0);
5700 group
= peer
->group
;
5701 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5702 filter
= &peer
->filter
[afi
][safi
];
5704 if (filter
->aslist
[direct
].name
)
5705 XFREE(MTYPE_BGP_FILTER_NAME
,
5706 filter
->aslist
[direct
].name
);
5707 filter
->aslist
[direct
].name
= NULL
;
5708 filter
->aslist
[direct
].aslist
= NULL
;
5709 peer_on_policy_change(peer
, afi
, safi
,
5710 (direct
== FILTER_OUT
) ? 1 : 0);
5716 static void peer_aslist_update(const char *aslist_name
)
5721 struct listnode
*mnode
, *mnnode
;
5722 struct listnode
*node
, *nnode
;
5725 struct peer_group
*group
;
5726 struct bgp_filter
*filter
;
5728 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5729 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5732 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5733 FOREACH_AFI_SAFI (afi
, safi
) {
5734 filter
= &peer
->filter
[afi
][safi
];
5736 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5738 if (filter
->aslist
[direct
].name
)
5739 filter
->aslist
[direct
]
5740 .aslist
= as_list_lookup(
5741 filter
->aslist
[direct
]
5744 filter
->aslist
[direct
].aslist
=
5749 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5750 FOREACH_AFI_SAFI (afi
, safi
) {
5751 filter
= &group
->conf
->filter
[afi
][safi
];
5753 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5755 if (filter
->aslist
[direct
].name
)
5756 filter
->aslist
[direct
]
5757 .aslist
= as_list_lookup(
5758 filter
->aslist
[direct
]
5761 filter
->aslist
[direct
].aslist
=
5769 static void peer_aslist_add(char *aslist_name
)
5771 peer_aslist_update(aslist_name
);
5772 route_map_notify_dependencies((char *)aslist_name
,
5773 RMAP_EVENT_ASLIST_ADDED
);
5776 static void peer_aslist_del(const char *aslist_name
)
5778 peer_aslist_update(aslist_name
);
5779 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5783 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5786 struct bgp_filter
*filter
;
5787 struct peer_group
*group
;
5788 struct listnode
*node
, *nnode
;
5790 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5791 return BGP_ERR_INVALID_VALUE
;
5793 filter
= &peer
->filter
[afi
][safi
];
5795 if (filter
->map
[direct
].name
)
5796 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5798 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5799 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5801 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5802 peer_on_policy_change(peer
, afi
, safi
,
5803 (direct
== RMAP_OUT
) ? 1 : 0);
5807 group
= peer
->group
;
5808 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5809 filter
= &peer
->filter
[afi
][safi
];
5811 if (filter
->map
[direct
].name
)
5812 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5813 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5814 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5815 peer_on_policy_change(peer
, afi
, safi
,
5816 (direct
== RMAP_OUT
) ? 1 : 0);
5821 /* Unset route-map from the peer. */
5822 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5824 struct bgp_filter
*filter
;
5825 struct bgp_filter
*gfilter
;
5826 struct peer_group
*group
;
5827 struct listnode
*node
, *nnode
;
5829 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5830 return BGP_ERR_INVALID_VALUE
;
5832 filter
= &peer
->filter
[afi
][safi
];
5834 /* apply peer-group filter */
5835 if (peer_group_active(peer
)) {
5836 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5838 if (gfilter
->map
[direct
].name
) {
5839 if (filter
->map
[direct
].name
)
5840 XFREE(MTYPE_BGP_FILTER_NAME
,
5841 filter
->map
[direct
].name
);
5842 filter
->map
[direct
].name
=
5843 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5844 gfilter
->map
[direct
].name
);
5845 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5846 peer_on_policy_change(peer
, afi
, safi
,
5847 (direct
== RMAP_OUT
) ? 1 : 0);
5852 if (filter
->map
[direct
].name
)
5853 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5854 filter
->map
[direct
].name
= NULL
;
5855 filter
->map
[direct
].map
= NULL
;
5857 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5858 peer_on_policy_change(peer
, afi
, safi
,
5859 (direct
== RMAP_OUT
) ? 1 : 0);
5863 group
= peer
->group
;
5864 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5865 filter
= &peer
->filter
[afi
][safi
];
5867 if (filter
->map
[direct
].name
)
5868 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5869 filter
->map
[direct
].name
= NULL
;
5870 filter
->map
[direct
].map
= NULL
;
5871 peer_on_policy_change(peer
, afi
, safi
,
5872 (direct
== RMAP_OUT
) ? 1 : 0);
5877 /* Set unsuppress-map to the peer. */
5878 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5881 struct bgp_filter
*filter
;
5882 struct peer_group
*group
;
5883 struct listnode
*node
, *nnode
;
5885 filter
= &peer
->filter
[afi
][safi
];
5887 if (filter
->usmap
.name
)
5888 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5890 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5891 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5893 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5894 peer_on_policy_change(peer
, afi
, safi
, 1);
5898 group
= peer
->group
;
5899 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5900 filter
= &peer
->filter
[afi
][safi
];
5902 if (filter
->usmap
.name
)
5903 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5904 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5905 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5906 peer_on_policy_change(peer
, afi
, safi
, 1);
5911 /* Unset route-map from the peer. */
5912 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5914 struct bgp_filter
*filter
;
5915 struct peer_group
*group
;
5916 struct listnode
*node
, *nnode
;
5918 filter
= &peer
->filter
[afi
][safi
];
5920 if (filter
->usmap
.name
)
5921 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5922 filter
->usmap
.name
= NULL
;
5923 filter
->usmap
.map
= NULL
;
5925 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5926 peer_on_policy_change(peer
, afi
, safi
, 1);
5930 group
= peer
->group
;
5931 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5932 filter
= &peer
->filter
[afi
][safi
];
5934 if (filter
->usmap
.name
)
5935 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5936 filter
->usmap
.name
= NULL
;
5937 filter
->usmap
.map
= NULL
;
5938 peer_on_policy_change(peer
, afi
, safi
, 1);
5943 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5944 uint32_t max
, uint8_t threshold
, int warning
,
5947 struct peer_group
*group
;
5948 struct listnode
*node
, *nnode
;
5950 /* apply configuration and set flags */
5951 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5953 SET_FLAG(peer
->af_flags
[afi
][safi
],
5954 PEER_FLAG_MAX_PREFIX_WARNING
);
5956 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5957 PEER_FLAG_MAX_PREFIX_WARNING
);
5958 peer
->pmax
[afi
][safi
] = max
;
5959 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5960 peer
->pmax_restart
[afi
][safi
] = restart
;
5962 /* if handling a peer-group, apply to all children */
5963 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5964 group
= peer
->group
;
5965 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5967 * If peer configuration is user-set, it overrides
5968 * peer-group config.
5970 if (!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
],
5971 PEER_FLAG_MAX_PREFIX
)) {
5972 SET_FLAG(peer
->af_flags
[afi
][safi
],
5973 PEER_FLAG_MAX_PREFIX
);
5974 peer
->pmax
[afi
][safi
] = max
;
5975 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5976 peer
->pmax_restart
[afi
][safi
] = restart
;
5978 if (!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
],
5979 PEER_FLAG_MAX_PREFIX_WARNING
)) {
5981 SET_FLAG(peer
->af_flags
[afi
][safi
],
5982 PEER_FLAG_MAX_PREFIX_WARNING
);
5985 peer
->af_flags
[afi
][safi
],
5986 PEER_FLAG_MAX_PREFIX_WARNING
);
5989 if ((peer
->status
== Established
)
5990 && (peer
->afc
[afi
][safi
]))
5991 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5994 /* if not handling a peer-group, set the override flags */
5995 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5996 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5998 SET_FLAG(peer
->af_flags_override
[afi
][safi
],
5999 PEER_FLAG_MAX_PREFIX
);
6002 SET_FLAG(peer
->af_flags_override
[afi
][safi
],
6003 PEER_FLAG_MAX_PREFIX_WARNING
);
6005 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
],
6006 PEER_FLAG_MAX_PREFIX_WARNING
);
6012 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6014 struct peer_group
*group
;
6015 struct listnode
*node
, *nnode
;
6017 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6018 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
6019 peer
->pmax
[afi
][safi
] = 0;
6020 peer
->pmax_threshold
[afi
][safi
] = 0;
6021 peer
->pmax_restart
[afi
][safi
] = 0;
6023 /* if not handling a peer-group, unset override flags */
6024 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6025 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
],
6026 PEER_FLAG_MAX_PREFIX
);
6027 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
],
6028 PEER_FLAG_MAX_PREFIX_WARNING
);
6029 /* if peer is part of a peer-group, apply peer-group config */
6030 if (peer_group_active(peer
)) {
6031 peer
->pmax
[afi
][safi
] =
6032 peer
->group
->conf
->pmax
[afi
][safi
];
6033 peer
->pmax_threshold
[afi
][safi
] =
6034 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
6035 peer
->pmax_restart
[afi
][safi
] =
6036 peer
->group
->conf
->pmax_restart
[afi
][safi
];
6043 * If this peer is a peer-group, set all peers in the group unless they
6044 * have overrides for our config.
6046 group
= peer
->group
;
6047 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6048 if (!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
],
6049 PEER_FLAG_MAX_PREFIX_WARNING
))
6050 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6051 PEER_FLAG_MAX_PREFIX_WARNING
);
6052 if (!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
],
6053 PEER_FLAG_MAX_PREFIX
)) {
6054 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6055 PEER_FLAG_MAX_PREFIX
);
6056 peer
->pmax
[afi
][safi
] = 0;
6057 peer
->pmax_threshold
[afi
][safi
] = 0;
6058 peer
->pmax_restart
[afi
][safi
] = 0;
6064 int is_ebgp_multihop_configured(struct peer
*peer
)
6066 struct peer_group
*group
;
6067 struct listnode
*node
, *nnode
;
6070 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6071 group
= peer
->group
;
6072 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6073 && (group
->conf
->ttl
!= 1))
6076 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6077 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6078 && (peer1
->ttl
!= 1))
6082 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6088 /* Set # of hops between us and BGP peer. */
6089 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6091 struct peer_group
*group
;
6092 struct listnode
*node
, *nnode
;
6095 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6096 gtsm_hops
, peer
->host
);
6098 /* We cannot configure ttl-security hops when ebgp-multihop is already
6099 set. For non peer-groups, the check is simple. For peer-groups,
6101 slightly messy, because we need to check both the peer-group
6103 and all peer-group members for any trace of ebgp-multihop
6105 before actually applying the ttl-security rules. Cisco really made a
6106 mess of this configuration parameter, and OpenBGPD got it right.
6109 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6110 if (is_ebgp_multihop_configured(peer
))
6111 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6113 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6114 peer
->gtsm_hops
= gtsm_hops
;
6116 /* Calling ebgp multihop also resets the session.
6117 * On restart, NHT will get setup correctly as will the
6118 * min & max ttls on the socket. The return value is
6121 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6126 group
= peer
->group
;
6127 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6129 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6131 /* Calling ebgp multihop also resets the
6133 * On restart, NHT will get setup correctly as
6135 * min & max ttls on the socket. The return
6139 peer_ebgp_multihop_set(peer
, MAXTTL
);
6143 /* Post the first gtsm setup or if its ibgp, maxttl setting
6145 * necessary, just set the minttl.
6147 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6148 peer
->gtsm_hops
= gtsm_hops
;
6151 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6152 MAXTTL
+ 1 - gtsm_hops
);
6153 if ((peer
->status
< Established
) && peer
->doppelganger
6154 && (peer
->doppelganger
->fd
>= 0))
6155 sockopt_minttl(peer
->su
.sa
.sa_family
,
6156 peer
->doppelganger
->fd
,
6157 MAXTTL
+ 1 - gtsm_hops
);
6159 group
= peer
->group
;
6160 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6162 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6164 /* Change setting of existing peer
6165 * established then change value (may break
6167 * not established yet (teardown session and
6169 * no session then do nothing (will get
6170 * handled by next connection)
6172 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6174 peer
->su
.sa
.sa_family
, peer
->fd
,
6175 MAXTTL
+ 1 - peer
->gtsm_hops
);
6176 if ((peer
->status
< Established
)
6177 && peer
->doppelganger
6178 && (peer
->doppelganger
->fd
>= 0))
6179 sockopt_minttl(peer
->su
.sa
.sa_family
,
6180 peer
->doppelganger
->fd
,
6181 MAXTTL
+ 1 - gtsm_hops
);
6189 int peer_ttl_security_hops_unset(struct peer
*peer
)
6191 struct peer_group
*group
;
6192 struct listnode
*node
, *nnode
;
6195 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6198 /* if a peer-group member, then reset to peer-group default rather than
6200 if (peer_group_active(peer
))
6201 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6203 peer
->gtsm_hops
= 0;
6205 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6206 /* Invoking ebgp_multihop_set will set the TTL back to the
6208 * value as well as restting the NHT and such. The session is
6211 if (peer
->sort
== BGP_PEER_EBGP
)
6212 ret
= peer_ebgp_multihop_unset(peer
);
6215 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6218 if ((peer
->status
< Established
) && peer
->doppelganger
6219 && (peer
->doppelganger
->fd
>= 0))
6220 sockopt_minttl(peer
->su
.sa
.sa_family
,
6221 peer
->doppelganger
->fd
, 0);
6224 group
= peer
->group
;
6225 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6226 peer
->gtsm_hops
= 0;
6227 if (peer
->sort
== BGP_PEER_EBGP
)
6228 ret
= peer_ebgp_multihop_unset(peer
);
6231 sockopt_minttl(peer
->su
.sa
.sa_family
,
6234 if ((peer
->status
< Established
)
6235 && peer
->doppelganger
6236 && (peer
->doppelganger
->fd
>= 0))
6237 sockopt_minttl(peer
->su
.sa
.sa_family
,
6238 peer
->doppelganger
->fd
,
6248 * If peer clear is invoked in a loop for all peers on the BGP instance,
6249 * it may end up freeing the doppelganger, and if this was the next node
6250 * to the current node, we would end up accessing the freed next node.
6251 * Pass along additional parameter which can be updated if next node
6252 * is freed; only required when walking the peer list on BGP instance.
6254 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6256 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6257 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6258 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6259 if (peer
->t_pmax_restart
) {
6260 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6261 if (bgp_debug_neighbor_events(peer
))
6263 "%s Maximum-prefix restart timer canceled",
6266 BGP_EVENT_ADD(peer
, BGP_Start
);
6270 peer
->v_start
= BGP_INIT_START_TIMER
;
6271 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6272 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6273 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6275 bgp_session_reset_safe(peer
, nnode
);
6280 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6281 enum bgp_clear_type stype
)
6283 struct peer_af
*paf
;
6285 if (peer
->status
!= Established
)
6288 if (!peer
->afc
[afi
][safi
])
6289 return BGP_ERR_AF_UNCONFIGURED
;
6291 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6293 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6294 /* Clear the "neighbor x.x.x.x default-originate" flag */
6295 paf
= peer_af_find(peer
, afi
, safi
);
6296 if (paf
&& paf
->subgroup
6297 && CHECK_FLAG(paf
->subgroup
->sflags
,
6298 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6299 UNSET_FLAG(paf
->subgroup
->sflags
,
6300 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6302 bgp_announce_route(peer
, afi
, safi
);
6305 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6306 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6307 PEER_CAP_ORF_PREFIX_SM_ADV
)
6308 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6309 PEER_CAP_ORF_PREFIX_RM_RCV
)
6310 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6311 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6312 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6313 uint8_t prefix_type
;
6315 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6316 PEER_CAP_ORF_PREFIX_RM_RCV
))
6317 prefix_type
= ORF_TYPE_PREFIX
;
6319 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6321 if (filter
->plist
[FILTER_IN
].plist
) {
6322 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6323 PEER_STATUS_ORF_PREFIX_SEND
))
6324 bgp_route_refresh_send(
6325 peer
, afi
, safi
, prefix_type
,
6327 bgp_route_refresh_send(peer
, afi
, safi
,
6329 REFRESH_IMMEDIATE
, 0);
6331 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6332 PEER_STATUS_ORF_PREFIX_SEND
))
6333 bgp_route_refresh_send(
6334 peer
, afi
, safi
, prefix_type
,
6335 REFRESH_IMMEDIATE
, 1);
6337 bgp_route_refresh_send(peer
, afi
, safi
,
6344 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6345 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6346 /* If neighbor has soft reconfiguration inbound flag.
6347 Use Adj-RIB-In database. */
6348 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6349 PEER_FLAG_SOFT_RECONFIG
))
6350 bgp_soft_reconfig_in(peer
, afi
, safi
);
6352 /* If neighbor has route refresh capability, send route
6354 message to the peer. */
6355 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6356 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6357 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6360 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6366 /* Display peer uptime.*/
6367 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, uint8_t use_json
,
6370 time_t uptime1
, epoch_tbuf
;
6373 /* Check buffer length. */
6374 if (len
< BGP_UPTIME_LEN
) {
6376 zlog_warn("peer_uptime (): buffer shortage %lu",
6377 (unsigned long)len
);
6378 /* XXX: should return status instead of buf... */
6379 snprintf(buf
, len
, "<error> ");
6384 /* If there is no connection has been done before print `never'. */
6387 json_object_string_add(json
, "peerUptime", "never");
6388 json_object_int_add(json
, "peerUptimeMsec", 0);
6390 snprintf(buf
, len
, "never");
6394 /* Get current time. */
6395 uptime1
= bgp_clock();
6397 tm
= gmtime(&uptime1
);
6399 if (uptime1
< ONE_DAY_SECOND
)
6400 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6402 else if (uptime1
< ONE_WEEK_SECOND
)
6403 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6405 else if (uptime1
< ONE_YEAR_SECOND
)
6406 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6407 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6409 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6411 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6414 epoch_tbuf
= time(NULL
) - uptime1
;
6415 json_object_string_add(json
, "peerUptime", buf
);
6416 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6417 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6424 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6425 afi_t afi
, safi_t safi
)
6427 struct bgp_filter
*filter
;
6428 struct bgp_filter
*gfilter
= NULL
;
6431 int out
= FILTER_OUT
;
6434 filter
= &peer
->filter
[afi
][safi
];
6436 if (peer_group_active(peer
))
6437 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6439 /* distribute-list. */
6440 if (filter
->dlist
[in
].name
)
6441 if (!gfilter
|| !gfilter
->dlist
[in
].name
6442 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6444 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6445 addr
, filter
->dlist
[in
].name
);
6448 if (filter
->dlist
[out
].name
&& !gfilter
) {
6449 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6450 filter
->dlist
[out
].name
);
6454 if (filter
->plist
[in
].name
)
6455 if (!gfilter
|| !gfilter
->plist
[in
].name
6456 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6458 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6459 filter
->plist
[in
].name
);
6462 if (filter
->plist
[out
].name
)
6463 if (!gfilter
|| !gfilter
->plist
[out
].name
6464 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6466 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6467 filter
->plist
[out
].name
);
6471 if (filter
->map
[RMAP_IN
].name
)
6472 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6473 || strcmp(filter
->map
[RMAP_IN
].name
,
6474 gfilter
->map
[RMAP_IN
].name
)
6476 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6477 filter
->map
[RMAP_IN
].name
);
6480 if (filter
->map
[RMAP_OUT
].name
)
6481 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6482 || strcmp(filter
->map
[RMAP_OUT
].name
,
6483 gfilter
->map
[RMAP_OUT
].name
)
6485 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6486 filter
->map
[RMAP_OUT
].name
);
6489 /* unsuppress-map */
6490 if (filter
->usmap
.name
&& !gfilter
) {
6491 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6492 filter
->usmap
.name
);
6496 if (filter
->aslist
[in
].name
)
6497 if (!gfilter
|| !gfilter
->aslist
[in
].name
6498 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6500 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6501 filter
->aslist
[in
].name
);
6504 if (filter
->aslist
[out
].name
&& !gfilter
) {
6505 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6506 filter
->aslist
[out
].name
);
6510 /* BGP peer configuration display function. */
6511 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6514 struct peer
*g_peer
= NULL
;
6515 char buf
[SU_ADDRSTRLEN
];
6517 int if_pg_printed
= FALSE
;
6518 int if_ras_printed
= FALSE
;
6520 /* Skip dynamic neighbors. */
6521 if (peer_dynamic_neighbor(peer
))
6525 addr
= peer
->conf_if
;
6529 /************************************
6530 ****** Global to the neighbor ******
6531 ************************************/
6532 if (peer
->conf_if
) {
6533 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6534 vty_out(vty
, " neighbor %s interface v6only", addr
);
6536 vty_out(vty
, " neighbor %s interface", addr
);
6538 if (peer_group_active(peer
)) {
6539 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6540 if_pg_printed
= TRUE
;
6541 } else if (peer
->as_type
== AS_SPECIFIED
) {
6542 vty_out(vty
, " remote-as %u", peer
->as
);
6543 if_ras_printed
= TRUE
;
6544 } else if (peer
->as_type
== AS_INTERNAL
) {
6545 vty_out(vty
, " remote-as internal");
6546 if_ras_printed
= TRUE
;
6547 } else if (peer
->as_type
== AS_EXTERNAL
) {
6548 vty_out(vty
, " remote-as external");
6549 if_ras_printed
= TRUE
;
6555 /* remote-as and peer-group */
6556 /* peer is a member of a peer-group */
6557 if (peer_group_active(peer
)) {
6558 g_peer
= peer
->group
->conf
;
6560 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6561 if (peer
->as_type
== AS_SPECIFIED
) {
6562 vty_out(vty
, " neighbor %s remote-as %u\n",
6564 } else if (peer
->as_type
== AS_INTERNAL
) {
6566 " neighbor %s remote-as internal\n",
6568 } else if (peer
->as_type
== AS_EXTERNAL
) {
6570 " neighbor %s remote-as external\n",
6575 /* For swpX peers we displayed the peer-group
6576 * via 'neighbor swpX interface peer-group WORD' */
6578 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6582 /* peer is NOT a member of a peer-group */
6584 /* peer is a peer-group, declare the peer-group */
6585 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6586 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6589 if (!if_ras_printed
) {
6590 if (peer
->as_type
== AS_SPECIFIED
) {
6591 vty_out(vty
, " neighbor %s remote-as %u\n",
6593 } else if (peer
->as_type
== AS_INTERNAL
) {
6595 " neighbor %s remote-as internal\n",
6597 } else if (peer
->as_type
== AS_EXTERNAL
) {
6599 " neighbor %s remote-as external\n",
6606 if (peer
->change_local_as
) {
6607 if (!peer_group_active(peer
)
6608 || peer
->change_local_as
!= g_peer
->change_local_as
6609 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6610 != CHECK_FLAG(g_peer
->flags
,
6611 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6612 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6613 != CHECK_FLAG(g_peer
->flags
,
6614 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6615 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6616 peer
->change_local_as
,
6617 CHECK_FLAG(peer
->flags
,
6618 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6621 CHECK_FLAG(peer
->flags
,
6622 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6630 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6634 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6635 if (!peer_group_active(peer
)
6636 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6637 || peer
->tx_shutdown_message
) {
6638 if (peer
->tx_shutdown_message
)
6640 " neighbor %s shutdown message %s\n",
6641 addr
, peer
->tx_shutdown_message
);
6643 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6648 if (peer
->bfd_info
) {
6649 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6650 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6655 if (peer
->password
) {
6656 if (!peer_group_active(peer
) || !g_peer
->password
6657 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6658 vty_out(vty
, " neighbor %s password %s\n", addr
,
6664 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6665 if (!peer_group_active(peer
)) {
6666 vty_out(vty
, " neighbor %s solo\n", addr
);
6671 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6672 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6675 /* Local interface name */
6677 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6681 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6682 if (!peer_group_active(peer
)
6683 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6684 vty_out(vty
, " neighbor %s passive\n", addr
);
6689 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6690 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6691 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6692 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6697 /* ttl-security hops */
6698 if (peer
->gtsm_hops
!= 0) {
6699 if (!peer_group_active(peer
)
6700 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6701 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6702 addr
, peer
->gtsm_hops
);
6706 /* disable-connected-check */
6707 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6708 if (!peer_group_active(peer
)
6709 || !CHECK_FLAG(g_peer
->flags
,
6710 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6711 vty_out(vty
, " neighbor %s disable-connected-check\n",
6717 if (peer
->update_if
) {
6718 if (!peer_group_active(peer
) || !g_peer
->update_if
6719 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6720 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6724 if (peer
->update_source
) {
6725 if (!peer_group_active(peer
) || !g_peer
->update_source
6726 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6728 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6729 sockunion2str(peer
->update_source
, buf
,
6734 /* advertisement-interval */
6735 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6736 && ((!peer_group_active(peer
)
6737 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6738 || (peer_group_active(peer
)
6739 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6740 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6745 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6746 && ((!peer_group_active(peer
)
6747 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6748 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6749 || (peer_group_active(peer
)
6750 && (peer
->keepalive
!= g_peer
->keepalive
6751 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6752 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6753 peer
->keepalive
, peer
->holdtime
);
6756 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6757 && ((!peer_group_active(peer
)
6758 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6759 || (peer_group_active(peer
)
6760 && peer
->connect
!= g_peer
->connect
)))
6763 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6767 /* capability dynamic */
6768 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6769 if (!peer_group_active(peer
)
6770 || !CHECK_FLAG(g_peer
->flags
,
6771 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6772 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6776 /* capability extended-nexthop */
6777 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6778 if (!peer_group_active(peer
)
6779 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6781 " no neighbor %s capability extended-nexthop\n",
6786 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6787 if (!peer_group_active(peer
)
6788 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6790 " neighbor %s capability extended-nexthop\n",
6795 /* dont-capability-negotiation */
6796 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6797 if (!peer_group_active(peer
)
6798 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6799 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6804 /* override-capability */
6805 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6806 if (!peer_group_active(peer
)
6807 || !CHECK_FLAG(g_peer
->flags
,
6808 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6809 vty_out(vty
, " neighbor %s override-capability\n",
6814 /* strict-capability-match */
6815 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6816 if (!peer_group_active(peer
)
6817 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6818 vty_out(vty
, " neighbor %s strict-capability-match\n",
6824 /* BGP peer configuration display function. */
6825 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6826 struct peer
*peer
, afi_t afi
, safi_t safi
)
6828 struct peer
*g_peer
= NULL
;
6831 /* Skip dynamic neighbors. */
6832 if (peer_dynamic_neighbor(peer
))
6836 addr
= peer
->conf_if
;
6840 /************************************
6841 ****** Per AF to the neighbor ******
6842 ************************************/
6843 if (peer_group_active(peer
)) {
6844 g_peer
= peer
->group
->conf
;
6846 /* If the peer-group is active but peer is not, print a 'no
6848 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6849 vty_out(vty
, " no neighbor %s activate\n", addr
);
6852 /* If the peer-group is not active but peer is, print an
6854 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6855 vty_out(vty
, " neighbor %s activate\n", addr
);
6858 if (peer
->afc
[afi
][safi
]) {
6859 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6860 if (bgp_flag_check(bgp
,
6861 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6862 vty_out(vty
, " neighbor %s activate\n",
6866 vty_out(vty
, " neighbor %s activate\n", addr
);
6868 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6869 if (!bgp_flag_check(bgp
,
6870 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6872 " no neighbor %s activate\n",
6879 /* addpath TX knobs */
6880 if (peergroup_af_flag_check(peer
, afi
, safi
,
6881 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6882 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6885 if (peergroup_af_flag_check(peer
, afi
, safi
,
6886 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6887 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6891 /* ORF capability. */
6892 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6893 || peergroup_af_flag_check(peer
, afi
, safi
,
6894 PEER_FLAG_ORF_PREFIX_RM
)) {
6895 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6897 if (peergroup_af_flag_check(peer
, afi
, safi
,
6898 PEER_FLAG_ORF_PREFIX_SM
)
6899 && peergroup_af_flag_check(peer
, afi
, safi
,
6900 PEER_FLAG_ORF_PREFIX_RM
))
6901 vty_out(vty
, " both");
6902 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6903 PEER_FLAG_ORF_PREFIX_SM
))
6904 vty_out(vty
, " send");
6906 vty_out(vty
, " receive");
6910 /* Route reflector client. */
6911 if (peergroup_af_flag_check(peer
, afi
, safi
,
6912 PEER_FLAG_REFLECTOR_CLIENT
)) {
6913 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6916 /* next-hop-self force */
6917 if (peergroup_af_flag_check(peer
, afi
, safi
,
6918 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6919 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6923 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6924 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6927 /* remove-private-AS */
6928 if (peergroup_af_flag_check(peer
, afi
, safi
,
6929 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6930 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6934 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6935 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6936 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6940 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6941 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6942 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6945 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6946 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6947 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6951 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6952 vty_out(vty
, " neighbor %s as-override\n", addr
);
6955 /* send-community print. */
6956 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6957 if (peergroup_af_flag_check(peer
, afi
, safi
,
6958 PEER_FLAG_SEND_COMMUNITY
)
6959 && peergroup_af_flag_check(peer
, afi
, safi
,
6960 PEER_FLAG_SEND_EXT_COMMUNITY
)
6961 && peergroup_af_flag_check(
6963 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6964 vty_out(vty
, " neighbor %s send-community all\n",
6966 } else if (peergroup_af_flag_check(
6968 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6969 vty_out(vty
, " neighbor %s send-community large\n",
6971 } else if (peergroup_af_flag_check(
6973 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6974 vty_out(vty
, " neighbor %s send-community extended\n",
6976 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6977 PEER_FLAG_SEND_COMMUNITY
)) {
6978 vty_out(vty
, " neighbor %s send-community\n", addr
);
6981 if (!peer_af_flag_check(peer
, afi
, safi
,
6982 PEER_FLAG_SEND_COMMUNITY
)
6983 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6984 PEER_FLAG_SEND_COMMUNITY
))
6985 && !peer_af_flag_check(peer
, afi
, safi
,
6986 PEER_FLAG_SEND_EXT_COMMUNITY
)
6988 || peer_af_flag_check(g_peer
, afi
, safi
,
6989 PEER_FLAG_SEND_EXT_COMMUNITY
))
6990 && !peer_af_flag_check(peer
, afi
, safi
,
6991 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6992 && (!g_peer
|| peer_af_flag_check(
6994 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6995 vty_out(vty
, " no neighbor %s send-community all\n",
6998 if (!peer_af_flag_check(peer
, afi
, safi
,
6999 PEER_FLAG_SEND_LARGE_COMMUNITY
)
7001 || peer_af_flag_check(
7003 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
7005 " no neighbor %s send-community large\n",
7009 if (!peer_af_flag_check(peer
, afi
, safi
,
7010 PEER_FLAG_SEND_EXT_COMMUNITY
)
7012 || peer_af_flag_check(
7014 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
7016 " no neighbor %s send-community extended\n",
7020 if (!peer_af_flag_check(peer
, afi
, safi
,
7021 PEER_FLAG_SEND_COMMUNITY
)
7022 && (!g_peer
|| peer_af_flag_check(
7024 PEER_FLAG_SEND_COMMUNITY
))) {
7026 " no neighbor %s send-community\n",
7032 /* Default information */
7033 if (peergroup_af_flag_check(peer
, afi
, safi
,
7034 PEER_FLAG_DEFAULT_ORIGINATE
)
7036 && ((peer
->default_rmap
[afi
][safi
].name
7037 && !g_peer
->default_rmap
[afi
][safi
].name
)
7038 || (!peer
->default_rmap
[afi
][safi
].name
7039 && g_peer
->default_rmap
[afi
][safi
].name
)
7040 || (peer
->default_rmap
[afi
][safi
].name
7041 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
7042 g_peer
->default_rmap
[afi
][safi
].name
))))) {
7043 vty_out(vty
, " neighbor %s default-originate", addr
);
7044 if (peer
->default_rmap
[afi
][safi
].name
)
7045 vty_out(vty
, " route-map %s",
7046 peer
->default_rmap
[afi
][safi
].name
);
7050 /* Soft reconfiguration inbound. */
7051 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7052 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7056 /* maximum-prefix. */
7057 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
7058 if (!peer_group_active(peer
)
7059 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
7060 || g_peer
->pmax_threshold
[afi
][safi
]
7061 != peer
->pmax_threshold
[afi
][safi
]
7062 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
7063 PEER_FLAG_MAX_PREFIX_WARNING
)
7064 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7065 PEER_FLAG_MAX_PREFIX_WARNING
)) {
7066 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7067 peer
->pmax
[afi
][safi
]);
7068 if (peer
->pmax_threshold
[afi
][safi
]
7069 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7071 peer
->pmax_threshold
[afi
][safi
]);
7072 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7073 PEER_FLAG_MAX_PREFIX_WARNING
))
7074 vty_out(vty
, " warning-only");
7075 if (peer
->pmax_restart
[afi
][safi
])
7076 vty_out(vty
, " restart %u",
7077 peer
->pmax_restart
[afi
][safi
]);
7081 /* Route server client. */
7082 if (peergroup_af_flag_check(peer
, afi
, safi
,
7083 PEER_FLAG_RSERVER_CLIENT
)) {
7084 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7087 /* Nexthop-local unchanged. */
7088 if (peergroup_af_flag_check(peer
, afi
, safi
,
7089 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7090 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7093 /* allowas-in <1-10> */
7094 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7095 if (!peer_group_active(peer
)
7096 || !peer_af_flag_check(g_peer
, afi
, safi
,
7097 PEER_FLAG_ALLOWAS_IN
)
7098 || peer
->allowas_in
[afi
][safi
]
7099 != g_peer
->allowas_in
[afi
][safi
]) {
7100 if (peer
->allowas_in
[afi
][safi
] == 3) {
7101 vty_out(vty
, " neighbor %s allowas-in\n",
7104 vty_out(vty
, " neighbor %s allowas-in %d\n",
7105 addr
, peer
->allowas_in
[afi
][safi
]);
7110 /* allowas-in origin */
7111 else if (peer_af_flag_check(peer
, afi
, safi
,
7112 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7113 if (!peer_group_active(peer
)
7114 || !peer_af_flag_check(g_peer
, afi
, safi
,
7115 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7116 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7121 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7122 if (!peer_group_active(peer
)
7123 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
7124 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
7125 if (peer
->weight
[afi
][safi
]) {
7126 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7127 peer
->weight
[afi
][safi
]);
7132 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7134 /* atribute-unchanged. */
7135 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7136 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
)
7137 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7139 if (!peer_group_active(peer
)
7140 || peergroup_af_flag_check(peer
, afi
, safi
,
7141 PEER_FLAG_AS_PATH_UNCHANGED
)
7142 || peergroup_af_flag_check(peer
, afi
, safi
,
7143 PEER_FLAG_NEXTHOP_UNCHANGED
)
7144 || peergroup_af_flag_check(peer
, afi
, safi
,
7145 PEER_FLAG_MED_UNCHANGED
)) {
7148 " neighbor %s attribute-unchanged%s%s%s\n",
7150 peer_af_flag_check(peer
, afi
, safi
,
7151 PEER_FLAG_AS_PATH_UNCHANGED
)
7154 peer_af_flag_check(peer
, afi
, safi
,
7155 PEER_FLAG_NEXTHOP_UNCHANGED
)
7158 peer_af_flag_check(peer
, afi
, safi
,
7159 PEER_FLAG_MED_UNCHANGED
)
7166 /* Address family based peer configuration display. */
7167 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7171 struct peer_group
*group
;
7172 struct listnode
*node
, *nnode
;
7175 vty_frame(vty
, " !\n address-family ");
7176 if (afi
== AFI_IP
) {
7177 if (safi
== SAFI_UNICAST
)
7178 vty_frame(vty
, "ipv4 unicast");
7179 else if (safi
== SAFI_LABELED_UNICAST
)
7180 vty_frame(vty
, "ipv4 labeled-unicast");
7181 else if (safi
== SAFI_MULTICAST
)
7182 vty_frame(vty
, "ipv4 multicast");
7183 else if (safi
== SAFI_MPLS_VPN
)
7184 vty_frame(vty
, "ipv4 vpn");
7185 else if (safi
== SAFI_ENCAP
)
7186 vty_frame(vty
, "ipv4 encap");
7187 else if (safi
== SAFI_FLOWSPEC
)
7188 vty_frame(vty
, "ipv4 flowspec");
7189 } else if (afi
== AFI_IP6
) {
7190 if (safi
== SAFI_UNICAST
)
7191 vty_frame(vty
, "ipv6 unicast");
7192 else if (safi
== SAFI_LABELED_UNICAST
)
7193 vty_frame(vty
, "ipv6 labeled-unicast");
7194 else if (safi
== SAFI_MULTICAST
)
7195 vty_frame(vty
, "ipv6 multicast");
7196 else if (safi
== SAFI_MPLS_VPN
)
7197 vty_frame(vty
, "ipv6 vpn");
7198 else if (safi
== SAFI_ENCAP
)
7199 vty_frame(vty
, "ipv6 encap");
7200 else if (safi
== SAFI_FLOWSPEC
)
7201 vty_frame(vty
, "ipv6 flowspec");
7202 } else if (afi
== AFI_L2VPN
) {
7203 if (safi
== SAFI_EVPN
)
7204 vty_frame(vty
, "l2vpn evpn");
7206 vty_frame(vty
, "\n");
7208 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7210 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7212 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7214 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7215 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7217 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7218 /* Skip dynamic neighbors. */
7219 if (peer_dynamic_neighbor(peer
))
7222 /* Do not display doppelganger peers */
7223 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7224 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7227 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7228 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7230 if (safi
== SAFI_EVPN
)
7231 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7233 if (safi
== SAFI_UNICAST
) {
7234 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7235 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7236 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7238 vty_out(vty
, " export vpn\n");
7240 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7241 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7243 vty_out(vty
, " import vpn\n");
7245 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7246 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7247 struct listnode
*node
;
7250 for (ALL_LIST_ELEMENTS_RO(
7251 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7253 vty_out(vty
, " import vrf %s\n", name
);
7257 vty_endframe(vty
, " exit-address-family\n");
7260 int bgp_config_write(struct vty
*vty
)
7264 struct peer_group
*group
;
7266 struct listnode
*node
, *nnode
;
7267 struct listnode
*mnode
, *mnnode
;
7269 /* BGP Multiple instance. */
7270 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7271 vty_out(vty
, "no bgp multiple-instance\n");
7275 /* BGP Config type. */
7276 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7277 vty_out(vty
, "bgp config-type cisco\n");
7281 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7282 vty_out(vty
, "bgp route-map delay-timer %u\n",
7283 bm
->rmap_update_timer
);
7286 vty_out(vty
, "!\n");
7288 /* BGP configuration. */
7289 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7291 /* skip all auto created vrf as they dont have user config */
7292 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7295 /* Router bgp ASN */
7296 vty_out(vty
, "router bgp %u", bgp
->as
);
7298 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7300 vty_out(vty
, " %s %s",
7302 == BGP_INSTANCE_TYPE_VIEW
)
7309 /* No Synchronization */
7310 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7311 vty_out(vty
, " no synchronization\n");
7313 /* BGP fast-external-failover. */
7314 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7315 vty_out(vty
, " no bgp fast-external-failover\n");
7317 /* BGP router ID. */
7318 if (bgp
->router_id_static
.s_addr
!= 0)
7319 vty_out(vty
, " bgp router-id %s\n",
7320 inet_ntoa(bgp
->router_id_static
));
7322 /* BGP log-neighbor-changes. */
7323 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7324 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7325 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7327 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7331 /* BGP configuration. */
7332 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7333 vty_out(vty
, " bgp always-compare-med\n");
7335 /* BGP default ipv4-unicast. */
7336 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7337 vty_out(vty
, " no bgp default ipv4-unicast\n");
7339 /* BGP default local-preference. */
7340 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7341 vty_out(vty
, " bgp default local-preference %u\n",
7342 bgp
->default_local_pref
);
7344 /* BGP default show-hostname */
7345 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7346 != DFLT_BGP_SHOW_HOSTNAME
)
7347 vty_out(vty
, " %sbgp default show-hostname\n",
7348 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7352 /* BGP default subgroup-pkt-queue-max. */
7353 if (bgp
->default_subgroup_pkt_queue_max
7354 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7355 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7356 bgp
->default_subgroup_pkt_queue_max
);
7358 /* BGP default autoshutdown neighbors */
7359 if (bgp
->autoshutdown
)
7360 vty_out(vty
, " bgp default shutdown\n");
7362 /* BGP client-to-client reflection. */
7363 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7364 vty_out(vty
, " no bgp client-to-client reflection\n");
7366 /* BGP cluster ID. */
7367 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7368 vty_out(vty
, " bgp cluster-id %s\n",
7369 inet_ntoa(bgp
->cluster_id
));
7371 /* Disable ebgp connected nexthop check */
7372 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7374 " bgp disable-ebgp-connected-route-check\n");
7376 /* Confederation identifier*/
7377 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7378 vty_out(vty
, " bgp confederation identifier %i\n",
7381 /* Confederation peer */
7382 if (bgp
->confed_peers_cnt
> 0) {
7385 vty_out(vty
, " bgp confederation peers");
7387 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7388 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7393 /* BGP enforce-first-as. */
7394 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7395 vty_out(vty
, " bgp enforce-first-as\n");
7397 /* BGP deterministic-med. */
7398 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7399 != DFLT_BGP_DETERMINISTIC_MED
)
7400 vty_out(vty
, " %sbgp deterministic-med\n",
7401 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7405 /* BGP update-delay. */
7406 bgp_config_write_update_delay(vty
, bgp
);
7408 if (bgp
->v_maxmed_onstartup
7409 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7410 vty_out(vty
, " bgp max-med on-startup %u",
7411 bgp
->v_maxmed_onstartup
);
7412 if (bgp
->maxmed_onstartup_value
7413 != BGP_MAXMED_VALUE_DEFAULT
)
7415 bgp
->maxmed_onstartup_value
);
7418 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7419 vty_out(vty
, " bgp max-med administrative");
7420 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7421 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7426 bgp_config_write_wpkt_quanta(vty
, bgp
);
7428 bgp_config_write_rpkt_quanta(vty
, bgp
);
7431 bgp_config_write_coalesce_time(vty
, bgp
);
7433 /* BGP graceful-restart. */
7434 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7436 " bgp graceful-restart stalepath-time %u\n",
7437 bgp
->stalepath_time
);
7438 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7439 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7441 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7442 vty_out(vty
, " bgp graceful-restart\n");
7444 /* BGP graceful-shutdown */
7445 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7446 vty_out(vty
, " bgp graceful-shutdown\n");
7448 /* BGP graceful-restart Preserve State F bit. */
7449 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7451 " bgp graceful-restart preserve-fw-state\n");
7453 /* BGP bestpath method. */
7454 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7455 vty_out(vty
, " bgp bestpath as-path ignore\n");
7456 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7457 vty_out(vty
, " bgp bestpath as-path confed\n");
7459 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7460 if (bgp_flag_check(bgp
,
7461 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7463 " bgp bestpath as-path multipath-relax as-set\n");
7466 " bgp bestpath as-path multipath-relax\n");
7470 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7472 " bgp route-reflector allow-outbound-policy\n");
7474 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7475 vty_out(vty
, " bgp bestpath compare-routerid\n");
7476 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7477 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7478 vty_out(vty
, " bgp bestpath med");
7479 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7480 vty_out(vty
, " confed");
7481 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7482 vty_out(vty
, " missing-as-worst");
7486 /* BGP network import check. */
7487 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7488 != DFLT_BGP_IMPORT_CHECK
)
7489 vty_out(vty
, " %sbgp network import-check\n",
7490 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7494 /* BGP flag dampening. */
7495 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7496 BGP_CONFIG_DAMPENING
))
7497 bgp_config_write_damp(vty
);
7499 /* BGP timers configuration. */
7500 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7501 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7502 vty_out(vty
, " timers bgp %u %u\n",
7503 bgp
->default_keepalive
, bgp
->default_holdtime
);
7506 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7507 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7510 /* Normal neighbor configuration. */
7511 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7512 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7513 bgp_config_write_peer_global(vty
, bgp
, peer
);
7516 /* listen range and limit for dynamic BGP neighbors */
7517 bgp_config_write_listen(vty
, bgp
);
7519 /* No auto-summary */
7520 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7521 vty_out(vty
, " no auto-summary\n");
7523 /* IPv4 unicast configuration. */
7524 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7526 /* IPv4 multicast configuration. */
7527 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7529 /* IPv4 labeled-unicast configuration. */
7530 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7532 /* IPv4 VPN configuration. */
7533 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7535 /* ENCAPv4 configuration. */
7536 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7538 /* FLOWSPEC v4 configuration. */
7539 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7541 /* IPv6 unicast configuration. */
7542 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7544 /* IPv6 multicast configuration. */
7545 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7547 /* IPv6 labeled-unicast configuration. */
7548 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7549 SAFI_LABELED_UNICAST
);
7551 /* IPv6 VPN configuration. */
7552 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7554 /* ENCAPv6 configuration. */
7555 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7557 /* FLOWSPEC v6 configuration. */
7558 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7560 /* EVPN configuration. */
7561 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7564 bgp_rfapi_cfg_write(vty
, bgp
);
7567 vty_out(vty
, "!\n");
7572 void bgp_master_init(struct thread_master
*master
)
7576 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7579 bm
->bgp
= list_new();
7580 bm
->listen_sockets
= list_new();
7581 bm
->port
= BGP_PORT_DEFAULT
;
7582 bm
->master
= master
;
7583 bm
->start_time
= bgp_clock();
7584 bm
->t_rmap_update
= NULL
;
7585 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7587 bgp_process_queue_init();
7589 /* init the rd id space.
7590 assign 0th index in the bitfield,
7591 so that we start with id 1
7593 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7594 bf_assign_zero_index(bm
->rd_idspace
);
7596 /* Enable multiple instances by default. */
7597 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7599 /* mpls label dynamic allocation pool */
7600 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7602 QOBJ_REG(bm
, bgp_master
);
7606 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7607 * instance delete (non-default only) or BGP exit.
7609 static void bgp_if_finish(struct bgp
*bgp
)
7611 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7612 struct interface
*ifp
;
7614 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7617 FOR_ALL_INTERFACES (vrf
, ifp
) {
7618 struct listnode
*c_node
, *c_nnode
;
7619 struct connected
*c
;
7621 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7622 bgp_connected_delete(bgp
, c
);
7626 extern void bgp_snmp_init(void);
7628 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7630 struct vrf
*vrf
= NULL
;
7631 struct listnode
*next
;
7634 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7635 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7636 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7639 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7640 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7643 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7647 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7648 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7649 {.completions
= NULL
},
7652 static void bgp_pthreads_init()
7656 struct frr_pthread_attr io
= {
7658 .start
= frr_pthread_attr_default
.start
,
7659 .stop
= frr_pthread_attr_default
.stop
,
7661 struct frr_pthread_attr ka
= {
7662 .id
= PTHREAD_KEEPALIVES
,
7663 .start
= bgp_keepalives_start
,
7664 .stop
= bgp_keepalives_stop
,
7666 frr_pthread_new(&io
, "BGP I/O thread");
7667 frr_pthread_new(&ka
, "BGP Keepalives thread");
7670 void bgp_pthreads_run()
7672 struct frr_pthread
*io
= frr_pthread_get(PTHREAD_IO
);
7673 struct frr_pthread
*ka
= frr_pthread_get(PTHREAD_KEEPALIVES
);
7675 frr_pthread_run(io
, NULL
);
7676 frr_pthread_run(ka
, NULL
);
7678 /* Wait until threads are ready. */
7679 frr_pthread_wait_running(io
);
7680 frr_pthread_wait_running(ka
);
7683 void bgp_pthreads_finish()
7685 frr_pthread_stop_all();
7686 frr_pthread_finish();
7692 /* allocates some vital data structures used by peer commands in
7695 /* pre-init pthreads */
7696 bgp_pthreads_init();
7699 bgp_zebra_init(bm
->master
);
7702 vnc_zebra_init(bm
->master
);
7705 /* BGP VTY commands installation. */
7713 bgp_route_map_init();
7714 bgp_scan_vty_init();
7719 bgp_ethernetvpn_init();
7720 bgp_flowspec_vty_init();
7722 /* Access list initialize. */
7724 access_list_add_hook(peer_distribute_update
);
7725 access_list_delete_hook(peer_distribute_update
);
7727 /* Filter list initialize. */
7729 as_list_add_hook(peer_aslist_add
);
7730 as_list_delete_hook(peer_aslist_del
);
7732 /* Prefix list initialize.*/
7734 prefix_list_add_hook(peer_prefix_list_update
);
7735 prefix_list_delete_hook(peer_prefix_list_update
);
7737 /* Community list initialize. */
7738 bgp_clist
= community_list_init();
7743 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7746 void bgp_terminate(void)
7750 struct listnode
*node
, *nnode
;
7751 struct listnode
*mnode
, *mnnode
;
7755 /* Close the listener sockets first as this prevents peers from
7757 * to reconnect on receiving the peer unconfig message. In the presence
7758 * of a large number of peers this will ensure that no peer is left with
7759 * a dangling connection
7761 /* reverse bgp_master_init */
7764 if (bm
->listen_sockets
)
7765 list_delete_and_null(&bm
->listen_sockets
);
7767 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7768 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7769 if (peer
->status
== Established
7770 || peer
->status
== OpenSent
7771 || peer
->status
== OpenConfirm
)
7772 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7773 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7775 if (bm
->process_main_queue
)
7776 work_queue_free_and_null(&bm
->process_main_queue
);
7778 if (bm
->t_rmap_update
)
7779 BGP_TIMER_OFF(bm
->t_rmap_update
);