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 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5951 peer
->pmax
[afi
][safi
] = max
;
5952 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5953 peer
->pmax_restart
[afi
][safi
] = restart
;
5955 SET_FLAG(peer
->af_flags
[afi
][safi
],
5956 PEER_FLAG_MAX_PREFIX_WARNING
);
5958 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5959 PEER_FLAG_MAX_PREFIX_WARNING
);
5961 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5962 group
= peer
->group
;
5963 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5964 SET_FLAG(peer
->af_flags
[afi
][safi
],
5965 PEER_FLAG_MAX_PREFIX
);
5966 peer
->pmax
[afi
][safi
] = max
;
5967 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5968 peer
->pmax_restart
[afi
][safi
] = restart
;
5970 SET_FLAG(peer
->af_flags
[afi
][safi
],
5971 PEER_FLAG_MAX_PREFIX_WARNING
);
5973 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5974 PEER_FLAG_MAX_PREFIX_WARNING
);
5976 if ((peer
->status
== Established
)
5977 && (peer
->afc
[afi
][safi
]))
5978 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5981 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5982 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5988 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5990 struct peer_group
*group
;
5991 struct listnode
*node
, *nnode
;
5993 /* apply peer-group config */
5994 if (peer_group_active(peer
)) {
5995 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5996 PEER_FLAG_MAX_PREFIX
))
5997 SET_FLAG(peer
->af_flags
[afi
][safi
],
5998 PEER_FLAG_MAX_PREFIX
);
6000 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6001 PEER_FLAG_MAX_PREFIX
);
6003 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
6004 PEER_FLAG_MAX_PREFIX_WARNING
))
6005 SET_FLAG(peer
->af_flags
[afi
][safi
],
6006 PEER_FLAG_MAX_PREFIX_WARNING
);
6008 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6009 PEER_FLAG_MAX_PREFIX_WARNING
);
6011 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
6012 peer
->pmax_threshold
[afi
][safi
] =
6013 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
6014 peer
->pmax_restart
[afi
][safi
] =
6015 peer
->group
->conf
->pmax_restart
[afi
][safi
];
6019 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6020 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
6021 peer
->pmax
[afi
][safi
] = 0;
6022 peer
->pmax_threshold
[afi
][safi
] = 0;
6023 peer
->pmax_restart
[afi
][safi
] = 0;
6025 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
6028 group
= peer
->group
;
6029 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6030 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6031 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6032 PEER_FLAG_MAX_PREFIX_WARNING
);
6033 peer
->pmax
[afi
][safi
] = 0;
6034 peer
->pmax_threshold
[afi
][safi
] = 0;
6035 peer
->pmax_restart
[afi
][safi
] = 0;
6040 int is_ebgp_multihop_configured(struct peer
*peer
)
6042 struct peer_group
*group
;
6043 struct listnode
*node
, *nnode
;
6046 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6047 group
= peer
->group
;
6048 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6049 && (group
->conf
->ttl
!= 1))
6052 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6053 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6054 && (peer1
->ttl
!= 1))
6058 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6064 /* Set # of hops between us and BGP peer. */
6065 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6067 struct peer_group
*group
;
6068 struct listnode
*node
, *nnode
;
6071 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6072 gtsm_hops
, peer
->host
);
6074 /* We cannot configure ttl-security hops when ebgp-multihop is already
6075 set. For non peer-groups, the check is simple. For peer-groups,
6077 slightly messy, because we need to check both the peer-group
6079 and all peer-group members for any trace of ebgp-multihop
6081 before actually applying the ttl-security rules. Cisco really made a
6082 mess of this configuration parameter, and OpenBGPD got it right.
6085 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6086 if (is_ebgp_multihop_configured(peer
))
6087 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6089 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6090 peer
->gtsm_hops
= gtsm_hops
;
6092 /* Calling ebgp multihop also resets the session.
6093 * On restart, NHT will get setup correctly as will the
6094 * min & max ttls on the socket. The return value is
6097 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6102 group
= peer
->group
;
6103 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6105 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6107 /* Calling ebgp multihop also resets the
6109 * On restart, NHT will get setup correctly as
6111 * min & max ttls on the socket. The return
6115 peer_ebgp_multihop_set(peer
, MAXTTL
);
6119 /* Post the first gtsm setup or if its ibgp, maxttl setting
6121 * necessary, just set the minttl.
6123 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6124 peer
->gtsm_hops
= gtsm_hops
;
6127 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6128 MAXTTL
+ 1 - gtsm_hops
);
6129 if ((peer
->status
< Established
) && peer
->doppelganger
6130 && (peer
->doppelganger
->fd
>= 0))
6131 sockopt_minttl(peer
->su
.sa
.sa_family
,
6132 peer
->doppelganger
->fd
,
6133 MAXTTL
+ 1 - gtsm_hops
);
6135 group
= peer
->group
;
6136 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6138 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6140 /* Change setting of existing peer
6141 * established then change value (may break
6143 * not established yet (teardown session and
6145 * no session then do nothing (will get
6146 * handled by next connection)
6148 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6150 peer
->su
.sa
.sa_family
, peer
->fd
,
6151 MAXTTL
+ 1 - peer
->gtsm_hops
);
6152 if ((peer
->status
< Established
)
6153 && peer
->doppelganger
6154 && (peer
->doppelganger
->fd
>= 0))
6155 sockopt_minttl(peer
->su
.sa
.sa_family
,
6156 peer
->doppelganger
->fd
,
6157 MAXTTL
+ 1 - gtsm_hops
);
6165 int peer_ttl_security_hops_unset(struct peer
*peer
)
6167 struct peer_group
*group
;
6168 struct listnode
*node
, *nnode
;
6171 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6174 /* if a peer-group member, then reset to peer-group default rather than
6176 if (peer_group_active(peer
))
6177 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6179 peer
->gtsm_hops
= 0;
6181 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6182 /* Invoking ebgp_multihop_set will set the TTL back to the
6184 * value as well as restting the NHT and such. The session is
6187 if (peer
->sort
== BGP_PEER_EBGP
)
6188 ret
= peer_ebgp_multihop_unset(peer
);
6191 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6194 if ((peer
->status
< Established
) && peer
->doppelganger
6195 && (peer
->doppelganger
->fd
>= 0))
6196 sockopt_minttl(peer
->su
.sa
.sa_family
,
6197 peer
->doppelganger
->fd
, 0);
6200 group
= peer
->group
;
6201 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6202 peer
->gtsm_hops
= 0;
6203 if (peer
->sort
== BGP_PEER_EBGP
)
6204 ret
= peer_ebgp_multihop_unset(peer
);
6207 sockopt_minttl(peer
->su
.sa
.sa_family
,
6210 if ((peer
->status
< Established
)
6211 && peer
->doppelganger
6212 && (peer
->doppelganger
->fd
>= 0))
6213 sockopt_minttl(peer
->su
.sa
.sa_family
,
6214 peer
->doppelganger
->fd
,
6224 * If peer clear is invoked in a loop for all peers on the BGP instance,
6225 * it may end up freeing the doppelganger, and if this was the next node
6226 * to the current node, we would end up accessing the freed next node.
6227 * Pass along additional parameter which can be updated if next node
6228 * is freed; only required when walking the peer list on BGP instance.
6230 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6232 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6233 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6234 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6235 if (peer
->t_pmax_restart
) {
6236 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6237 if (bgp_debug_neighbor_events(peer
))
6239 "%s Maximum-prefix restart timer canceled",
6242 BGP_EVENT_ADD(peer
, BGP_Start
);
6246 peer
->v_start
= BGP_INIT_START_TIMER
;
6247 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6248 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6249 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6251 bgp_session_reset_safe(peer
, nnode
);
6256 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6257 enum bgp_clear_type stype
)
6259 struct peer_af
*paf
;
6261 if (peer
->status
!= Established
)
6264 if (!peer
->afc
[afi
][safi
])
6265 return BGP_ERR_AF_UNCONFIGURED
;
6267 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6269 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6270 /* Clear the "neighbor x.x.x.x default-originate" flag */
6271 paf
= peer_af_find(peer
, afi
, safi
);
6272 if (paf
&& paf
->subgroup
6273 && CHECK_FLAG(paf
->subgroup
->sflags
,
6274 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6275 UNSET_FLAG(paf
->subgroup
->sflags
,
6276 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6278 bgp_announce_route(peer
, afi
, safi
);
6281 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6282 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6283 PEER_CAP_ORF_PREFIX_SM_ADV
)
6284 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6285 PEER_CAP_ORF_PREFIX_RM_RCV
)
6286 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6287 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6288 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6289 uint8_t prefix_type
;
6291 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6292 PEER_CAP_ORF_PREFIX_RM_RCV
))
6293 prefix_type
= ORF_TYPE_PREFIX
;
6295 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6297 if (filter
->plist
[FILTER_IN
].plist
) {
6298 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6299 PEER_STATUS_ORF_PREFIX_SEND
))
6300 bgp_route_refresh_send(
6301 peer
, afi
, safi
, prefix_type
,
6303 bgp_route_refresh_send(peer
, afi
, safi
,
6305 REFRESH_IMMEDIATE
, 0);
6307 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6308 PEER_STATUS_ORF_PREFIX_SEND
))
6309 bgp_route_refresh_send(
6310 peer
, afi
, safi
, prefix_type
,
6311 REFRESH_IMMEDIATE
, 1);
6313 bgp_route_refresh_send(peer
, afi
, safi
,
6320 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6321 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6322 /* If neighbor has soft reconfiguration inbound flag.
6323 Use Adj-RIB-In database. */
6324 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6325 PEER_FLAG_SOFT_RECONFIG
))
6326 bgp_soft_reconfig_in(peer
, afi
, safi
);
6328 /* If neighbor has route refresh capability, send route
6330 message to the peer. */
6331 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6332 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6333 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6336 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6342 /* Display peer uptime.*/
6343 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, uint8_t use_json
,
6346 time_t uptime1
, epoch_tbuf
;
6349 /* Check buffer length. */
6350 if (len
< BGP_UPTIME_LEN
) {
6352 zlog_warn("peer_uptime (): buffer shortage %lu",
6353 (unsigned long)len
);
6354 /* XXX: should return status instead of buf... */
6355 snprintf(buf
, len
, "<error> ");
6360 /* If there is no connection has been done before print `never'. */
6363 json_object_string_add(json
, "peerUptime", "never");
6364 json_object_int_add(json
, "peerUptimeMsec", 0);
6366 snprintf(buf
, len
, "never");
6370 /* Get current time. */
6371 uptime1
= bgp_clock();
6373 tm
= gmtime(&uptime1
);
6375 if (uptime1
< ONE_DAY_SECOND
)
6376 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6378 else if (uptime1
< ONE_WEEK_SECOND
)
6379 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6381 else if (uptime1
< ONE_YEAR_SECOND
)
6382 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6383 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6385 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6387 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6390 epoch_tbuf
= time(NULL
) - uptime1
;
6391 json_object_string_add(json
, "peerUptime", buf
);
6392 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6393 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6400 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6401 afi_t afi
, safi_t safi
)
6403 struct bgp_filter
*filter
;
6404 struct bgp_filter
*gfilter
= NULL
;
6407 int out
= FILTER_OUT
;
6410 filter
= &peer
->filter
[afi
][safi
];
6412 if (peer_group_active(peer
))
6413 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6415 /* distribute-list. */
6416 if (filter
->dlist
[in
].name
)
6417 if (!gfilter
|| !gfilter
->dlist
[in
].name
6418 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6420 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6421 addr
, filter
->dlist
[in
].name
);
6424 if (filter
->dlist
[out
].name
&& !gfilter
) {
6425 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6426 filter
->dlist
[out
].name
);
6430 if (filter
->plist
[in
].name
)
6431 if (!gfilter
|| !gfilter
->plist
[in
].name
6432 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6434 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6435 filter
->plist
[in
].name
);
6438 if (filter
->plist
[out
].name
)
6439 if (!gfilter
|| !gfilter
->plist
[out
].name
6440 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6442 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6443 filter
->plist
[out
].name
);
6447 if (filter
->map
[RMAP_IN
].name
)
6448 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6449 || strcmp(filter
->map
[RMAP_IN
].name
,
6450 gfilter
->map
[RMAP_IN
].name
)
6452 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6453 filter
->map
[RMAP_IN
].name
);
6456 if (filter
->map
[RMAP_OUT
].name
)
6457 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6458 || strcmp(filter
->map
[RMAP_OUT
].name
,
6459 gfilter
->map
[RMAP_OUT
].name
)
6461 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6462 filter
->map
[RMAP_OUT
].name
);
6465 /* unsuppress-map */
6466 if (filter
->usmap
.name
&& !gfilter
) {
6467 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6468 filter
->usmap
.name
);
6472 if (filter
->aslist
[in
].name
)
6473 if (!gfilter
|| !gfilter
->aslist
[in
].name
6474 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6476 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6477 filter
->aslist
[in
].name
);
6480 if (filter
->aslist
[out
].name
&& !gfilter
) {
6481 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6482 filter
->aslist
[out
].name
);
6486 /* BGP peer configuration display function. */
6487 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6490 struct peer
*g_peer
= NULL
;
6491 char buf
[SU_ADDRSTRLEN
];
6493 int if_pg_printed
= FALSE
;
6494 int if_ras_printed
= FALSE
;
6496 /* Skip dynamic neighbors. */
6497 if (peer_dynamic_neighbor(peer
))
6501 addr
= peer
->conf_if
;
6505 /************************************
6506 ****** Global to the neighbor ******
6507 ************************************/
6508 if (peer
->conf_if
) {
6509 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6510 vty_out(vty
, " neighbor %s interface v6only", addr
);
6512 vty_out(vty
, " neighbor %s interface", addr
);
6514 if (peer_group_active(peer
)) {
6515 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6516 if_pg_printed
= TRUE
;
6517 } else if (peer
->as_type
== AS_SPECIFIED
) {
6518 vty_out(vty
, " remote-as %u", peer
->as
);
6519 if_ras_printed
= TRUE
;
6520 } else if (peer
->as_type
== AS_INTERNAL
) {
6521 vty_out(vty
, " remote-as internal");
6522 if_ras_printed
= TRUE
;
6523 } else if (peer
->as_type
== AS_EXTERNAL
) {
6524 vty_out(vty
, " remote-as external");
6525 if_ras_printed
= TRUE
;
6531 /* remote-as and peer-group */
6532 /* peer is a member of a peer-group */
6533 if (peer_group_active(peer
)) {
6534 g_peer
= peer
->group
->conf
;
6536 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6537 if (peer
->as_type
== AS_SPECIFIED
) {
6538 vty_out(vty
, " neighbor %s remote-as %u\n",
6540 } else if (peer
->as_type
== AS_INTERNAL
) {
6542 " neighbor %s remote-as internal\n",
6544 } else if (peer
->as_type
== AS_EXTERNAL
) {
6546 " neighbor %s remote-as external\n",
6551 /* For swpX peers we displayed the peer-group
6552 * via 'neighbor swpX interface peer-group WORD' */
6554 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6558 /* peer is NOT a member of a peer-group */
6560 /* peer is a peer-group, declare the peer-group */
6561 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6562 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6565 if (!if_ras_printed
) {
6566 if (peer
->as_type
== AS_SPECIFIED
) {
6567 vty_out(vty
, " neighbor %s remote-as %u\n",
6569 } else if (peer
->as_type
== AS_INTERNAL
) {
6571 " neighbor %s remote-as internal\n",
6573 } else if (peer
->as_type
== AS_EXTERNAL
) {
6575 " neighbor %s remote-as external\n",
6582 if (peer
->change_local_as
) {
6583 if (!peer_group_active(peer
)
6584 || peer
->change_local_as
!= g_peer
->change_local_as
6585 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6586 != CHECK_FLAG(g_peer
->flags
,
6587 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6588 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6589 != CHECK_FLAG(g_peer
->flags
,
6590 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6591 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6592 peer
->change_local_as
,
6593 CHECK_FLAG(peer
->flags
,
6594 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6597 CHECK_FLAG(peer
->flags
,
6598 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6606 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6610 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6611 if (!peer_group_active(peer
)
6612 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6613 || peer
->tx_shutdown_message
) {
6614 if (peer
->tx_shutdown_message
)
6616 " neighbor %s shutdown message %s\n",
6617 addr
, peer
->tx_shutdown_message
);
6619 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6624 if (peer
->bfd_info
) {
6625 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6626 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6631 if (peer
->password
) {
6632 if (!peer_group_active(peer
) || !g_peer
->password
6633 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6634 vty_out(vty
, " neighbor %s password %s\n", addr
,
6640 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6641 if (!peer_group_active(peer
)) {
6642 vty_out(vty
, " neighbor %s solo\n", addr
);
6647 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6648 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6651 /* Local interface name */
6653 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6657 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6658 if (!peer_group_active(peer
)
6659 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6660 vty_out(vty
, " neighbor %s passive\n", addr
);
6665 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6666 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6667 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6668 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6673 /* ttl-security hops */
6674 if (peer
->gtsm_hops
!= 0) {
6675 if (!peer_group_active(peer
)
6676 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6677 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6678 addr
, peer
->gtsm_hops
);
6682 /* disable-connected-check */
6683 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6684 if (!peer_group_active(peer
)
6685 || !CHECK_FLAG(g_peer
->flags
,
6686 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6687 vty_out(vty
, " neighbor %s disable-connected-check\n",
6693 if (peer
->update_if
) {
6694 if (!peer_group_active(peer
) || !g_peer
->update_if
6695 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6696 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6700 if (peer
->update_source
) {
6701 if (!peer_group_active(peer
) || !g_peer
->update_source
6702 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6704 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6705 sockunion2str(peer
->update_source
, buf
,
6710 /* advertisement-interval */
6711 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6712 && ((!peer_group_active(peer
)
6713 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6714 || (peer_group_active(peer
)
6715 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6716 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6721 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6722 && ((!peer_group_active(peer
)
6723 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6724 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6725 || (peer_group_active(peer
)
6726 && (peer
->keepalive
!= g_peer
->keepalive
6727 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6728 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6729 peer
->keepalive
, peer
->holdtime
);
6732 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6733 && ((!peer_group_active(peer
)
6734 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6735 || (peer_group_active(peer
)
6736 && peer
->connect
!= g_peer
->connect
)))
6739 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6743 /* capability dynamic */
6744 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6745 if (!peer_group_active(peer
)
6746 || !CHECK_FLAG(g_peer
->flags
,
6747 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6748 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6752 /* capability extended-nexthop */
6753 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6754 if (!peer_group_active(peer
)
6755 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6757 " no neighbor %s capability extended-nexthop\n",
6762 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6763 if (!peer_group_active(peer
)
6764 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6766 " neighbor %s capability extended-nexthop\n",
6771 /* dont-capability-negotiation */
6772 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6773 if (!peer_group_active(peer
)
6774 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6775 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6780 /* override-capability */
6781 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6782 if (!peer_group_active(peer
)
6783 || !CHECK_FLAG(g_peer
->flags
,
6784 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6785 vty_out(vty
, " neighbor %s override-capability\n",
6790 /* strict-capability-match */
6791 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6792 if (!peer_group_active(peer
)
6793 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6794 vty_out(vty
, " neighbor %s strict-capability-match\n",
6800 /* BGP peer configuration display function. */
6801 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6802 struct peer
*peer
, afi_t afi
, safi_t safi
)
6804 struct peer
*g_peer
= NULL
;
6807 /* Skip dynamic neighbors. */
6808 if (peer_dynamic_neighbor(peer
))
6812 addr
= peer
->conf_if
;
6816 /************************************
6817 ****** Per AF to the neighbor ******
6818 ************************************/
6819 if (peer_group_active(peer
)) {
6820 g_peer
= peer
->group
->conf
;
6822 /* If the peer-group is active but peer is not, print a 'no
6824 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6825 vty_out(vty
, " no neighbor %s activate\n", addr
);
6828 /* If the peer-group is not active but peer is, print an
6830 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6831 vty_out(vty
, " neighbor %s activate\n", addr
);
6834 if (peer
->afc
[afi
][safi
]) {
6835 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6836 if (bgp_flag_check(bgp
,
6837 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6838 vty_out(vty
, " neighbor %s activate\n",
6842 vty_out(vty
, " neighbor %s activate\n", addr
);
6844 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6845 if (!bgp_flag_check(bgp
,
6846 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6848 " no neighbor %s activate\n",
6855 /* addpath TX knobs */
6856 if (peergroup_af_flag_check(peer
, afi
, safi
,
6857 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6858 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6861 if (peergroup_af_flag_check(peer
, afi
, safi
,
6862 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6863 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6867 /* ORF capability. */
6868 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6869 || peergroup_af_flag_check(peer
, afi
, safi
,
6870 PEER_FLAG_ORF_PREFIX_RM
)) {
6871 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6873 if (peergroup_af_flag_check(peer
, afi
, safi
,
6874 PEER_FLAG_ORF_PREFIX_SM
)
6875 && peergroup_af_flag_check(peer
, afi
, safi
,
6876 PEER_FLAG_ORF_PREFIX_RM
))
6877 vty_out(vty
, " both");
6878 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6879 PEER_FLAG_ORF_PREFIX_SM
))
6880 vty_out(vty
, " send");
6882 vty_out(vty
, " receive");
6886 /* Route reflector client. */
6887 if (peergroup_af_flag_check(peer
, afi
, safi
,
6888 PEER_FLAG_REFLECTOR_CLIENT
)) {
6889 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6892 /* next-hop-self force */
6893 if (peergroup_af_flag_check(peer
, afi
, safi
,
6894 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6895 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6899 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6900 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6903 /* remove-private-AS */
6904 if (peergroup_af_flag_check(peer
, afi
, safi
,
6905 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6906 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6910 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6911 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6912 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6916 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6917 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6918 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6921 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6922 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6923 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6927 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6928 vty_out(vty
, " neighbor %s as-override\n", addr
);
6931 /* send-community print. */
6932 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6933 if (peergroup_af_flag_check(peer
, afi
, safi
,
6934 PEER_FLAG_SEND_COMMUNITY
)
6935 && peergroup_af_flag_check(peer
, afi
, safi
,
6936 PEER_FLAG_SEND_EXT_COMMUNITY
)
6937 && peergroup_af_flag_check(
6939 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6940 vty_out(vty
, " neighbor %s send-community all\n",
6942 } else if (peergroup_af_flag_check(
6944 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6945 vty_out(vty
, " neighbor %s send-community large\n",
6947 } else if (peergroup_af_flag_check(
6949 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6950 vty_out(vty
, " neighbor %s send-community extended\n",
6952 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6953 PEER_FLAG_SEND_COMMUNITY
)) {
6954 vty_out(vty
, " neighbor %s send-community\n", addr
);
6957 if (!peer_af_flag_check(peer
, afi
, safi
,
6958 PEER_FLAG_SEND_COMMUNITY
)
6959 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6960 PEER_FLAG_SEND_COMMUNITY
))
6961 && !peer_af_flag_check(peer
, afi
, safi
,
6962 PEER_FLAG_SEND_EXT_COMMUNITY
)
6964 || peer_af_flag_check(g_peer
, afi
, safi
,
6965 PEER_FLAG_SEND_EXT_COMMUNITY
))
6966 && !peer_af_flag_check(peer
, afi
, safi
,
6967 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6968 && (!g_peer
|| peer_af_flag_check(
6970 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6971 vty_out(vty
, " no neighbor %s send-community all\n",
6974 if (!peer_af_flag_check(peer
, afi
, safi
,
6975 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6977 || peer_af_flag_check(
6979 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6981 " no neighbor %s send-community large\n",
6985 if (!peer_af_flag_check(peer
, afi
, safi
,
6986 PEER_FLAG_SEND_EXT_COMMUNITY
)
6988 || peer_af_flag_check(
6990 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6992 " no neighbor %s send-community extended\n",
6996 if (!peer_af_flag_check(peer
, afi
, safi
,
6997 PEER_FLAG_SEND_COMMUNITY
)
6998 && (!g_peer
|| peer_af_flag_check(
7000 PEER_FLAG_SEND_COMMUNITY
))) {
7002 " no neighbor %s send-community\n",
7008 /* Default information */
7009 if (peergroup_af_flag_check(peer
, afi
, safi
,
7010 PEER_FLAG_DEFAULT_ORIGINATE
)
7012 && ((peer
->default_rmap
[afi
][safi
].name
7013 && !g_peer
->default_rmap
[afi
][safi
].name
)
7014 || (!peer
->default_rmap
[afi
][safi
].name
7015 && g_peer
->default_rmap
[afi
][safi
].name
)
7016 || (peer
->default_rmap
[afi
][safi
].name
7017 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
7018 g_peer
->default_rmap
[afi
][safi
].name
))))) {
7019 vty_out(vty
, " neighbor %s default-originate", addr
);
7020 if (peer
->default_rmap
[afi
][safi
].name
)
7021 vty_out(vty
, " route-map %s",
7022 peer
->default_rmap
[afi
][safi
].name
);
7026 /* Soft reconfiguration inbound. */
7027 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7028 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7032 /* maximum-prefix. */
7033 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
7034 if (!peer_group_active(peer
)
7035 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
7036 || g_peer
->pmax_threshold
[afi
][safi
]
7037 != peer
->pmax_threshold
[afi
][safi
]
7038 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
7039 PEER_FLAG_MAX_PREFIX_WARNING
)
7040 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7041 PEER_FLAG_MAX_PREFIX_WARNING
)) {
7042 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7043 peer
->pmax
[afi
][safi
]);
7044 if (peer
->pmax_threshold
[afi
][safi
]
7045 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7047 peer
->pmax_threshold
[afi
][safi
]);
7048 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7049 PEER_FLAG_MAX_PREFIX_WARNING
))
7050 vty_out(vty
, " warning-only");
7051 if (peer
->pmax_restart
[afi
][safi
])
7052 vty_out(vty
, " restart %u",
7053 peer
->pmax_restart
[afi
][safi
]);
7057 /* Route server client. */
7058 if (peergroup_af_flag_check(peer
, afi
, safi
,
7059 PEER_FLAG_RSERVER_CLIENT
)) {
7060 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7063 /* Nexthop-local unchanged. */
7064 if (peergroup_af_flag_check(peer
, afi
, safi
,
7065 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7066 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7069 /* allowas-in <1-10> */
7070 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7071 if (!peer_group_active(peer
)
7072 || !peer_af_flag_check(g_peer
, afi
, safi
,
7073 PEER_FLAG_ALLOWAS_IN
)
7074 || peer
->allowas_in
[afi
][safi
]
7075 != g_peer
->allowas_in
[afi
][safi
]) {
7076 if (peer
->allowas_in
[afi
][safi
] == 3) {
7077 vty_out(vty
, " neighbor %s allowas-in\n",
7080 vty_out(vty
, " neighbor %s allowas-in %d\n",
7081 addr
, peer
->allowas_in
[afi
][safi
]);
7086 /* allowas-in origin */
7087 else if (peer_af_flag_check(peer
, afi
, safi
,
7088 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7089 if (!peer_group_active(peer
)
7090 || !peer_af_flag_check(g_peer
, afi
, safi
,
7091 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7092 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7097 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7098 if (!peer_group_active(peer
)
7099 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
7100 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
7101 if (peer
->weight
[afi
][safi
]) {
7102 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7103 peer
->weight
[afi
][safi
]);
7108 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7110 /* atribute-unchanged. */
7111 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7112 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
)
7113 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7115 if (!peer_group_active(peer
)
7116 || peergroup_af_flag_check(peer
, afi
, safi
,
7117 PEER_FLAG_AS_PATH_UNCHANGED
)
7118 || peergroup_af_flag_check(peer
, afi
, safi
,
7119 PEER_FLAG_NEXTHOP_UNCHANGED
)
7120 || peergroup_af_flag_check(peer
, afi
, safi
,
7121 PEER_FLAG_MED_UNCHANGED
)) {
7124 " neighbor %s attribute-unchanged%s%s%s\n",
7126 peer_af_flag_check(peer
, afi
, safi
,
7127 PEER_FLAG_AS_PATH_UNCHANGED
)
7130 peer_af_flag_check(peer
, afi
, safi
,
7131 PEER_FLAG_NEXTHOP_UNCHANGED
)
7134 peer_af_flag_check(peer
, afi
, safi
,
7135 PEER_FLAG_MED_UNCHANGED
)
7142 /* Address family based peer configuration display. */
7143 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7147 struct peer_group
*group
;
7148 struct listnode
*node
, *nnode
;
7151 vty_frame(vty
, " !\n address-family ");
7152 if (afi
== AFI_IP
) {
7153 if (safi
== SAFI_UNICAST
)
7154 vty_frame(vty
, "ipv4 unicast");
7155 else if (safi
== SAFI_LABELED_UNICAST
)
7156 vty_frame(vty
, "ipv4 labeled-unicast");
7157 else if (safi
== SAFI_MULTICAST
)
7158 vty_frame(vty
, "ipv4 multicast");
7159 else if (safi
== SAFI_MPLS_VPN
)
7160 vty_frame(vty
, "ipv4 vpn");
7161 else if (safi
== SAFI_ENCAP
)
7162 vty_frame(vty
, "ipv4 encap");
7163 else if (safi
== SAFI_FLOWSPEC
)
7164 vty_frame(vty
, "ipv4 flowspec");
7165 } else if (afi
== AFI_IP6
) {
7166 if (safi
== SAFI_UNICAST
)
7167 vty_frame(vty
, "ipv6 unicast");
7168 else if (safi
== SAFI_LABELED_UNICAST
)
7169 vty_frame(vty
, "ipv6 labeled-unicast");
7170 else if (safi
== SAFI_MULTICAST
)
7171 vty_frame(vty
, "ipv6 multicast");
7172 else if (safi
== SAFI_MPLS_VPN
)
7173 vty_frame(vty
, "ipv6 vpn");
7174 else if (safi
== SAFI_ENCAP
)
7175 vty_frame(vty
, "ipv6 encap");
7176 else if (safi
== SAFI_FLOWSPEC
)
7177 vty_frame(vty
, "ipv6 flowspec");
7178 } else if (afi
== AFI_L2VPN
) {
7179 if (safi
== SAFI_EVPN
)
7180 vty_frame(vty
, "l2vpn evpn");
7182 vty_frame(vty
, "\n");
7184 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7186 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7188 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7190 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7191 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7193 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7194 /* Skip dynamic neighbors. */
7195 if (peer_dynamic_neighbor(peer
))
7198 /* Do not display doppelganger peers */
7199 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7200 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7203 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7204 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7206 if (safi
== SAFI_EVPN
)
7207 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7209 if (safi
== SAFI_UNICAST
) {
7210 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7211 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7212 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7214 vty_out(vty
, " export vpn\n");
7216 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7217 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7219 vty_out(vty
, " import vpn\n");
7221 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7222 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7223 struct listnode
*node
;
7226 for (ALL_LIST_ELEMENTS_RO(
7227 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7229 vty_out(vty
, " import vrf %s\n", name
);
7233 vty_endframe(vty
, " exit-address-family\n");
7236 int bgp_config_write(struct vty
*vty
)
7240 struct peer_group
*group
;
7242 struct listnode
*node
, *nnode
;
7243 struct listnode
*mnode
, *mnnode
;
7245 /* BGP Multiple instance. */
7246 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7247 vty_out(vty
, "no bgp multiple-instance\n");
7251 /* BGP Config type. */
7252 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7253 vty_out(vty
, "bgp config-type cisco\n");
7257 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7258 vty_out(vty
, "bgp route-map delay-timer %u\n",
7259 bm
->rmap_update_timer
);
7262 vty_out(vty
, "!\n");
7264 /* BGP configuration. */
7265 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7267 /* skip all auto created vrf as they dont have user config */
7268 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7271 /* Router bgp ASN */
7272 vty_out(vty
, "router bgp %u", bgp
->as
);
7274 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7276 vty_out(vty
, " %s %s",
7278 == BGP_INSTANCE_TYPE_VIEW
)
7285 /* No Synchronization */
7286 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7287 vty_out(vty
, " no synchronization\n");
7289 /* BGP fast-external-failover. */
7290 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7291 vty_out(vty
, " no bgp fast-external-failover\n");
7293 /* BGP router ID. */
7294 if (bgp
->router_id_static
.s_addr
!= 0)
7295 vty_out(vty
, " bgp router-id %s\n",
7296 inet_ntoa(bgp
->router_id_static
));
7298 /* BGP log-neighbor-changes. */
7299 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7300 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7301 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7303 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7307 /* BGP configuration. */
7308 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7309 vty_out(vty
, " bgp always-compare-med\n");
7311 /* BGP default ipv4-unicast. */
7312 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7313 vty_out(vty
, " no bgp default ipv4-unicast\n");
7315 /* BGP default local-preference. */
7316 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7317 vty_out(vty
, " bgp default local-preference %u\n",
7318 bgp
->default_local_pref
);
7320 /* BGP default show-hostname */
7321 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7322 != DFLT_BGP_SHOW_HOSTNAME
)
7323 vty_out(vty
, " %sbgp default show-hostname\n",
7324 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7328 /* BGP default subgroup-pkt-queue-max. */
7329 if (bgp
->default_subgroup_pkt_queue_max
7330 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7331 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7332 bgp
->default_subgroup_pkt_queue_max
);
7334 /* BGP default autoshutdown neighbors */
7335 if (bgp
->autoshutdown
)
7336 vty_out(vty
, " bgp default shutdown\n");
7338 /* BGP client-to-client reflection. */
7339 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7340 vty_out(vty
, " no bgp client-to-client reflection\n");
7342 /* BGP cluster ID. */
7343 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7344 vty_out(vty
, " bgp cluster-id %s\n",
7345 inet_ntoa(bgp
->cluster_id
));
7347 /* Disable ebgp connected nexthop check */
7348 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7350 " bgp disable-ebgp-connected-route-check\n");
7352 /* Confederation identifier*/
7353 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7354 vty_out(vty
, " bgp confederation identifier %i\n",
7357 /* Confederation peer */
7358 if (bgp
->confed_peers_cnt
> 0) {
7361 vty_out(vty
, " bgp confederation peers");
7363 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7364 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7369 /* BGP enforce-first-as. */
7370 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7371 vty_out(vty
, " bgp enforce-first-as\n");
7373 /* BGP deterministic-med. */
7374 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7375 != DFLT_BGP_DETERMINISTIC_MED
)
7376 vty_out(vty
, " %sbgp deterministic-med\n",
7377 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7381 /* BGP update-delay. */
7382 bgp_config_write_update_delay(vty
, bgp
);
7384 if (bgp
->v_maxmed_onstartup
7385 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7386 vty_out(vty
, " bgp max-med on-startup %u",
7387 bgp
->v_maxmed_onstartup
);
7388 if (bgp
->maxmed_onstartup_value
7389 != BGP_MAXMED_VALUE_DEFAULT
)
7391 bgp
->maxmed_onstartup_value
);
7394 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7395 vty_out(vty
, " bgp max-med administrative");
7396 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7397 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7402 bgp_config_write_wpkt_quanta(vty
, bgp
);
7404 bgp_config_write_rpkt_quanta(vty
, bgp
);
7407 bgp_config_write_coalesce_time(vty
, bgp
);
7409 /* BGP graceful-restart. */
7410 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7412 " bgp graceful-restart stalepath-time %u\n",
7413 bgp
->stalepath_time
);
7414 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7415 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7417 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7418 vty_out(vty
, " bgp graceful-restart\n");
7420 /* BGP graceful-shutdown */
7421 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7422 vty_out(vty
, " bgp graceful-shutdown\n");
7424 /* BGP graceful-restart Preserve State F bit. */
7425 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7427 " bgp graceful-restart preserve-fw-state\n");
7429 /* BGP bestpath method. */
7430 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7431 vty_out(vty
, " bgp bestpath as-path ignore\n");
7432 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7433 vty_out(vty
, " bgp bestpath as-path confed\n");
7435 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7436 if (bgp_flag_check(bgp
,
7437 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7439 " bgp bestpath as-path multipath-relax as-set\n");
7442 " bgp bestpath as-path multipath-relax\n");
7446 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7448 " bgp route-reflector allow-outbound-policy\n");
7450 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7451 vty_out(vty
, " bgp bestpath compare-routerid\n");
7452 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7453 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7454 vty_out(vty
, " bgp bestpath med");
7455 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7456 vty_out(vty
, " confed");
7457 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7458 vty_out(vty
, " missing-as-worst");
7462 /* BGP network import check. */
7463 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7464 != DFLT_BGP_IMPORT_CHECK
)
7465 vty_out(vty
, " %sbgp network import-check\n",
7466 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7470 /* BGP flag dampening. */
7471 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7472 BGP_CONFIG_DAMPENING
))
7473 bgp_config_write_damp(vty
);
7475 /* BGP timers configuration. */
7476 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7477 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7478 vty_out(vty
, " timers bgp %u %u\n",
7479 bgp
->default_keepalive
, bgp
->default_holdtime
);
7482 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7483 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7486 /* Normal neighbor configuration. */
7487 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7488 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7489 bgp_config_write_peer_global(vty
, bgp
, peer
);
7492 /* listen range and limit for dynamic BGP neighbors */
7493 bgp_config_write_listen(vty
, bgp
);
7495 /* No auto-summary */
7496 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7497 vty_out(vty
, " no auto-summary\n");
7499 /* IPv4 unicast configuration. */
7500 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7502 /* IPv4 multicast configuration. */
7503 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7505 /* IPv4 labeled-unicast configuration. */
7506 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7508 /* IPv4 VPN configuration. */
7509 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7511 /* ENCAPv4 configuration. */
7512 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7514 /* FLOWSPEC v4 configuration. */
7515 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7517 /* IPv6 unicast configuration. */
7518 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7520 /* IPv6 multicast configuration. */
7521 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7523 /* IPv6 labeled-unicast configuration. */
7524 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7525 SAFI_LABELED_UNICAST
);
7527 /* IPv6 VPN configuration. */
7528 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7530 /* ENCAPv6 configuration. */
7531 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7533 /* FLOWSPEC v6 configuration. */
7534 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7536 /* EVPN configuration. */
7537 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7540 bgp_rfapi_cfg_write(vty
, bgp
);
7543 vty_out(vty
, "!\n");
7548 void bgp_master_init(struct thread_master
*master
)
7552 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7555 bm
->bgp
= list_new();
7556 bm
->listen_sockets
= list_new();
7557 bm
->port
= BGP_PORT_DEFAULT
;
7558 bm
->master
= master
;
7559 bm
->start_time
= bgp_clock();
7560 bm
->t_rmap_update
= NULL
;
7561 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7563 bgp_process_queue_init();
7565 /* init the rd id space.
7566 assign 0th index in the bitfield,
7567 so that we start with id 1
7569 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7570 bf_assign_zero_index(bm
->rd_idspace
);
7572 /* Enable multiple instances by default. */
7573 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7575 /* mpls label dynamic allocation pool */
7576 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7578 QOBJ_REG(bm
, bgp_master
);
7582 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7583 * instance delete (non-default only) or BGP exit.
7585 static void bgp_if_finish(struct bgp
*bgp
)
7587 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7588 struct interface
*ifp
;
7590 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7593 FOR_ALL_INTERFACES (vrf
, ifp
) {
7594 struct listnode
*c_node
, *c_nnode
;
7595 struct connected
*c
;
7597 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7598 bgp_connected_delete(bgp
, c
);
7602 extern void bgp_snmp_init(void);
7604 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7606 struct vrf
*vrf
= NULL
;
7607 struct listnode
*next
;
7610 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7611 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7612 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7615 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7616 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7619 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7623 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7624 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7625 {.completions
= NULL
},
7628 static void bgp_pthreads_init()
7632 struct frr_pthread_attr io
= {
7634 .start
= frr_pthread_attr_default
.start
,
7635 .stop
= frr_pthread_attr_default
.stop
,
7637 struct frr_pthread_attr ka
= {
7638 .id
= PTHREAD_KEEPALIVES
,
7639 .start
= bgp_keepalives_start
,
7640 .stop
= bgp_keepalives_stop
,
7642 frr_pthread_new(&io
, "BGP I/O thread");
7643 frr_pthread_new(&ka
, "BGP Keepalives thread");
7646 void bgp_pthreads_run()
7648 struct frr_pthread
*io
= frr_pthread_get(PTHREAD_IO
);
7649 struct frr_pthread
*ka
= frr_pthread_get(PTHREAD_KEEPALIVES
);
7651 frr_pthread_run(io
, NULL
);
7652 frr_pthread_run(ka
, NULL
);
7654 /* Wait until threads are ready. */
7655 frr_pthread_wait_running(io
);
7656 frr_pthread_wait_running(ka
);
7659 void bgp_pthreads_finish()
7661 frr_pthread_stop_all();
7662 frr_pthread_finish();
7668 /* allocates some vital data structures used by peer commands in
7671 /* pre-init pthreads */
7672 bgp_pthreads_init();
7675 bgp_zebra_init(bm
->master
);
7678 vnc_zebra_init(bm
->master
);
7681 /* BGP VTY commands installation. */
7689 bgp_route_map_init();
7690 bgp_scan_vty_init();
7695 bgp_ethernetvpn_init();
7696 bgp_flowspec_vty_init();
7698 /* Access list initialize. */
7700 access_list_add_hook(peer_distribute_update
);
7701 access_list_delete_hook(peer_distribute_update
);
7703 /* Filter list initialize. */
7705 as_list_add_hook(peer_aslist_add
);
7706 as_list_delete_hook(peer_aslist_del
);
7708 /* Prefix list initialize.*/
7710 prefix_list_add_hook(peer_prefix_list_update
);
7711 prefix_list_delete_hook(peer_prefix_list_update
);
7713 /* Community list initialize. */
7714 bgp_clist
= community_list_init();
7719 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7722 void bgp_terminate(void)
7726 struct listnode
*node
, *nnode
;
7727 struct listnode
*mnode
, *mnnode
;
7731 /* Close the listener sockets first as this prevents peers from
7733 * to reconnect on receiving the peer unconfig message. In the presence
7734 * of a large number of peers this will ensure that no peer is left with
7735 * a dangling connection
7737 /* reverse bgp_master_init */
7740 if (bm
->listen_sockets
)
7741 list_delete_and_null(&bm
->listen_sockets
);
7743 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7744 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7745 if (peer
->status
== Established
7746 || peer
->status
== OpenSent
7747 || peer
->status
== OpenConfirm
)
7748 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7749 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7751 if (bm
->process_main_queue
)
7752 work_queue_free_and_null(&bm
->process_main_queue
);
7754 if (bm
->t_rmap_update
)
7755 BGP_TIMER_OFF(bm
->t_rmap_update
);