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
28 #include "sockunion.h"
37 #include "workqueue.h"
45 #include "frr_pthread.h"
47 #include "bgpd/bgpd.h"
48 #include "bgpd/bgp_table.h"
49 #include "bgpd/bgp_aspath.h"
50 #include "bgpd/bgp_route.h"
51 #include "bgpd/bgp_dump.h"
52 #include "bgpd/bgp_debug.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_attr.h"
55 #include "bgpd/bgp_regex.h"
56 #include "bgpd/bgp_clist.h"
57 #include "bgpd/bgp_fsm.h"
58 #include "bgpd/bgp_packet.h"
59 #include "bgpd/bgp_zebra.h"
60 #include "bgpd/bgp_open.h"
61 #include "bgpd/bgp_filter.h"
62 #include "bgpd/bgp_nexthop.h"
63 #include "bgpd/bgp_damp.h"
64 #include "bgpd/bgp_mplsvpn.h"
66 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
67 #include "bgpd/rfapi/rfapi_backend.h"
69 #include "bgpd/bgp_evpn.h"
70 #include "bgpd/bgp_advertise.h"
71 #include "bgpd/bgp_network.h"
72 #include "bgpd/bgp_vty.h"
73 #include "bgpd/bgp_mpath.h"
74 #include "bgpd/bgp_nht.h"
75 #include "bgpd/bgp_updgrp.h"
76 #include "bgpd/bgp_bfd.h"
77 #include "bgpd/bgp_memory.h"
78 #include "bgpd/bgp_evpn_vty.h"
79 #include "bgpd/bgp_keepalives.h"
80 #include "bgpd/bgp_io.h"
83 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
84 DEFINE_QOBJ_TYPE(bgp_master
)
86 DEFINE_QOBJ_TYPE(peer
)
88 /* BGP process wide configuration. */
89 static struct bgp_master bgp_master
;
91 /* BGP process wide configuration pointer to export. */
92 struct bgp_master
*bm
;
94 /* BGP community-list. */
95 struct community_list_handler
*bgp_clist
;
97 unsigned int multipath_num
= MULTIPATH_NUM
;
99 static void bgp_if_finish(struct bgp
*bgp
);
101 extern struct zclient
*zclient
;
103 void bgp_session_reset(struct peer
*peer
)
105 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
106 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
107 peer_delete(peer
->doppelganger
);
109 BGP_EVENT_ADD(peer
, BGP_Stop
);
113 * During session reset, we may delete the doppelganger peer, which would
114 * be the next node to the current node. If the session reset was invoked
115 * during walk of peer list, we would end up accessing the freed next
116 * node. This function moves the next node along.
118 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
123 n
= (nnode
) ? *nnode
: NULL
;
124 npeer
= (n
) ? listgetdata(n
) : NULL
;
126 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
127 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
128 PEER_FLAG_CONFIG_NODE
))) {
129 if (peer
->doppelganger
== npeer
)
130 /* nnode and *nnode are confirmed to be non-NULL here */
131 *nnode
= (*nnode
)->next
;
132 peer_delete(peer
->doppelganger
);
135 BGP_EVENT_ADD(peer
, BGP_Stop
);
138 /* BGP global flag manipulation. */
139 int bgp_option_set(int flag
)
143 case BGP_OPT_MULTIPLE_INSTANCE
:
144 case BGP_OPT_CONFIG_CISCO
:
145 case BGP_OPT_NO_LISTEN
:
146 SET_FLAG(bm
->options
, flag
);
149 return BGP_ERR_INVALID_FLAG
;
154 int bgp_option_unset(int flag
)
157 case BGP_OPT_MULTIPLE_INSTANCE
:
158 if (listcount(bm
->bgp
) > 1)
159 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
162 case BGP_OPT_CONFIG_CISCO
:
163 UNSET_FLAG(bm
->options
, flag
);
166 return BGP_ERR_INVALID_FLAG
;
171 int bgp_option_check(int flag
)
173 return CHECK_FLAG(bm
->options
, flag
);
176 /* BGP flag manipulation. */
177 int bgp_flag_set(struct bgp
*bgp
, int flag
)
179 SET_FLAG(bgp
->flags
, flag
);
183 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
185 UNSET_FLAG(bgp
->flags
, flag
);
189 int bgp_flag_check(struct bgp
*bgp
, int flag
)
191 return CHECK_FLAG(bgp
->flags
, flag
);
194 /* Internal function to set BGP structure configureation flag. */
195 static void bgp_config_set(struct bgp
*bgp
, int config
)
197 SET_FLAG(bgp
->config
, config
);
200 static void bgp_config_unset(struct bgp
*bgp
, int config
)
202 UNSET_FLAG(bgp
->config
, config
);
205 static int bgp_config_check(struct bgp
*bgp
, int config
)
207 return CHECK_FLAG(bgp
->config
, config
);
210 /* Set BGP router identifier. */
211 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
214 struct listnode
*node
, *nnode
;
216 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
219 /* EVPN uses router id in RD, withdraw them */
220 if (bgp
->advertise_all_vni
)
221 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
223 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
225 /* Set all peer's local identifier with this value. */
226 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
227 IPV4_ADDR_COPY(&peer
->local_id
, id
);
229 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
230 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
231 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
232 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
236 /* EVPN uses router id in RD, update them */
237 if (bgp
->advertise_all_vni
)
238 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
243 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
245 struct listnode
*node
, *nnode
;
248 if (vrf_id
== VRF_DEFAULT
) {
249 /* Router-id change for default VRF has to also update all
251 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
252 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
255 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
256 if (!bgp
->router_id_static
.s_addr
)
257 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
260 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
262 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
264 if (!bgp
->router_id_static
.s_addr
)
265 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
270 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
272 bgp
->router_id_static
= id
;
273 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
277 /* BGP's cluster-id control. */
278 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
281 struct listnode
*node
, *nnode
;
283 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
284 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
287 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
288 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
290 /* Clear all IBGP peer. */
291 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
292 if (peer
->sort
!= BGP_PEER_IBGP
)
295 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
296 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
297 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
298 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
304 int bgp_cluster_id_unset(struct bgp
*bgp
)
307 struct listnode
*node
, *nnode
;
309 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
312 bgp
->cluster_id
.s_addr
= 0;
313 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
315 /* Clear all IBGP peer. */
316 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
317 if (peer
->sort
!= BGP_PEER_IBGP
)
320 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
321 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
322 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
323 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
329 /* time_t value that is monotonicly increasing
330 * and uneffected by adjustments to system clock
332 time_t bgp_clock(void)
340 /* BGP timer configuration. */
341 int bgp_timers_set(struct bgp
*bgp
, u_int32_t keepalive
, u_int32_t holdtime
)
343 bgp
->default_keepalive
=
344 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
345 bgp
->default_holdtime
= holdtime
;
350 int bgp_timers_unset(struct bgp
*bgp
)
352 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
353 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
358 /* BGP confederation configuration. */
359 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
362 struct listnode
*node
, *nnode
;
366 return BGP_ERR_INVALID_AS
;
368 /* Remember - were we doing confederation before? */
369 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
371 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
373 /* If we were doing confederation already, this is just an external
374 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
375 were not doing confederation before, reset all EBGP sessions. */
376 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
377 /* We're looking for peers who's AS is not local or part of our
379 if (already_confed
) {
380 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
382 if (BGP_IS_VALID_STATE_FOR_NOTIF(
385 PEER_DOWN_CONFED_ID_CHANGE
;
387 peer
, BGP_NOTIFY_CEASE
,
388 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
390 bgp_session_reset_safe(peer
, &nnode
);
393 /* Not doign confederation before, so reset every
396 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
397 /* Reset the local_as to be our EBGP one */
398 if (peer_sort(peer
) == BGP_PEER_EBGP
)
400 if (BGP_IS_VALID_STATE_FOR_NOTIF(
403 PEER_DOWN_CONFED_ID_CHANGE
;
405 peer
, BGP_NOTIFY_CEASE
,
406 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
408 bgp_session_reset_safe(peer
, &nnode
);
415 int bgp_confederation_id_unset(struct bgp
*bgp
)
418 struct listnode
*node
, *nnode
;
421 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
423 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
424 /* We're looking for peers who's AS is not local */
425 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
426 peer
->local_as
= bgp
->as
;
427 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
428 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
429 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
430 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
434 bgp_session_reset_safe(peer
, &nnode
);
440 /* Is an AS part of the confed or not? */
441 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
448 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
449 if (bgp
->confed_peers
[i
] == as
)
455 /* Add an AS to the confederation set. */
456 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
459 struct listnode
*node
, *nnode
;
462 return BGP_ERR_INVALID_BGP
;
465 return BGP_ERR_INVALID_AS
;
467 if (bgp_confederation_peers_check(bgp
, as
))
470 if (bgp
->confed_peers
)
472 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
473 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
476 XMALLOC(MTYPE_BGP_CONFED_LIST
,
477 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
479 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
480 bgp
->confed_peers_cnt
++;
482 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
483 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
484 if (peer
->as
== as
) {
485 peer
->local_as
= bgp
->as
;
486 if (BGP_IS_VALID_STATE_FOR_NOTIF(
489 PEER_DOWN_CONFED_PEER_CHANGE
;
491 peer
, BGP_NOTIFY_CEASE
,
492 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
494 bgp_session_reset_safe(peer
, &nnode
);
501 /* Delete an AS from the confederation set. */
502 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
507 struct listnode
*node
, *nnode
;
512 if (!bgp_confederation_peers_check(bgp
, as
))
515 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
516 if (bgp
->confed_peers
[i
] == as
)
517 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
518 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
520 bgp
->confed_peers_cnt
--;
522 if (bgp
->confed_peers_cnt
== 0) {
523 if (bgp
->confed_peers
)
524 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
525 bgp
->confed_peers
= NULL
;
528 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
529 bgp
->confed_peers_cnt
* sizeof(as_t
));
531 /* Now reset any peer who's remote AS has just been removed from the
533 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
534 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
535 if (peer
->as
== as
) {
536 peer
->local_as
= bgp
->confed_id
;
537 if (BGP_IS_VALID_STATE_FOR_NOTIF(
540 PEER_DOWN_CONFED_PEER_CHANGE
;
542 peer
, BGP_NOTIFY_CEASE
,
543 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
545 bgp_session_reset_safe(peer
, &nnode
);
553 /* Local preference configuration. */
554 int bgp_default_local_preference_set(struct bgp
*bgp
, u_int32_t local_pref
)
559 bgp
->default_local_pref
= local_pref
;
564 int bgp_default_local_preference_unset(struct bgp
*bgp
)
569 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
574 /* Local preference configuration. */
575 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
,
576 u_int32_t queue_size
)
581 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
586 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
590 bgp
->default_subgroup_pkt_queue_max
=
591 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
596 /* Listen limit configuration. */
597 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
602 bgp
->dynamic_neighbors_limit
= listen_limit
;
607 int bgp_listen_limit_unset(struct bgp
*bgp
)
612 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
617 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
618 afi_t
*afi
, safi_t
*safi
)
620 /* Map from IANA values to internal values, return error if
621 * values are unrecognized.
623 *afi
= afi_iana2int(pkt_afi
);
624 *safi
= safi_iana2int(pkt_safi
);
625 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
631 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
632 iana_safi_t
*pkt_safi
)
634 /* Map from internal values to IANA values, return error if
635 * internal values are bad (unexpected).
637 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
639 *pkt_afi
= afi_int2iana(afi
);
640 *pkt_safi
= safi_int2iana(safi
);
644 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
652 afid
= afindex(afi
, safi
);
653 if (afid
>= BGP_AF_MAX
)
656 assert(peer
->peer_af_array
[afid
] == NULL
);
658 /* Allocate new peer af */
659 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
662 zlog_err("Could not create af structure for peer %s",
667 peer
->peer_af_array
[afid
] = af
;
676 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
683 afid
= afindex(afi
, safi
);
684 if (afid
>= BGP_AF_MAX
)
687 return peer
->peer_af_array
[afid
];
690 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
698 afid
= afindex(afi
, safi
);
699 if (afid
>= BGP_AF_MAX
)
702 af
= peer
->peer_af_array
[afid
];
706 bgp_stop_announce_route_timer(af
);
708 if (PAF_SUBGRP(af
)) {
709 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
710 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
711 af
->subgroup
->update_group
->id
,
712 af
->subgroup
->id
, peer
->host
);
715 update_subgroup_remove_peer(af
->subgroup
, af
);
717 peer
->peer_af_array
[afid
] = NULL
;
718 XFREE(MTYPE_BGP_PEER_AF
, af
);
722 /* Peer comparison function for sorting. */
723 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
725 if (p1
->group
&& !p2
->group
)
728 if (!p1
->group
&& p2
->group
)
731 if (p1
->group
== p2
->group
) {
732 if (p1
->conf_if
&& !p2
->conf_if
)
735 if (!p1
->conf_if
&& p2
->conf_if
)
738 if (p1
->conf_if
&& p2
->conf_if
)
739 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
741 return strcmp(p1
->group
->name
, p2
->group
->name
);
743 return sockunion_cmp(&p1
->su
, &p2
->su
);
746 static unsigned int peer_hash_key_make(void *p
)
748 struct peer
*peer
= p
;
749 return sockunion_hash(&peer
->su
);
752 static int peer_hash_same(const void *p1
, const void *p2
)
754 const struct peer
*peer1
= p1
;
755 const struct peer
*peer2
= p2
;
756 return (sockunion_same(&peer1
->su
, &peer2
->su
)
757 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
758 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
761 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
764 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
767 /* Return true if flag is set for the peer but not the peer-group */
768 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
771 struct peer
*g_peer
= NULL
;
773 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
774 if (peer_group_active(peer
)) {
775 g_peer
= peer
->group
->conf
;
777 /* If this flag is not set for the peer's peer-group
778 * then return true */
779 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
784 /* peer is not in a peer-group but the flag is set to return
794 /* Reset all address family specific configuration. */
795 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
798 struct bgp_filter
*filter
;
799 char orf_name
[BUFSIZ
];
801 filter
= &peer
->filter
[afi
][safi
];
803 /* Clear neighbor filter and route-map */
804 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
805 if (filter
->dlist
[i
].name
) {
806 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
807 filter
->dlist
[i
].name
= NULL
;
809 if (filter
->plist
[i
].name
) {
810 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
811 filter
->plist
[i
].name
= NULL
;
813 if (filter
->aslist
[i
].name
) {
814 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
815 filter
->aslist
[i
].name
= NULL
;
818 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
819 if (filter
->map
[i
].name
) {
820 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
821 filter
->map
[i
].name
= NULL
;
825 /* Clear unsuppress map. */
826 if (filter
->usmap
.name
)
827 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
828 filter
->usmap
.name
= NULL
;
829 filter
->usmap
.map
= NULL
;
831 /* Clear neighbor's all address family flags. */
832 peer
->af_flags
[afi
][safi
] = 0;
834 /* Clear neighbor's all address family sflags. */
835 peer
->af_sflags
[afi
][safi
] = 0;
837 /* Clear neighbor's all address family capabilities. */
838 peer
->af_cap
[afi
][safi
] = 0;
841 peer
->orf_plist
[afi
][safi
] = NULL
;
842 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
843 prefix_bgp_orf_remove_all(afi
, orf_name
);
845 /* Set default neighbor send-community. */
846 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
847 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
848 SET_FLAG(peer
->af_flags
[afi
][safi
],
849 PEER_FLAG_SEND_EXT_COMMUNITY
);
850 SET_FLAG(peer
->af_flags
[afi
][safi
],
851 PEER_FLAG_SEND_LARGE_COMMUNITY
);
854 /* Clear neighbor default_originate_rmap */
855 if (peer
->default_rmap
[afi
][safi
].name
)
856 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
857 peer
->default_rmap
[afi
][safi
].name
= NULL
;
858 peer
->default_rmap
[afi
][safi
].map
= NULL
;
860 /* Clear neighbor maximum-prefix */
861 peer
->pmax
[afi
][safi
] = 0;
862 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
865 /* peer global config reset */
866 static void peer_global_config_reset(struct peer
*peer
)
871 peer
->change_local_as
= 0;
872 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
873 if (peer
->update_source
) {
874 sockunion_free(peer
->update_source
);
875 peer
->update_source
= NULL
;
877 if (peer
->update_if
) {
878 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
879 peer
->update_if
= NULL
;
882 if (peer_sort(peer
) == BGP_PEER_IBGP
)
883 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
885 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
887 /* This is a per-peer specific flag and so we must preserve it */
888 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
893 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
899 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
901 /* Reset some other configs back to defaults. */
902 peer
->v_start
= BGP_INIT_START_TIMER
;
903 peer
->password
= NULL
;
904 peer
->local_id
= peer
->bgp
->router_id
;
905 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
906 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
908 bfd_info_free(&(peer
->bfd_info
));
910 /* Set back the CONFIG_NODE flag. */
911 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
914 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
915 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
922 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
923 if (peer
->as_type
== AS_INTERNAL
)
924 return BGP_PEER_IBGP
;
926 else if (peer
->as_type
== AS_EXTERNAL
)
927 return BGP_PEER_EBGP
;
929 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
930 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
935 peer1
= listnode_head(peer
->group
->peer
);
940 return BGP_PEER_INTERNAL
;
944 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
945 if (peer
->local_as
== 0)
946 return BGP_PEER_INTERNAL
;
948 if (peer
->local_as
== peer
->as
) {
949 if (bgp
->as
== bgp
->confed_id
) {
950 if (peer
->local_as
== bgp
->as
)
951 return BGP_PEER_IBGP
;
953 return BGP_PEER_EBGP
;
955 if (peer
->local_as
== bgp
->confed_id
)
956 return BGP_PEER_EBGP
;
958 return BGP_PEER_IBGP
;
962 if (bgp_confederation_peers_check(bgp
, peer
->as
))
963 return BGP_PEER_CONFED
;
965 return BGP_PEER_EBGP
;
967 if (peer
->as_type
!= AS_SPECIFIED
)
968 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
971 return (peer
->local_as
== 0
973 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
978 /* Calculate and cache the peer "sort" */
979 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
981 peer
->sort
= peer_calc_sort(peer
);
985 static void peer_free(struct peer
*peer
)
987 assert(peer
->status
== Deleted
);
991 /* this /ought/ to have been done already through bgp_stop earlier,
992 * but just to be sure..
996 bgp_writes_off(peer
);
997 assert(!peer
->t_write
);
998 assert(!peer
->t_read
);
999 BGP_EVENT_FLUSH(peer
);
1001 pthread_mutex_destroy(&peer
->io_mtx
);
1003 /* Free connected nexthop, if present */
1004 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1005 && !peer_dynamic_neighbor(peer
))
1006 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1009 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1012 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1016 /* Free allocated host character. */
1018 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1022 if (peer
->domainname
) {
1023 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1024 peer
->domainname
= NULL
;
1028 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1029 peer
->ifname
= NULL
;
1032 /* Update source configuration. */
1033 if (peer
->update_source
) {
1034 sockunion_free(peer
->update_source
);
1035 peer
->update_source
= NULL
;
1038 if (peer
->update_if
) {
1039 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1040 peer
->update_if
= NULL
;
1043 if (peer
->notify
.data
)
1044 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1045 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1047 if (peer
->clear_node_queue
) {
1048 work_queue_free(peer
->clear_node_queue
);
1049 peer
->clear_node_queue
= NULL
;
1052 bgp_sync_delete(peer
);
1054 if (peer
->conf_if
) {
1055 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1056 peer
->conf_if
= NULL
;
1059 bfd_info_free(&(peer
->bfd_info
));
1061 bgp_unlock(peer
->bgp
);
1063 memset(peer
, 0, sizeof(struct peer
));
1065 XFREE(MTYPE_BGP_PEER
, peer
);
1068 /* increase reference count on a struct peer */
1069 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1071 assert(peer
&& (peer
->lock
>= 0));
1074 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1082 /* decrease reference count on a struct peer
1083 * struct peer is freed and NULL returned if last reference
1085 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1087 assert(peer
&& (peer
->lock
> 0));
1090 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1095 if (peer
->lock
== 0) {
1103 /* Allocate new peer object, implicitely locked. */
1104 struct peer
*peer_new(struct bgp
*bgp
)
1111 /* bgp argument is absolutely required */
1116 /* Allocate new peer. */
1117 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1119 /* Set default value. */
1121 peer
->v_start
= BGP_INIT_START_TIMER
;
1122 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1123 peer
->status
= Idle
;
1124 peer
->ostatus
= Idle
;
1125 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1126 peer
->bgp
= bgp_lock(bgp
);
1127 peer
= peer_lock(peer
); /* initial reference */
1128 peer
->password
= NULL
;
1130 /* Set default flags. */
1131 FOREACH_AFI_SAFI (afi
, safi
) {
1132 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1133 SET_FLAG(peer
->af_flags
[afi
][safi
],
1134 PEER_FLAG_SEND_COMMUNITY
);
1135 SET_FLAG(peer
->af_flags
[afi
][safi
],
1136 PEER_FLAG_SEND_EXT_COMMUNITY
);
1137 SET_FLAG(peer
->af_flags
[afi
][safi
],
1138 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1140 peer
->orf_plist
[afi
][safi
] = NULL
;
1142 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1144 /* Create buffers. */
1145 peer
->ibuf
= stream_fifo_new();
1146 peer
->obuf
= stream_fifo_new();
1147 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1149 /* We use a larger buffer for peer->obuf_work in the event that:
1150 * - We RX a BGP_UPDATE where the attributes alone are just
1151 * under BGP_MAX_PACKET_SIZE
1152 * - The user configures an outbound route-map that does many as-path
1153 * prepends or adds many communities. At most they can have
1155 * args in a route-map so there is a finite limit on how large they
1157 * make the attributes.
1159 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1161 * checking for every single attribute as we construct an UPDATE.
1164 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1165 peer
->ibuf_work
= stream_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1166 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1168 bgp_sync_init(peer
);
1170 /* Get service port number. */
1171 sp
= getservbyname("bgp", "tcp");
1172 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1174 QOBJ_REG(peer
, peer
);
1179 * This function is invoked when a duplicate peer structure associated with
1180 * a neighbor is being deleted. If this about-to-be-deleted structure is
1181 * the one with all the config, then we have to copy over the info.
1183 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1185 struct peer_af
*paf
;
1193 /* The following function is used by both peer group config copy to
1194 * individual peer and when we transfer config
1196 if (peer_src
->change_local_as
)
1197 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1199 /* peer flags apply */
1200 peer_dst
->flags
= peer_src
->flags
;
1201 peer_dst
->cap
= peer_src
->cap
;
1202 peer_dst
->config
= peer_src
->config
;
1204 peer_dst
->local_as
= peer_src
->local_as
;
1205 peer_dst
->ifindex
= peer_src
->ifindex
;
1206 peer_dst
->port
= peer_src
->port
;
1207 (void)peer_sort(peer_dst
);
1208 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1211 peer_dst
->holdtime
= peer_src
->holdtime
;
1212 peer_dst
->keepalive
= peer_src
->keepalive
;
1213 peer_dst
->connect
= peer_src
->connect
;
1214 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1215 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1216 peer_dst
->routeadv
= peer_src
->routeadv
;
1217 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1219 /* password apply */
1220 if (peer_src
->password
&& !peer_dst
->password
)
1221 peer_dst
->password
=
1222 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1224 FOREACH_AFI_SAFI (afi
, safi
) {
1225 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1226 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1227 peer_dst
->allowas_in
[afi
][safi
] =
1228 peer_src
->allowas_in
[afi
][safi
];
1229 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1232 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1233 paf
= peer_src
->peer_af_array
[afidx
];
1235 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1238 /* update-source apply */
1239 if (peer_src
->update_source
) {
1240 if (peer_dst
->update_source
)
1241 sockunion_free(peer_dst
->update_source
);
1242 if (peer_dst
->update_if
) {
1243 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1244 peer_dst
->update_if
= NULL
;
1246 peer_dst
->update_source
=
1247 sockunion_dup(peer_src
->update_source
);
1248 } else if (peer_src
->update_if
) {
1249 if (peer_dst
->update_if
)
1250 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1251 if (peer_dst
->update_source
) {
1252 sockunion_free(peer_dst
->update_source
);
1253 peer_dst
->update_source
= NULL
;
1255 peer_dst
->update_if
=
1256 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1259 if (peer_src
->ifname
) {
1260 if (peer_dst
->ifname
)
1261 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1264 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1268 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1269 struct interface
*ifp
)
1271 struct connected
*ifc
;
1274 struct listnode
*node
;
1276 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1277 * IPv4 address of the other end.
1279 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1280 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1281 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1282 if (p
.prefixlen
== 30) {
1283 peer
->su
.sa
.sa_family
= AF_INET
;
1284 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1286 peer
->su
.sin
.sin_addr
.s_addr
=
1288 else if (addr
% 4 == 2)
1289 peer
->su
.sin
.sin_addr
.s_addr
=
1291 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1292 peer
->su
.sin
.sin_len
=
1293 sizeof(struct sockaddr_in
);
1294 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1296 } else if (p
.prefixlen
== 31) {
1297 peer
->su
.sa
.sa_family
= AF_INET
;
1298 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1300 peer
->su
.sin
.sin_addr
.s_addr
=
1303 peer
->su
.sin
.sin_addr
.s_addr
=
1305 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1306 peer
->su
.sin
.sin_len
=
1307 sizeof(struct sockaddr_in
);
1308 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1310 } else if (bgp_debug_neighbor_events(peer
))
1312 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1320 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1321 struct interface
*ifp
)
1323 struct nbr_connected
*ifc_nbr
;
1325 /* Have we learnt the peer's IPv6 link-local address? */
1326 if (ifp
->nbr_connected
1327 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1328 peer
->su
.sa
.sa_family
= AF_INET6
;
1329 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1330 sizeof(struct in6_addr
));
1332 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1334 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1342 * Set or reset the peer address socketunion structure based on the
1343 * learnt/derived peer address. If the address has changed, update the
1344 * password on the listen socket, if needed.
1346 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1348 struct interface
*ifp
;
1350 int peer_addr_updated
= 0;
1355 prev_family
= peer
->su
.sa
.sa_family
;
1356 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1358 /* If BGP unnumbered is not "v6only", we first see if we can
1360 * peer's IPv4 address.
1362 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1364 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1366 /* If "v6only" or we can't derive peer's IPv4 address, see if
1368 * learnt the peer's IPv6 link-local address. This is from the
1370 * IPv6 address in router advertisement.
1372 if (!peer_addr_updated
)
1374 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1376 /* If we could derive the peer address, we may need to install the
1378 * configured for the peer, if any, on the listen socket. Otherwise,
1380 * that peer's address is not available and uninstall the password, if
1383 if (peer_addr_updated
) {
1384 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1387 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1388 bgp_md5_unset(peer
);
1389 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1390 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1393 /* Since our su changed we need to del/add peer to the peerhash */
1394 hash_release(peer
->bgp
->peerhash
, peer
);
1395 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1398 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1401 struct bgp_node
*rn
, *nrn
;
1403 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1404 rn
= bgp_route_next(rn
)) {
1405 if (rn
->info
!= NULL
) {
1406 /* Special handling for 2-level routing
1408 if (safi
== SAFI_MPLS_VPN
1409 || safi
== SAFI_ENCAP
1410 || safi
== SAFI_EVPN
) {
1411 for (nrn
= bgp_table_top((
1415 nrn
= bgp_route_next(nrn
))
1416 bgp_process(bgp
, nrn
,
1419 bgp_process(bgp
, rn
, afi
, safi
);
1424 /* Force a bestpath recalculation for all prefixes. This is used
1425 * when 'bgp bestpath' commands are entered.
1427 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1432 FOREACH_AFI_SAFI (afi
, safi
) {
1433 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1437 /* Create new BGP peer. */
1438 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1439 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1440 int as_type
, afi_t afi
, safi_t safi
,
1441 struct peer_group
*group
)
1445 char buf
[SU_ADDRSTRLEN
];
1447 peer
= peer_new(bgp
);
1449 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1450 bgp_peer_conf_if_to_su_update(peer
);
1452 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1453 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1456 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1458 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1459 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1461 peer
->local_as
= local_as
;
1462 peer
->as
= remote_as
;
1463 peer
->as_type
= as_type
;
1464 peer
->local_id
= bgp
->router_id
;
1465 peer
->v_holdtime
= bgp
->default_holdtime
;
1466 peer
->v_keepalive
= bgp
->default_keepalive
;
1467 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1468 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1470 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1472 peer
= peer_lock(peer
); /* bgp peer list reference */
1473 peer
->group
= group
;
1474 listnode_add_sort(bgp
->peer
, peer
);
1475 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1477 /* Adjust update-group coalesce timer heuristics for # peers. */
1478 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1479 + (bgp
->peer
->count
* BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1480 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1482 active
= peer_active(peer
);
1484 /* Last read and reset time set */
1485 peer
->readtime
= peer
->resettime
= bgp_clock();
1487 /* Default TTL set. */
1488 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1490 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1493 peer
->afc
[afi
][safi
] = 1;
1494 peer_af_create(peer
, afi
, safi
);
1497 /* Set up peer's events and timers. */
1498 if (!active
&& peer_active(peer
))
1499 bgp_timer_set(peer
);
1504 /* Make accept BGP peer. This function is only called from the test code */
1505 struct peer
*peer_create_accept(struct bgp
*bgp
)
1509 peer
= peer_new(bgp
);
1511 peer
= peer_lock(peer
); /* bgp peer list reference */
1512 listnode_add_sort(bgp
->peer
, peer
);
1518 * Return true if we have a peer configured to use this afi/safi
1520 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1522 struct listnode
*node
;
1525 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1526 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1529 if (peer
->afc
[afi
][safi
])
1536 /* Change peer's AS number. */
1537 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1539 bgp_peer_sort_t type
;
1543 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1544 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1545 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1546 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1547 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1549 bgp_session_reset(peer
);
1551 type
= peer_sort(peer
);
1553 peer
->as_type
= as_specified
;
1555 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1556 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1557 && peer
->bgp
->as
!= as
)
1558 peer
->local_as
= peer
->bgp
->confed_id
;
1560 peer
->local_as
= peer
->bgp
->as
;
1562 /* Advertisement-interval reset */
1565 conf
= peer
->group
->conf
;
1567 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1568 peer
->v_routeadv
= conf
->routeadv
;
1570 /* Only go back to the default advertisement-interval if the user had
1572 * already configured it */
1573 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1574 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1575 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1577 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1580 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1582 else if (type
== BGP_PEER_IBGP
)
1585 /* reflector-client reset */
1586 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1587 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1588 PEER_FLAG_REFLECTOR_CLIENT
);
1589 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1590 PEER_FLAG_REFLECTOR_CLIENT
);
1591 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1592 PEER_FLAG_REFLECTOR_CLIENT
);
1593 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1594 PEER_FLAG_REFLECTOR_CLIENT
);
1595 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1596 PEER_FLAG_REFLECTOR_CLIENT
);
1597 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1598 PEER_FLAG_REFLECTOR_CLIENT
);
1599 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1600 PEER_FLAG_REFLECTOR_CLIENT
);
1601 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1602 PEER_FLAG_REFLECTOR_CLIENT
);
1603 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1604 PEER_FLAG_REFLECTOR_CLIENT
);
1605 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1606 PEER_FLAG_REFLECTOR_CLIENT
);
1607 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1608 PEER_FLAG_REFLECTOR_CLIENT
);
1611 /* local-as reset */
1612 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1613 peer
->change_local_as
= 0;
1614 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1615 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1619 /* If peer does not exist, create new one. If peer already exists,
1620 set AS number to the peer. */
1621 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1622 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1628 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1630 peer
= peer_lookup(bgp
, su
);
1633 /* Not allowed for a dynamic peer. */
1634 if (peer_dynamic_neighbor(peer
)) {
1636 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1639 /* When this peer is a member of peer-group. */
1641 if (peer
->group
->conf
->as
) {
1642 /* Return peer group's AS number. */
1643 *as
= peer
->group
->conf
->as
;
1644 return BGP_ERR_PEER_GROUP_MEMBER
;
1646 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1647 if ((as_type
!= AS_INTERNAL
)
1648 && (bgp
->as
!= *as
)) {
1650 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1653 if ((as_type
!= AS_EXTERNAL
)
1654 && (bgp
->as
== *as
)) {
1656 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1661 /* Existing peer's AS number change. */
1662 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1663 || (peer
->as_type
!= as_type
))
1664 peer_as_change(peer
, *as
, as_type
);
1667 return BGP_ERR_NO_INTERFACE_CONFIG
;
1669 /* If the peer is not part of our confederation, and its not an
1670 iBGP peer then spoof the source AS */
1671 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1672 && !bgp_confederation_peers_check(bgp
, *as
)
1674 local_as
= bgp
->confed_id
;
1678 /* If this is IPv4 unicast configuration and "no bgp default
1679 ipv4-unicast" is specified. */
1681 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1682 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1683 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1686 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1693 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1694 struct peer
*peer
, afi_t afi
,
1698 int out
= FILTER_OUT
;
1700 struct bgp_filter
*pfilter
;
1701 struct bgp_filter
*gfilter
;
1704 pfilter
= &peer
->filter
[afi
][safi
];
1705 gfilter
= &conf
->filter
[afi
][safi
];
1707 /* peer af_flags apply */
1708 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1710 /* maximum-prefix */
1711 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1712 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1713 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1716 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1719 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1721 /* default-originate route-map */
1722 if (conf
->default_rmap
[afi
][safi
].name
) {
1723 if (peer
->default_rmap
[afi
][safi
].name
)
1724 XFREE(MTYPE_BGP_FILTER_NAME
,
1725 peer
->default_rmap
[afi
][safi
].name
);
1726 peer
->default_rmap
[afi
][safi
].name
=
1727 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1728 conf
->default_rmap
[afi
][safi
].name
);
1729 peer
->default_rmap
[afi
][safi
].map
=
1730 conf
->default_rmap
[afi
][safi
].map
;
1733 /* inbound filter apply */
1734 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1735 if (pfilter
->dlist
[in
].name
)
1736 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1737 pfilter
->dlist
[in
].name
=
1738 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1739 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1742 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1743 if (pfilter
->plist
[in
].name
)
1744 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1745 pfilter
->plist
[in
].name
=
1746 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1747 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1750 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1751 if (pfilter
->aslist
[in
].name
)
1752 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1753 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1754 gfilter
->aslist
[in
].name
);
1755 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1758 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1759 if (pfilter
->map
[RMAP_IN
].name
)
1760 XFREE(MTYPE_BGP_FILTER_NAME
,
1761 pfilter
->map
[RMAP_IN
].name
);
1762 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1763 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1764 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1767 /* outbound filter apply */
1768 if (gfilter
->dlist
[out
].name
) {
1769 if (pfilter
->dlist
[out
].name
)
1770 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1771 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1772 gfilter
->dlist
[out
].name
);
1773 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1775 if (pfilter
->dlist
[out
].name
)
1776 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1777 pfilter
->dlist
[out
].name
= NULL
;
1778 pfilter
->dlist
[out
].alist
= NULL
;
1781 if (gfilter
->plist
[out
].name
) {
1782 if (pfilter
->plist
[out
].name
)
1783 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1784 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1785 gfilter
->plist
[out
].name
);
1786 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1788 if (pfilter
->plist
[out
].name
)
1789 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1790 pfilter
->plist
[out
].name
= NULL
;
1791 pfilter
->plist
[out
].plist
= NULL
;
1794 if (gfilter
->aslist
[out
].name
) {
1795 if (pfilter
->aslist
[out
].name
)
1796 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1797 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1798 gfilter
->aslist
[out
].name
);
1799 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1801 if (pfilter
->aslist
[out
].name
)
1802 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1803 pfilter
->aslist
[out
].name
= NULL
;
1804 pfilter
->aslist
[out
].aslist
= NULL
;
1807 if (gfilter
->map
[RMAP_OUT
].name
) {
1808 if (pfilter
->map
[RMAP_OUT
].name
)
1809 XFREE(MTYPE_BGP_FILTER_NAME
,
1810 pfilter
->map
[RMAP_OUT
].name
);
1811 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1812 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1813 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1815 if (pfilter
->map
[RMAP_OUT
].name
)
1816 XFREE(MTYPE_BGP_FILTER_NAME
,
1817 pfilter
->map
[RMAP_OUT
].name
);
1818 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1819 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1822 if (gfilter
->usmap
.name
) {
1823 if (pfilter
->usmap
.name
)
1824 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1825 pfilter
->usmap
.name
=
1826 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1827 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1829 if (pfilter
->usmap
.name
)
1830 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1831 pfilter
->usmap
.name
= NULL
;
1832 pfilter
->usmap
.map
= NULL
;
1836 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1840 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1841 zlog_err("%s was called for peer-group %s", __func__
,
1846 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1848 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1849 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1850 return BGP_ERR_PEER_SAFI_CONFLICT
;
1852 /* Nothing to do if we've already activated this peer */
1853 if (peer
->afc
[afi
][safi
])
1856 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1859 active
= peer_active(peer
);
1860 peer
->afc
[afi
][safi
] = 1;
1863 peer_group2peer_config_copy_af(peer
->group
, peer
,
1866 if (!active
&& peer_active(peer
)) {
1867 bgp_timer_set(peer
);
1869 if (peer
->status
== Established
) {
1870 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1871 peer
->afc_adv
[afi
][safi
] = 1;
1872 bgp_capability_send(peer
, afi
, safi
,
1874 CAPABILITY_ACTION_SET
);
1875 if (peer
->afc_recv
[afi
][safi
]) {
1876 peer
->afc_nego
[afi
][safi
] = 1;
1877 bgp_announce_route(peer
, afi
, safi
);
1880 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1881 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1882 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1885 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1886 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1887 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1888 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1895 /* Activate the peer or peer group for specified AFI and SAFI. */
1896 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1899 struct peer_group
*group
;
1900 struct listnode
*node
, *nnode
;
1901 struct peer
*tmp_peer
;
1904 /* Nothing to do if we've already activated this peer */
1905 if (peer
->afc
[afi
][safi
])
1910 /* This is a peer-group so activate all of the members of the
1911 * peer-group as well */
1912 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1914 /* Do not activate a peer for both SAFI_UNICAST and
1915 * SAFI_LABELED_UNICAST */
1916 if ((safi
== SAFI_UNICAST
1917 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1918 || (safi
== SAFI_LABELED_UNICAST
1919 && peer
->afc
[afi
][SAFI_UNICAST
]))
1920 return BGP_ERR_PEER_SAFI_CONFLICT
;
1922 peer
->afc
[afi
][safi
] = 1;
1923 group
= peer
->group
;
1925 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1926 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1929 ret
|= peer_activate_af(peer
, afi
, safi
);
1932 /* If this is the first peer to be activated for this afi/labeled-unicast
1933 * recalc bestpaths to trigger label allocation */
1934 if (safi
== SAFI_LABELED_UNICAST
&& !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1936 if (BGP_DEBUG(zebra
, ZEBRA
))
1937 zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels");
1939 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1940 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1946 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1949 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1950 zlog_err("%s was called for peer-group %s", __func__
,
1955 /* Nothing to do if we've already deactivated this peer */
1956 if (!peer
->afc
[afi
][safi
])
1959 /* De-activate the address family configuration. */
1960 peer
->afc
[afi
][safi
] = 0;
1962 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1963 zlog_err("couldn't delete af structure for peer %s",
1968 if (peer
->status
== Established
) {
1969 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1970 peer
->afc_adv
[afi
][safi
] = 0;
1971 peer
->afc_nego
[afi
][safi
] = 0;
1973 if (peer_active_nego(peer
)) {
1974 bgp_capability_send(peer
, afi
, safi
,
1976 CAPABILITY_ACTION_UNSET
);
1977 bgp_clear_route(peer
, afi
, safi
);
1978 peer
->pcount
[afi
][safi
] = 0;
1980 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1981 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1982 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1985 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1986 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1987 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1994 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1997 struct peer_group
*group
;
1998 struct peer
*tmp_peer
;
1999 struct listnode
*node
, *nnode
;
2002 /* Nothing to do if we've already de-activated this peer */
2003 if (!peer
->afc
[afi
][safi
])
2006 /* This is a peer-group so de-activate all of the members of the
2007 * peer-group as well */
2008 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2009 peer
->afc
[afi
][safi
] = 0;
2010 group
= peer
->group
;
2012 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2013 zlog_err("couldn't delete af structure for peer %s",
2017 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2018 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2021 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2026 /* If this is the last peer to be deactivated for this afi/labeled-unicast
2027 * recalc bestpaths to trigger label deallocation */
2028 if (safi
== SAFI_LABELED_UNICAST
&&
2029 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] &&
2030 !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2032 if (BGP_DEBUG(zebra
, ZEBRA
))
2033 zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2035 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2036 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2041 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2044 return peer_activate(peer
, afi
, safi
);
2046 return peer_deactivate(peer
, afi
, safi
);
2049 static void peer_nsf_stop(struct peer
*peer
)
2054 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2055 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2057 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2058 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2059 peer
->nsf
[afi
][safi
] = 0;
2061 if (peer
->t_gr_restart
) {
2062 BGP_TIMER_OFF(peer
->t_gr_restart
);
2063 if (bgp_debug_neighbor_events(peer
))
2064 zlog_debug("%s graceful restart timer stopped",
2067 if (peer
->t_gr_stale
) {
2068 BGP_TIMER_OFF(peer
->t_gr_stale
);
2069 if (bgp_debug_neighbor_events(peer
))
2071 "%s graceful restart stalepath timer stopped",
2074 bgp_clear_route_all(peer
);
2077 /* Delete peer from confguration.
2079 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2080 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2082 * This function /should/ take care to be idempotent, to guard against
2083 * it being called multiple times through stray events that come in
2084 * that happen to result in this function being called again. That
2085 * said, getting here for a "Deleted" peer is a bug in the neighbour
2088 int peer_delete(struct peer
*peer
)
2094 struct bgp_filter
*filter
;
2095 struct listnode
*pn
;
2098 assert(peer
->status
!= Deleted
);
2101 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2103 bgp_reads_off(peer
);
2104 bgp_writes_off(peer
);
2105 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2106 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2108 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2109 peer_nsf_stop(peer
);
2111 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2113 /* If this peer belongs to peer group, clear up the
2116 if (peer_dynamic_neighbor(peer
))
2117 peer_drop_dynamic_neighbor(peer
);
2119 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2121 peer
); /* group->peer list reference */
2122 list_delete_node(peer
->group
->peer
, pn
);
2127 /* Withdraw all information from routing table. We can not use
2128 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2129 * executed after peer structure is deleted.
2131 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2133 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2135 if (peer
->doppelganger
) {
2136 peer
->doppelganger
->doppelganger
= NULL
;
2137 peer
->doppelganger
= NULL
;
2140 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2141 bgp_fsm_change_status(peer
, Deleted
);
2143 /* Remove from NHT */
2144 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2145 bgp_unlink_nexthop_by_peer(peer
);
2147 /* Password configuration */
2148 if (peer
->password
) {
2149 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2150 peer
->password
= NULL
;
2152 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2153 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2154 bgp_md5_unset(peer
);
2157 bgp_timer_set(peer
); /* stops all timers for Deleted */
2159 /* Delete from all peer list. */
2160 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2161 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2162 peer_unlock(peer
); /* bgp peer list reference */
2163 list_delete_node(bgp
->peer
, pn
);
2164 hash_release(bgp
->peerhash
, peer
);
2169 stream_fifo_free(peer
->ibuf
);
2174 stream_fifo_free(peer
->obuf
);
2178 if (peer
->ibuf_work
) {
2179 stream_free(peer
->ibuf_work
);
2180 peer
->ibuf_work
= NULL
;
2183 if (peer
->obuf_work
) {
2184 stream_free(peer
->obuf_work
);
2185 peer
->obuf_work
= NULL
;
2188 if (peer
->scratch
) {
2189 stream_free(peer
->scratch
);
2190 peer
->scratch
= NULL
;
2193 /* Local and remote addresses. */
2194 if (peer
->su_local
) {
2195 sockunion_free(peer
->su_local
);
2196 peer
->su_local
= NULL
;
2199 if (peer
->su_remote
) {
2200 sockunion_free(peer
->su_remote
);
2201 peer
->su_remote
= NULL
;
2204 /* Free filter related memory. */
2205 FOREACH_AFI_SAFI (afi
, safi
) {
2206 filter
= &peer
->filter
[afi
][safi
];
2208 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2209 if (filter
->dlist
[i
].name
) {
2210 XFREE(MTYPE_BGP_FILTER_NAME
,
2211 filter
->dlist
[i
].name
);
2212 filter
->dlist
[i
].name
= NULL
;
2215 if (filter
->plist
[i
].name
) {
2216 XFREE(MTYPE_BGP_FILTER_NAME
,
2217 filter
->plist
[i
].name
);
2218 filter
->plist
[i
].name
= NULL
;
2221 if (filter
->aslist
[i
].name
) {
2222 XFREE(MTYPE_BGP_FILTER_NAME
,
2223 filter
->aslist
[i
].name
);
2224 filter
->aslist
[i
].name
= NULL
;
2228 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2229 if (filter
->map
[i
].name
) {
2230 XFREE(MTYPE_BGP_FILTER_NAME
,
2231 filter
->map
[i
].name
);
2232 filter
->map
[i
].name
= NULL
;
2236 if (filter
->usmap
.name
) {
2237 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2238 filter
->usmap
.name
= NULL
;
2241 if (peer
->default_rmap
[afi
][safi
].name
) {
2242 XFREE(MTYPE_ROUTE_MAP_NAME
,
2243 peer
->default_rmap
[afi
][safi
].name
);
2244 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2248 FOREACH_AFI_SAFI (afi
, safi
)
2249 peer_af_delete(peer
, afi
, safi
);
2251 if (peer
->hostname
) {
2252 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2253 peer
->hostname
= NULL
;
2256 if (peer
->domainname
) {
2257 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2258 peer
->domainname
= NULL
;
2261 peer_unlock(peer
); /* initial reference */
2266 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2268 return strcmp(g1
->name
, g2
->name
);
2271 /* Peer group cofiguration. */
2272 static struct peer_group
*peer_group_new(void)
2274 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2275 sizeof(struct peer_group
));
2278 static void peer_group_free(struct peer_group
*group
)
2280 XFREE(MTYPE_PEER_GROUP
, group
);
2283 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2285 struct peer_group
*group
;
2286 struct listnode
*node
, *nnode
;
2288 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2289 if (strcmp(group
->name
, name
) == 0)
2295 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2297 struct peer_group
*group
;
2300 group
= peer_group_lookup(bgp
, name
);
2304 group
= peer_group_new();
2307 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2308 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2309 group
->peer
= list_new();
2310 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2311 group
->listen_range
[afi
] = list_new();
2312 group
->conf
= peer_new(bgp
);
2313 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2314 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2315 if (group
->conf
->host
)
2316 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2317 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2318 group
->conf
->group
= group
;
2319 group
->conf
->as
= 0;
2320 group
->conf
->ttl
= 1;
2321 group
->conf
->gtsm_hops
= 0;
2322 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2323 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2324 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2325 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2326 group
->conf
->keepalive
= 0;
2327 group
->conf
->holdtime
= 0;
2328 group
->conf
->connect
= 0;
2329 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2330 listnode_add_sort(bgp
->group
, group
);
2335 static void peer_group2peer_config_copy(struct peer_group
*group
,
2345 peer
->as
= conf
->as
;
2348 if (conf
->change_local_as
)
2349 peer
->change_local_as
= conf
->change_local_as
;
2352 peer
->ttl
= conf
->ttl
;
2355 peer
->gtsm_hops
= conf
->gtsm_hops
;
2357 /* this flag is per-neighbor and so has to be preserved */
2358 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2360 /* peer flags apply */
2361 peer
->flags
= conf
->flags
;
2364 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2366 /* peer config apply */
2367 peer
->config
= conf
->config
;
2369 /* peer timers apply */
2370 peer
->holdtime
= conf
->holdtime
;
2371 peer
->keepalive
= conf
->keepalive
;
2372 peer
->connect
= conf
->connect
;
2373 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2374 peer
->v_connect
= conf
->connect
;
2376 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2378 /* advertisement-interval reset */
2379 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2380 peer
->v_routeadv
= conf
->routeadv
;
2381 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2382 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2384 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2386 /* password apply */
2387 if (conf
->password
&& !peer
->password
)
2388 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2390 if (!BGP_PEER_SU_UNSPEC(peer
))
2393 /* update-source apply */
2394 if (conf
->update_source
) {
2395 if (peer
->update_source
)
2396 sockunion_free(peer
->update_source
);
2397 if (peer
->update_if
) {
2398 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2399 peer
->update_if
= NULL
;
2401 peer
->update_source
= sockunion_dup(conf
->update_source
);
2402 } else if (conf
->update_if
) {
2403 if (peer
->update_if
)
2404 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2405 if (peer
->update_source
) {
2406 sockunion_free(peer
->update_source
);
2407 peer
->update_source
= NULL
;
2410 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2413 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2416 /* Peer group's remote AS configuration. */
2417 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2420 struct peer_group
*group
;
2422 struct listnode
*node
, *nnode
;
2424 group
= peer_group_lookup(bgp
, group_name
);
2428 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2432 /* When we setup peer-group AS number all peer group member's AS
2433 number must be updated to same number. */
2434 peer_as_change(group
->conf
, *as
, as_type
);
2436 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2437 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2438 || (peer
->as_type
!= as_type
))
2439 peer_as_change(peer
, *as
, as_type
);
2445 int peer_group_delete(struct peer_group
*group
)
2449 struct prefix
*prefix
;
2451 struct listnode
*node
, *nnode
;
2456 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2457 other
= peer
->doppelganger
;
2459 if (other
&& other
->status
!= Deleted
) {
2460 other
->group
= NULL
;
2464 list_delete_and_null(&group
->peer
);
2466 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2467 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2469 prefix_free(prefix
);
2471 list_delete_and_null(&group
->listen_range
[afi
]);
2474 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2477 bfd_info_free(&(group
->conf
->bfd_info
));
2479 group
->conf
->group
= NULL
;
2480 peer_delete(group
->conf
);
2482 /* Delete from all peer_group list. */
2483 listnode_delete(bgp
->group
, group
);
2485 peer_group_free(group
);
2490 int peer_group_remote_as_delete(struct peer_group
*group
)
2492 struct peer
*peer
, *other
;
2493 struct listnode
*node
, *nnode
;
2495 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2496 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2499 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2500 other
= peer
->doppelganger
;
2504 if (other
&& other
->status
!= Deleted
) {
2505 other
->group
= NULL
;
2509 list_delete_all_node(group
->peer
);
2511 group
->conf
->as
= 0;
2512 group
->conf
->as_type
= AS_UNSPECIFIED
;
2517 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2519 struct prefix
*prefix
;
2520 struct listnode
*node
, *nnode
;
2523 afi
= family2afi(range
->family
);
2525 /* Group needs remote AS configured. */
2526 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2527 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2529 /* Ensure no duplicates. Currently we don't care about overlaps. */
2530 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2531 if (prefix_same(range
, prefix
))
2535 prefix
= prefix_new();
2536 prefix_copy(prefix
, range
);
2537 listnode_add(group
->listen_range
[afi
], prefix
);
2541 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2543 struct prefix
*prefix
, prefix2
;
2544 struct listnode
*node
, *nnode
;
2547 char buf
[PREFIX2STR_BUFFER
];
2549 afi
= family2afi(range
->family
);
2551 /* Identify the listen range. */
2552 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2553 if (prefix_same(range
, prefix
))
2558 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2560 prefix2str(prefix
, buf
, sizeof(buf
));
2562 /* Dispose off any dynamic neighbors that exist due to this listen range
2564 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2565 if (!peer_dynamic_neighbor(peer
))
2568 sockunion2hostprefix(&peer
->su
, &prefix2
);
2569 if (prefix_match(prefix
, &prefix2
)) {
2570 if (bgp_debug_neighbor_events(peer
))
2572 "Deleting dynamic neighbor %s group %s upon "
2573 "delete of listen range %s",
2574 peer
->host
, group
->name
, buf
);
2579 /* Get rid of the listen range */
2580 listnode_delete(group
->listen_range
[afi
], prefix
);
2585 /* Bind specified peer to peer group. */
2586 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2587 struct peer_group
*group
, as_t
*as
)
2589 int first_member
= 0;
2592 int cap_enhe_preset
= 0;
2594 /* Lookup the peer. */
2596 peer
= peer_lookup(bgp
, su
);
2598 /* The peer exist, bind it to the peer-group */
2600 /* When the peer already belongs to a peer-group, check the
2602 if (peer_group_active(peer
)) {
2604 /* The peer is already bound to the peer-group,
2607 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2610 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2613 /* The peer has not specified a remote-as, inherit it from the
2615 if (peer
->as_type
== AS_UNSPECIFIED
) {
2616 peer
->as_type
= group
->conf
->as_type
;
2617 peer
->as
= group
->conf
->as
;
2620 if (!group
->conf
->as
) {
2621 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2622 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2625 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2628 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2632 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2633 cap_enhe_preset
= 1;
2635 peer_group2peer_config_copy(group
, peer
);
2638 * Capability extended-nexthop is enabled for an interface
2640 * default. So, fix that up here.
2642 if (peer
->conf_if
&& cap_enhe_preset
)
2643 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2645 FOREACH_AFI_SAFI (afi
, safi
) {
2646 if (group
->conf
->afc
[afi
][safi
]) {
2647 peer
->afc
[afi
][safi
] = 1;
2649 if (peer_af_find(peer
, afi
, safi
)
2650 || peer_af_create(peer
, afi
, safi
)) {
2651 peer_group2peer_config_copy_af(
2652 group
, peer
, afi
, safi
);
2654 } else if (peer
->afc
[afi
][safi
])
2655 peer_deactivate(peer
, afi
, safi
);
2659 assert(group
&& peer
->group
== group
);
2661 struct listnode
*pn
;
2662 pn
= listnode_lookup(bgp
->peer
, peer
);
2663 list_delete_node(bgp
->peer
, pn
);
2664 peer
->group
= group
;
2665 listnode_add_sort(bgp
->peer
, peer
);
2667 peer
= peer_lock(peer
); /* group->peer list reference */
2668 listnode_add(group
->peer
, peer
);
2672 /* Advertisement-interval reset */
2673 if (!CHECK_FLAG(group
->conf
->config
,
2674 PEER_CONFIG_ROUTEADV
)) {
2675 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2676 group
->conf
->v_routeadv
=
2677 BGP_DEFAULT_IBGP_ROUTEADV
;
2679 group
->conf
->v_routeadv
=
2680 BGP_DEFAULT_EBGP_ROUTEADV
;
2683 /* ebgp-multihop reset */
2684 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2685 group
->conf
->ttl
= MAXTTL
;
2687 /* local-as reset */
2688 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2689 group
->conf
->change_local_as
= 0;
2690 UNSET_FLAG(peer
->flags
,
2691 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2692 UNSET_FLAG(peer
->flags
,
2693 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2697 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2699 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2700 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2701 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2702 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2704 bgp_session_reset(peer
);
2708 /* Create a new peer. */
2710 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2711 && (!group
->conf
->as
)) {
2712 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2715 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2716 group
->conf
->as_type
, 0, 0, group
);
2718 peer
= peer_lock(peer
); /* group->peer list reference */
2719 listnode_add(group
->peer
, peer
);
2721 peer_group2peer_config_copy(group
, peer
);
2723 /* If the peer-group is active for this afi/safi then activate
2725 FOREACH_AFI_SAFI (afi
, safi
) {
2726 if (group
->conf
->afc
[afi
][safi
]) {
2727 peer
->afc
[afi
][safi
] = 1;
2728 peer_af_create(peer
, afi
, safi
);
2729 peer_group2peer_config_copy_af(group
, peer
, afi
,
2731 } else if (peer
->afc
[afi
][safi
])
2732 peer_deactivate(peer
, afi
, safi
);
2735 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2737 /* Set up peer's events and timers. */
2738 if (peer_active(peer
))
2739 bgp_timer_set(peer
);
2745 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2746 struct peer_group
*group
)
2752 if (group
!= peer
->group
)
2753 return BGP_ERR_PEER_GROUP_MISMATCH
;
2755 FOREACH_AFI_SAFI (afi
, safi
) {
2756 if (peer
->afc
[afi
][safi
]) {
2757 peer
->afc
[afi
][safi
] = 0;
2758 peer_af_flag_reset(peer
, afi
, safi
);
2760 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2762 "couldn't delete af structure for peer %s",
2768 assert(listnode_lookup(group
->peer
, peer
));
2769 peer_unlock(peer
); /* peer group list reference */
2770 listnode_delete(group
->peer
, peer
);
2772 other
= peer
->doppelganger
;
2774 if (group
->conf
->as
) {
2776 if (other
&& other
->status
!= Deleted
) {
2779 listnode_delete(group
->peer
, other
);
2781 other
->group
= NULL
;
2787 bgp_bfd_deregister_peer(peer
);
2788 peer_global_config_reset(peer
);
2790 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2791 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2792 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2793 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2795 bgp_session_reset(peer
);
2800 static int bgp_startup_timer_expire(struct thread
*thread
)
2804 bgp
= THREAD_ARG(thread
);
2805 bgp
->t_startup
= NULL
;
2810 /* BGP instance creation by `router bgp' commands. */
2811 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2812 enum bgp_instance_type inst_type
)
2818 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2821 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2822 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2823 zlog_debug("Creating Default VRF, AS %u", *as
);
2825 zlog_debug("Creating %s %s, AS %u",
2826 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2833 bgp
->inst_type
= inst_type
;
2834 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2836 bgp
->peer_self
= peer_new(bgp
);
2837 if (bgp
->peer_self
->host
)
2838 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2839 bgp
->peer_self
->host
=
2840 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2841 if (bgp
->peer_self
->hostname
!= NULL
) {
2842 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2843 bgp
->peer_self
->hostname
= NULL
;
2845 if (cmd_hostname_get())
2846 bgp
->peer_self
->hostname
=
2847 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2849 if (bgp
->peer_self
->domainname
!= NULL
) {
2850 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2851 bgp
->peer_self
->domainname
= NULL
;
2853 if (cmd_domainname_get())
2854 bgp
->peer_self
->domainname
=
2855 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2856 bgp
->peer
= list_new();
2857 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2858 bgp
->peerhash
= hash_create(peer_hash_key_make
,
2861 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2863 bgp
->group
= list_new();
2864 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2866 FOREACH_AFI_SAFI (afi
, safi
) {
2867 bgp
->route
[afi
][safi
] = bgp_table_init(afi
, safi
);
2868 bgp
->aggregate
[afi
][safi
] = bgp_table_init(afi
, safi
);
2869 bgp
->rib
[afi
][safi
] = bgp_table_init(afi
, safi
);
2871 /* Enable maximum-paths */
2872 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2874 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2878 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2879 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2880 bgp
->default_subgroup_pkt_queue_max
=
2881 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2882 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2883 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2884 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2885 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2886 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2887 bgp
->dynamic_neighbors_count
= 0;
2888 #if DFLT_BGP_IMPORT_CHECK
2889 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2891 #if DFLT_BGP_SHOW_HOSTNAME
2892 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2894 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2895 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2897 #if DFLT_BGP_DETERMINISTIC_MED
2898 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2900 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2905 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2906 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2908 assert(bgp
->rfapi_cfg
);
2910 #endif /* ENABLE_BGP_VNC */
2913 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2915 /* TODO - The startup timer needs to be run for the whole of BGP
2917 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2918 bgp
->restart_time
, &bgp
->t_startup
);
2921 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2922 memory_order_relaxed
);
2923 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2924 memory_order_relaxed
);
2925 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2929 update_bgp_group_init(bgp
);
2934 /* Return the "default VRF" instance of BGP. */
2935 struct bgp
*bgp_get_default(void)
2938 struct listnode
*node
, *nnode
;
2940 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2941 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2946 /* Lookup BGP entry. */
2947 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2950 struct listnode
*node
, *nnode
;
2952 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2954 && ((bgp
->name
== NULL
&& name
== NULL
)
2955 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2960 /* Lookup BGP structure by view name. */
2961 struct bgp
*bgp_lookup_by_name(const char *name
)
2964 struct listnode
*node
, *nnode
;
2966 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2967 if ((bgp
->name
== NULL
&& name
== NULL
)
2968 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2973 /* Lookup BGP instance based on VRF id. */
2974 /* Note: Only to be used for incoming messages from Zebra. */
2975 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2979 /* Lookup VRF (in tree) and follow link. */
2980 vrf
= vrf_lookup_by_id(vrf_id
);
2983 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2986 /* Called from VTY commands. */
2987 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
2988 enum bgp_instance_type inst_type
)
2992 /* Multiple instance check. */
2993 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
2995 bgp
= bgp_lookup_by_name(name
);
2997 bgp
= bgp_get_default();
2999 /* Already exists. */
3001 if (bgp
->as
!= *as
) {
3003 return BGP_ERR_INSTANCE_MISMATCH
;
3005 if (bgp
->inst_type
!= inst_type
)
3006 return BGP_ERR_INSTANCE_MISMATCH
;
3011 /* BGP instance name can not be specified for single instance.
3014 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3016 /* Get default BGP structure if exists. */
3017 bgp
= bgp_get_default();
3020 if (bgp
->as
!= *as
) {
3022 return BGP_ERR_AS_MISMATCH
;
3029 bgp
= bgp_create(as
, name
, inst_type
);
3030 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3031 bgp_address_init(bgp
);
3032 bgp_tip_hash_init(bgp
);
3036 bgp
->t_rmap_def_originate_eval
= NULL
;
3038 /* Create BGP server socket, if first instance. */
3039 if (list_isempty(bm
->bgp
) && !bgp_option_check(BGP_OPT_NO_LISTEN
)) {
3040 if (bgp_socket(bm
->port
, bm
->address
) < 0)
3041 return BGP_ERR_INVALID_VALUE
;
3044 listnode_add(bm
->bgp
, bgp
);
3046 /* If Default instance or VRF, link to the VRF structure, if present. */
3047 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3048 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3051 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3053 bgp_vrf_link(bgp
, vrf
);
3056 /* Register with Zebra, if needed */
3057 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3058 bgp_zebra_instance_register(bgp
);
3065 * Make BGP instance "up". Applies only to VRFs (non-default) and
3066 * implies the VRF has been learnt from Zebra.
3068 void bgp_instance_up(struct bgp
*bgp
)
3071 struct listnode
*node
, *next
;
3073 /* Register with zebra. */
3074 bgp_zebra_instance_register(bgp
);
3076 /* Kick off any peers that may have been configured. */
3077 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3078 if (!BGP_PEER_START_SUPPRESSED(peer
))
3079 BGP_EVENT_ADD(peer
, BGP_Start
);
3082 /* Process any networks that have been configured. */
3083 bgp_static_add(bgp
);
3087 * Make BGP instance "down". Applies only to VRFs (non-default) and
3088 * implies the VRF has been deleted by Zebra.
3090 void bgp_instance_down(struct bgp
*bgp
)
3093 struct listnode
*node
;
3094 struct listnode
*next
;
3097 if (bgp
->t_rmap_def_originate_eval
) {
3098 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3099 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3103 /* Bring down peers, so corresponding routes are purged. */
3104 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3105 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3106 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3107 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3109 bgp_session_reset(peer
);
3112 /* Purge network and redistributed routes. */
3113 bgp_purge_static_redist_routes(bgp
);
3115 /* Cleanup registered nexthops (flags) */
3116 bgp_cleanup_nexthops(bgp
);
3119 /* Delete BGP instance. */
3120 int bgp_delete(struct bgp
*bgp
)
3123 struct peer_group
*group
;
3124 struct listnode
*node
, *next
;
3129 THREAD_OFF(bgp
->t_startup
);
3131 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3132 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3133 zlog_debug("Deleting Default VRF");
3135 zlog_debug("Deleting %s %s",
3136 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3143 if (bgp
->t_rmap_def_originate_eval
) {
3144 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3145 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3149 /* Inform peers we're going down. */
3150 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3151 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3152 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3153 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3156 /* Delete static routes (networks). */
3157 bgp_static_delete(bgp
);
3159 /* Unset redistribution. */
3160 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3161 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3162 if (i
!= ZEBRA_ROUTE_BGP
)
3163 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3165 /* Free peers and peer-groups. */
3166 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3167 peer_group_delete(group
);
3169 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3172 if (bgp
->peer_self
) {
3173 peer_delete(bgp
->peer_self
);
3174 bgp
->peer_self
= NULL
;
3177 update_bgp_group_free(bgp
);
3179 /* TODO - Other memory may need to be freed - e.g., NHT */
3184 bgp_cleanup_routes(bgp
);
3186 /* Remove visibility via the master list - there may however still be
3187 * routes to be processed still referencing the struct bgp.
3189 listnode_delete(bm
->bgp
, bgp
);
3190 if (list_isempty(bm
->bgp
))
3193 /* Deregister from Zebra, if needed */
3194 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3195 bgp_zebra_instance_deregister(bgp
);
3197 /* Free interfaces in this instance. */
3200 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3202 bgp_vrf_unlink(bgp
, vrf
);
3204 thread_master_free_unused(bm
->master
);
3205 bgp_unlock(bgp
); /* initial reference */
3210 void bgp_free(struct bgp
*bgp
)
3214 struct bgp_table
*table
;
3215 struct bgp_node
*rn
;
3216 struct bgp_rmap
*rmap
;
3220 list_delete_and_null(&bgp
->group
);
3221 list_delete_and_null(&bgp
->peer
);
3223 if (bgp
->peerhash
) {
3224 hash_free(bgp
->peerhash
);
3225 bgp
->peerhash
= NULL
;
3228 FOREACH_AFI_SAFI (afi
, safi
) {
3229 /* Special handling for 2-level routing tables. */
3230 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3231 || safi
== SAFI_EVPN
) {
3232 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3233 rn
= bgp_route_next(rn
)) {
3234 table
= (struct bgp_table
*)rn
->info
;
3235 bgp_table_finish(&table
);
3238 if (bgp
->route
[afi
][safi
])
3239 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3240 if (bgp
->aggregate
[afi
][safi
])
3241 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3242 if (bgp
->rib
[afi
][safi
])
3243 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3244 rmap
= &bgp
->table_map
[afi
][safi
];
3246 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3249 bgp_scan_finish(bgp
);
3250 bgp_address_destroy(bgp
);
3251 bgp_tip_hash_destroy(bgp
);
3253 bgp_evpn_cleanup(bgp
);
3256 XFREE(MTYPE_BGP
, bgp
->name
);
3258 XFREE(MTYPE_BGP
, bgp
);
3261 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3264 struct listnode
*node
, *nnode
;
3270 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3271 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3272 && !CHECK_FLAG(peer
->sflags
,
3273 PEER_STATUS_ACCEPT_PEER
))
3275 } else if (bm
->bgp
!= NULL
) {
3276 struct listnode
*bgpnode
, *nbgpnode
;
3278 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3279 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3281 && !strcmp(peer
->conf_if
, conf_if
)
3282 && !CHECK_FLAG(peer
->sflags
,
3283 PEER_STATUS_ACCEPT_PEER
))
3289 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3292 struct listnode
*node
, *nnode
;
3298 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3299 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3300 && !CHECK_FLAG(peer
->sflags
,
3301 PEER_STATUS_ACCEPT_PEER
))
3303 } else if (bm
->bgp
!= NULL
) {
3304 struct listnode
*bgpnode
, *nbgpnode
;
3306 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3307 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3309 && !strcmp(peer
->hostname
, hostname
)
3310 && !CHECK_FLAG(peer
->sflags
,
3311 PEER_STATUS_ACCEPT_PEER
))
3317 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3319 struct peer
*peer
= NULL
;
3320 struct peer tmp_peer
;
3322 memset(&tmp_peer
, 0, sizeof(struct peer
));
3325 * We do not want to find the doppelganger peer so search for the peer
3327 * the hash that has PEER_FLAG_CONFIG_NODE
3329 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3334 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3335 } else if (bm
->bgp
!= NULL
) {
3336 struct listnode
*bgpnode
, *nbgpnode
;
3338 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3339 /* Skip VRFs, this function will not be invoked without
3341 * when examining VRFs.
3343 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3346 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3356 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3357 union sockunion
*su
,
3358 struct peer_group
*group
)
3364 /* Create peer first; we've already checked group config is valid. */
3365 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3366 group
->conf
->as_type
, 0, 0, group
);
3371 peer
= peer_lock(peer
);
3372 listnode_add(group
->peer
, peer
);
3374 peer_group2peer_config_copy(group
, peer
);
3377 * Bind peer for all AFs configured for the group. We don't call
3378 * peer_group_bind as that is sub-optimal and does some stuff we don't
3381 FOREACH_AFI_SAFI (afi
, safi
) {
3382 if (!group
->conf
->afc
[afi
][safi
])
3384 peer
->afc
[afi
][safi
] = 1;
3386 if (!peer_af_find(peer
, afi
, safi
))
3387 peer_af_create(peer
, afi
, safi
);
3389 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3392 /* Mark as dynamic, but also as a "config node" for other things to
3394 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3395 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3401 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3402 struct prefix
*prefix
)
3404 struct listnode
*node
, *nnode
;
3405 struct prefix
*range
;
3408 afi
= family2afi(prefix
->family
);
3410 if (group
->listen_range
[afi
])
3411 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3413 if (prefix_match(range
, prefix
))
3420 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3421 struct prefix
**listen_range
)
3423 struct prefix
*range
= NULL
;
3424 struct peer_group
*group
= NULL
;
3425 struct listnode
*node
, *nnode
;
3427 *listen_range
= NULL
;
3429 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3430 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3433 } else if (bm
->bgp
!= NULL
) {
3434 struct listnode
*bgpnode
, *nbgpnode
;
3436 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3437 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3438 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3444 *listen_range
= range
;
3445 return (group
&& range
) ? group
: NULL
;
3448 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3450 struct peer_group
*group
;
3453 struct prefix prefix
;
3454 struct prefix
*listen_range
;
3456 char buf
[PREFIX2STR_BUFFER
];
3457 char buf1
[PREFIX2STR_BUFFER
];
3459 sockunion2hostprefix(su
, &prefix
);
3461 /* See if incoming connection matches a configured listen range. */
3462 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3473 prefix2str(&prefix
, buf
, sizeof(buf
));
3474 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3476 if (bgp_debug_neighbor_events(NULL
))
3478 "Dynamic Neighbor %s matches group %s listen range %s",
3479 buf
, group
->name
, buf1
);
3481 /* Are we within the listen limit? */
3482 dncount
= gbgp
->dynamic_neighbors_count
;
3484 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3485 if (bgp_debug_neighbor_events(NULL
))
3486 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3487 inet_sutop(su
, buf
),
3488 gbgp
->dynamic_neighbors_limit
);
3492 /* Ensure group is not disabled. */
3493 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3494 if (bgp_debug_neighbor_events(NULL
))
3496 "Dynamic Neighbor %s rejected - group %s disabled",
3501 /* Check that at least one AF is activated for the group. */
3502 if (!peer_group_af_configured(group
)) {
3503 if (bgp_debug_neighbor_events(NULL
))
3505 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3510 /* Create dynamic peer and bind to associated group. */
3511 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3514 gbgp
->dynamic_neighbors_count
= ++dncount
;
3516 if (bgp_debug_neighbor_events(peer
))
3517 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3518 peer
->host
, group
->name
, dncount
);
3523 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3526 if (peer
->group
&& peer
->group
->bgp
) {
3527 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3529 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3531 if (bgp_debug_neighbor_events(peer
))
3532 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3533 peer
->group
->name
, dncount
);
3537 /* If peer is configured at least one address family return 1. */
3538 int peer_active(struct peer
*peer
)
3540 if (BGP_PEER_SU_UNSPEC(peer
))
3542 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3543 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3544 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3545 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3546 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3547 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3548 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3549 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3550 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3555 /* If peer is negotiated at least one address family return 1. */
3556 int peer_active_nego(struct peer
*peer
)
3558 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3559 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3560 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3561 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3562 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3563 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3564 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3565 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3566 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3567 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3568 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3573 /* peer_flag_change_type. */
3574 enum peer_change_type
{
3577 peer_change_reset_in
,
3578 peer_change_reset_out
,
3581 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3582 enum peer_change_type type
)
3584 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3587 if (peer
->status
!= Established
)
3590 if (type
== peer_change_reset
) {
3591 /* If we're resetting session, we've to delete both peer struct
3593 if ((peer
->doppelganger
)
3594 && (peer
->doppelganger
->status
!= Deleted
)
3595 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3596 PEER_FLAG_CONFIG_NODE
)))
3597 peer_delete(peer
->doppelganger
);
3599 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3600 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3601 } else if (type
== peer_change_reset_in
) {
3602 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3603 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3604 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3606 if ((peer
->doppelganger
)
3607 && (peer
->doppelganger
->status
!= Deleted
)
3608 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3609 PEER_FLAG_CONFIG_NODE
)))
3610 peer_delete(peer
->doppelganger
);
3612 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3613 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3615 } else if (type
== peer_change_reset_out
) {
3616 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3617 bgp_announce_route(peer
, afi
, safi
);
3621 struct peer_flag_action
{
3625 /* This flag can be set for peer-group member. */
3626 u_char not_for_member
;
3628 /* Action when the flag is changed. */
3629 enum peer_change_type type
;
3631 /* Peer down cause */
3635 static const struct peer_flag_action peer_flag_action_list
[] = {
3636 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3637 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3638 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3639 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3640 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3641 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3642 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3643 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3646 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3647 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3648 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3649 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3650 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3651 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3652 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3653 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3654 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3655 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3656 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3657 // PEER_FLAG_DEFAULT_ORIGINATE
3658 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3659 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3660 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3661 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3662 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3663 // PEER_FLAG_MAX_PREFIX
3664 // PEER_FLAG_MAX_PREFIX_WARNING
3665 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3666 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3667 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3668 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3669 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3670 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3671 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3672 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3673 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3676 /* Proper action set. */
3677 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3678 int size
, struct peer_flag_action
*action
,
3685 const struct peer_flag_action
*match
= NULL
;
3687 /* Check peer's frag action. */
3688 for (i
= 0; i
< size
; i
++) {
3689 match
= &action_list
[i
];
3691 if (match
->flag
== 0)
3694 if (match
->flag
& flag
) {
3697 if (match
->type
== peer_change_reset_in
)
3699 if (match
->type
== peer_change_reset_out
)
3701 if (match
->type
== peer_change_reset
) {
3705 if (match
->not_for_member
)
3706 action
->not_for_member
= 1;
3710 /* Set peer clear type. */
3711 if (reset_in
&& reset_out
)
3712 action
->type
= peer_change_reset
;
3714 action
->type
= peer_change_reset_in
;
3716 action
->type
= peer_change_reset_out
;
3718 action
->type
= peer_change_none
;
3723 static void peer_flag_modify_action(struct peer
*peer
, u_int32_t flag
)
3725 if (flag
== PEER_FLAG_SHUTDOWN
) {
3726 if (CHECK_FLAG(peer
->flags
, flag
)) {
3727 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3728 peer_nsf_stop(peer
);
3730 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3731 if (peer
->t_pmax_restart
) {
3732 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3733 if (bgp_debug_neighbor_events(peer
))
3735 "%s Maximum-prefix restart timer canceled",
3739 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3740 peer_nsf_stop(peer
);
3742 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3743 char *msg
= peer
->tx_shutdown_message
;
3746 if (!msg
&& peer_group_active(peer
))
3747 msg
= peer
->group
->conf
3748 ->tx_shutdown_message
;
3749 msglen
= msg
? strlen(msg
) : 0;
3757 memcpy(msgbuf
+ 1, msg
, msglen
);
3759 bgp_notify_send_with_data(
3760 peer
, BGP_NOTIFY_CEASE
,
3761 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3762 msgbuf
, msglen
+ 1);
3765 peer
, BGP_NOTIFY_CEASE
,
3766 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3768 bgp_session_reset(peer
);
3770 peer
->v_start
= BGP_INIT_START_TIMER
;
3771 BGP_EVENT_ADD(peer
, BGP_Stop
);
3773 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3774 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3775 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3776 else if (flag
== PEER_FLAG_PASSIVE
)
3777 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3778 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3779 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3781 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3782 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3784 bgp_session_reset(peer
);
3787 /* Change specified peer flag. */
3788 static int peer_flag_modify(struct peer
*peer
, u_int32_t flag
, int set
)
3792 struct peer_group
*group
;
3793 struct peer
*tmp_peer
;
3794 struct listnode
*node
, *nnode
;
3795 struct peer_flag_action action
;
3797 memset(&action
, 0, sizeof(struct peer_flag_action
));
3798 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3800 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3803 /* No flag action is found. */
3805 return BGP_ERR_INVALID_FLAG
;
3807 /* When unset the peer-group member's flag we have to check
3808 peer-group configuration. */
3809 if (!set
&& peer_group_active(peer
))
3810 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3811 if (flag
== PEER_FLAG_SHUTDOWN
)
3812 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3815 /* Flag conflict check. */
3816 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3817 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3818 return BGP_ERR_PEER_FLAG_CONFLICT
;
3820 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3821 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3823 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3828 SET_FLAG(peer
->flags
, flag
);
3830 UNSET_FLAG(peer
->flags
, flag
);
3832 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3833 if (action
.type
== peer_change_reset
)
3834 peer_flag_modify_action(peer
, flag
);
3839 /* peer-group member updates. */
3840 group
= peer
->group
;
3842 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3844 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
3847 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
3851 SET_FLAG(tmp_peer
->flags
, flag
);
3853 UNSET_FLAG(tmp_peer
->flags
, flag
);
3855 if (action
.type
== peer_change_reset
)
3856 peer_flag_modify_action(tmp_peer
, flag
);
3861 int peer_flag_set(struct peer
*peer
, u_int32_t flag
)
3863 return peer_flag_modify(peer
, flag
, 1);
3866 int peer_flag_unset(struct peer
*peer
, u_int32_t flag
)
3868 return peer_flag_modify(peer
, flag
, 0);
3871 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3872 u_int32_t flag
, int set
)
3876 struct listnode
*node
, *nnode
;
3877 struct peer_group
*group
;
3878 struct peer_flag_action action
;
3879 struct peer
*tmp_peer
;
3881 int addpath_tx_used
;
3883 memset(&action
, 0, sizeof(struct peer_flag_action
));
3884 size
= sizeof peer_af_flag_action_list
3885 / sizeof(struct peer_flag_action
);
3887 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3890 /* No flag action is found. */
3892 return BGP_ERR_INVALID_FLAG
;
3894 /* Special check for reflector client. */
3895 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3896 && peer_sort(peer
) != BGP_PEER_IBGP
)
3897 return BGP_ERR_NOT_INTERNAL_PEER
;
3899 /* Special check for remove-private-AS. */
3900 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3901 && peer_sort(peer
) == BGP_PEER_IBGP
)
3902 return BGP_ERR_REMOVE_PRIVATE_AS
;
3904 /* as-override is not allowed for IBGP peers */
3905 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3906 return BGP_ERR_AS_OVERRIDE
;
3908 /* When current flag configuration is same as requested one. */
3909 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3910 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
3912 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
3917 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3919 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3921 /* Execute action when peer is established. */
3922 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
3923 && peer
->status
== Established
) {
3924 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3925 bgp_clear_adj_in(peer
, afi
, safi
);
3927 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3928 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
3929 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
3930 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
3931 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
3932 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3933 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
3934 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3936 peer_change_action(peer
, afi
, safi
, action
.type
);
3940 /* Peer group member updates. */
3941 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3942 group
= peer
->group
;
3944 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3946 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
3951 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
3955 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3957 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3959 if (tmp_peer
->status
== Established
) {
3960 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3961 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
3963 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3964 tmp_peer
->last_reset
=
3965 PEER_DOWN_RR_CLIENT_CHANGE
;
3967 == PEER_FLAG_RSERVER_CLIENT
)
3968 tmp_peer
->last_reset
=
3969 PEER_DOWN_RS_CLIENT_CHANGE
;
3971 == PEER_FLAG_ORF_PREFIX_SM
)
3972 tmp_peer
->last_reset
=
3973 PEER_DOWN_CAPABILITY_CHANGE
;
3975 == PEER_FLAG_ORF_PREFIX_RM
)
3976 tmp_peer
->last_reset
=
3977 PEER_DOWN_CAPABILITY_CHANGE
;
3979 peer_change_action(tmp_peer
, afi
, safi
,
3986 /* Track if addpath TX is in use */
3987 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
3988 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
3990 addpath_tx_used
= 0;
3993 addpath_tx_used
= 1;
3995 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
3996 if (!bgp_flag_check(
3997 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
3999 "%s: enabling bgp deterministic-med, this is required"
4000 " for addpath-tx-bestpath-per-AS",
4004 BGP_FLAG_DETERMINISTIC_MED
);
4005 bgp_recalculate_all_bestpaths(bgp
);
4009 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4011 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4012 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4014 tmp_peer
->af_flags
[afi
][safi
],
4015 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4016 addpath_tx_used
= 1;
4022 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4028 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int32_t flag
)
4030 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4033 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
4036 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4040 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4042 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4043 peer
->tx_shutdown_message
=
4044 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4048 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4050 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4055 /* EBGP multihop configuration. */
4056 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4058 struct peer_group
*group
;
4059 struct listnode
*node
, *nnode
;
4062 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4065 /* see comment in peer_ttl_security_hops_set() */
4066 if (ttl
!= MAXTTL
) {
4067 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4068 group
= peer
->group
;
4069 if (group
->conf
->gtsm_hops
!= 0)
4070 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4072 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4074 if (peer1
->sort
== BGP_PEER_IBGP
)
4077 if (peer1
->gtsm_hops
!= 0)
4078 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4081 if (peer
->gtsm_hops
!= 0)
4082 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4088 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4089 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4090 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4091 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4092 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4094 bgp_session_reset(peer
);
4097 group
= peer
->group
;
4098 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4099 if (peer
->sort
== BGP_PEER_IBGP
)
4102 peer
->ttl
= group
->conf
->ttl
;
4104 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4105 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4106 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4108 bgp_session_reset(peer
);
4114 int peer_ebgp_multihop_unset(struct peer
*peer
)
4116 struct peer_group
*group
;
4117 struct listnode
*node
, *nnode
;
4119 if (peer
->sort
== BGP_PEER_IBGP
)
4122 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4123 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4125 if (peer_group_active(peer
))
4126 peer
->ttl
= peer
->group
->conf
->ttl
;
4130 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4131 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4132 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4133 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4135 bgp_session_reset(peer
);
4137 group
= peer
->group
;
4138 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4139 if (peer
->sort
== BGP_PEER_IBGP
)
4144 if (peer
->fd
>= 0) {
4145 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4147 peer
, BGP_NOTIFY_CEASE
,
4148 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4150 bgp_session_reset(peer
);
4157 /* Neighbor description. */
4158 int peer_description_set(struct peer
*peer
, const char *desc
)
4161 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4163 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4168 int peer_description_unset(struct peer
*peer
)
4171 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4178 /* Neighbor update-source. */
4179 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4181 struct peer_group
*group
;
4182 struct listnode
*node
, *nnode
;
4184 if (peer
->update_if
) {
4185 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4186 && strcmp(peer
->update_if
, ifname
) == 0)
4189 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4190 peer
->update_if
= NULL
;
4193 if (peer
->update_source
) {
4194 sockunion_free(peer
->update_source
);
4195 peer
->update_source
= NULL
;
4198 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4200 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4201 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4202 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4203 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4204 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4206 bgp_session_reset(peer
);
4210 /* peer-group member updates. */
4211 group
= peer
->group
;
4212 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4213 if (peer
->update_if
) {
4214 if (strcmp(peer
->update_if
, ifname
) == 0)
4217 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4218 peer
->update_if
= NULL
;
4221 if (peer
->update_source
) {
4222 sockunion_free(peer
->update_source
);
4223 peer
->update_source
= NULL
;
4226 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4228 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4229 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4230 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4231 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4233 bgp_session_reset(peer
);
4238 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4240 struct peer_group
*group
;
4241 struct listnode
*node
, *nnode
;
4243 if (peer
->update_source
) {
4244 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4245 && sockunion_cmp(peer
->update_source
, su
) == 0)
4247 sockunion_free(peer
->update_source
);
4248 peer
->update_source
= NULL
;
4251 if (peer
->update_if
) {
4252 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4253 peer
->update_if
= NULL
;
4256 peer
->update_source
= sockunion_dup(su
);
4258 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4259 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4260 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4261 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4262 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4264 bgp_session_reset(peer
);
4268 /* peer-group member updates. */
4269 group
= peer
->group
;
4270 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4271 if (peer
->update_source
) {
4272 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4274 sockunion_free(peer
->update_source
);
4275 peer
->update_source
= NULL
;
4278 if (peer
->update_if
) {
4279 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4280 peer
->update_if
= NULL
;
4283 peer
->update_source
= sockunion_dup(su
);
4285 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4286 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4287 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4288 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4290 bgp_session_reset(peer
);
4295 int peer_update_source_unset(struct peer
*peer
)
4297 union sockunion
*su
;
4298 struct peer_group
*group
;
4299 struct listnode
*node
, *nnode
;
4301 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4302 && !peer
->update_if
)
4305 if (peer
->update_source
) {
4306 sockunion_free(peer
->update_source
);
4307 peer
->update_source
= NULL
;
4309 if (peer
->update_if
) {
4310 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4311 peer
->update_if
= NULL
;
4314 if (peer_group_active(peer
)) {
4315 group
= peer
->group
;
4317 if (group
->conf
->update_source
) {
4318 su
= sockunion_dup(group
->conf
->update_source
);
4319 peer
->update_source
= su
;
4320 } else if (group
->conf
->update_if
)
4321 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4322 group
->conf
->update_if
);
4325 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4326 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4327 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4328 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4329 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4331 bgp_session_reset(peer
);
4335 /* peer-group member updates. */
4336 group
= peer
->group
;
4337 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4338 if (!peer
->update_source
&& !peer
->update_if
)
4341 if (peer
->update_source
) {
4342 sockunion_free(peer
->update_source
);
4343 peer
->update_source
= NULL
;
4346 if (peer
->update_if
) {
4347 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4348 peer
->update_if
= NULL
;
4351 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4352 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4353 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4354 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4356 bgp_session_reset(peer
);
4361 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4364 struct peer_group
*group
;
4365 struct listnode
*node
, *nnode
;
4367 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4368 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4370 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4371 SET_FLAG(peer
->af_flags
[afi
][safi
],
4372 PEER_FLAG_DEFAULT_ORIGINATE
);
4375 if (peer
->default_rmap
[afi
][safi
].name
)
4376 XFREE(MTYPE_ROUTE_MAP_NAME
,
4377 peer
->default_rmap
[afi
][safi
].name
);
4378 peer
->default_rmap
[afi
][safi
].name
=
4379 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4380 peer
->default_rmap
[afi
][safi
].map
=
4381 route_map_lookup_by_name(rmap
);
4385 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4386 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4387 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4388 bgp_default_originate(peer
, afi
, safi
, 0);
4389 bgp_announce_route(peer
, afi
, safi
);
4394 /* peer-group member updates. */
4395 group
= peer
->group
;
4396 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4397 SET_FLAG(peer
->af_flags
[afi
][safi
],
4398 PEER_FLAG_DEFAULT_ORIGINATE
);
4401 if (peer
->default_rmap
[afi
][safi
].name
)
4402 XFREE(MTYPE_ROUTE_MAP_NAME
,
4403 peer
->default_rmap
[afi
][safi
].name
);
4404 peer
->default_rmap
[afi
][safi
].name
=
4405 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4406 peer
->default_rmap
[afi
][safi
].map
=
4407 route_map_lookup_by_name(rmap
);
4410 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4411 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4412 bgp_default_originate(peer
, afi
, safi
, 0);
4413 bgp_announce_route(peer
, afi
, safi
);
4419 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4421 struct peer_group
*group
;
4422 struct listnode
*node
, *nnode
;
4424 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4425 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4426 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4427 PEER_FLAG_DEFAULT_ORIGINATE
);
4429 if (peer
->default_rmap
[afi
][safi
].name
)
4430 XFREE(MTYPE_ROUTE_MAP_NAME
,
4431 peer
->default_rmap
[afi
][safi
].name
);
4432 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4433 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4436 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4437 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4438 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4439 bgp_default_originate(peer
, afi
, safi
, 1);
4440 bgp_announce_route(peer
, afi
, safi
);
4445 /* peer-group member updates. */
4446 group
= peer
->group
;
4447 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4448 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4449 PEER_FLAG_DEFAULT_ORIGINATE
);
4451 if (peer
->default_rmap
[afi
][safi
].name
)
4452 XFREE(MTYPE_ROUTE_MAP_NAME
,
4453 peer
->default_rmap
[afi
][safi
].name
);
4454 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4455 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4457 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4458 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4459 bgp_default_originate(peer
, afi
, safi
, 1);
4460 bgp_announce_route(peer
, afi
, safi
);
4466 int peer_port_set(struct peer
*peer
, u_int16_t port
)
4472 int peer_port_unset(struct peer
*peer
)
4474 peer
->port
= BGP_PORT_DEFAULT
;
4479 * Helper function that is called after the name of the policy
4480 * being used by a peer has changed (AF specific). Automatically
4481 * initiates inbound or outbound processing as needed.
4483 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4487 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4488 if (peer
->status
== Established
)
4489 bgp_announce_route(peer
, afi
, safi
);
4491 if (peer
->status
!= Established
)
4494 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4495 PEER_FLAG_SOFT_RECONFIG
))
4496 bgp_soft_reconfig_in(peer
, afi
, safi
);
4497 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4498 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4499 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4504 /* neighbor weight. */
4505 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int16_t weight
)
4507 struct peer_group
*group
;
4508 struct listnode
*node
, *nnode
;
4510 if (peer
->weight
[afi
][safi
] != weight
) {
4511 peer
->weight
[afi
][safi
] = weight
;
4512 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4513 peer_on_policy_change(peer
, afi
, safi
, 0);
4516 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4519 /* peer-group member updates. */
4520 group
= peer
->group
;
4521 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4522 if (peer
->weight
[afi
][safi
] != weight
) {
4523 peer
->weight
[afi
][safi
] = weight
;
4524 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4525 peer_on_policy_change(peer
, afi
, safi
, 0);
4531 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4533 struct peer_group
*group
;
4534 struct listnode
*node
, *nnode
;
4536 /* not the peer-group itself but a peer in a peer-group */
4537 if (peer_group_active(peer
)) {
4538 group
= peer
->group
;
4540 /* inherit weight from the peer-group */
4541 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4542 PEER_FLAG_WEIGHT
)) {
4543 peer
->weight
[afi
][safi
] =
4544 group
->conf
->weight
[afi
][safi
];
4545 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4546 peer_on_policy_change(peer
, afi
, safi
, 0);
4548 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4549 PEER_FLAG_WEIGHT
)) {
4550 peer
->weight
[afi
][safi
] = 0;
4551 peer_af_flag_unset(peer
, afi
, safi
,
4553 peer_on_policy_change(peer
, afi
, safi
, 0);
4559 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4560 peer
->weight
[afi
][safi
] = 0;
4561 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4562 peer_on_policy_change(peer
, afi
, safi
, 0);
4565 /* peer-group member updates. */
4566 group
= peer
->group
;
4569 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4571 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4572 PEER_FLAG_WEIGHT
)) {
4573 peer
->weight
[afi
][safi
] = 0;
4574 peer_af_flag_unset(peer
, afi
, safi
,
4576 peer_on_policy_change(peer
, afi
, safi
,
4585 int peer_timers_set(struct peer
*peer
, u_int32_t keepalive
, u_int32_t holdtime
)
4587 struct peer_group
*group
;
4588 struct listnode
*node
, *nnode
;
4590 /* keepalive value check. */
4591 if (keepalive
> 65535)
4592 return BGP_ERR_INVALID_VALUE
;
4594 /* Holdtime value check. */
4595 if (holdtime
> 65535)
4596 return BGP_ERR_INVALID_VALUE
;
4598 /* Holdtime value must be either 0 or greater than 3. */
4599 if (holdtime
< 3 && holdtime
!= 0)
4600 return BGP_ERR_INVALID_VALUE
;
4602 /* Set value to the configuration. */
4603 peer
->holdtime
= holdtime
;
4604 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4606 /* First work on real peers with timers */
4607 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4608 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4609 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4611 /* Now work on the peer-group timers */
4612 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4614 /* peer-group member updates. */
4615 group
= peer
->group
;
4616 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4617 /* Skip peers that have their own timers */
4618 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4621 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4622 peer
->holdtime
= group
->conf
->holdtime
;
4623 peer
->keepalive
= group
->conf
->keepalive
;
4630 int peer_timers_unset(struct peer
*peer
)
4632 struct peer_group
*group
;
4633 struct listnode
*node
, *nnode
;
4635 /* First work on real peers vs the peer-group */
4636 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4637 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4638 peer
->keepalive
= 0;
4641 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4642 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4643 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4644 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4647 /* peer-group member updates. */
4648 group
= peer
->group
;
4649 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4650 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4651 UNSET_FLAG(peer
->config
,
4652 PEER_GROUP_CONFIG_TIMER
);
4654 peer
->keepalive
= 0;
4658 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4659 group
->conf
->holdtime
= 0;
4660 group
->conf
->keepalive
= 0;
4666 int peer_timers_connect_set(struct peer
*peer
, u_int32_t connect
)
4668 struct peer_group
*group
;
4669 struct listnode
*node
, *nnode
;
4671 if (connect
> 65535)
4672 return BGP_ERR_INVALID_VALUE
;
4674 /* Set value to the configuration. */
4675 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4676 peer
->connect
= connect
;
4678 /* Set value to timer setting. */
4679 peer
->v_connect
= connect
;
4681 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4684 /* peer-group member updates. */
4685 group
= peer
->group
;
4686 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4687 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4688 peer
->connect
= connect
;
4689 peer
->v_connect
= connect
;
4694 int peer_timers_connect_unset(struct peer
*peer
)
4696 struct peer_group
*group
;
4697 struct listnode
*node
, *nnode
;
4699 /* Clear configuration. */
4700 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4703 /* Set timer setting to default value. */
4704 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4706 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4709 /* peer-group member updates. */
4710 group
= peer
->group
;
4711 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4712 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4714 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4719 int peer_advertise_interval_set(struct peer
*peer
, u_int32_t routeadv
)
4721 struct peer_group
*group
;
4722 struct listnode
*node
, *nnode
;
4725 return BGP_ERR_INVALID_VALUE
;
4727 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4728 peer
->routeadv
= routeadv
;
4729 peer
->v_routeadv
= routeadv
;
4731 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4732 update_group_adjust_peer_afs(peer
);
4733 if (peer
->status
== Established
)
4734 bgp_announce_route_all(peer
);
4738 /* peer-group member updates. */
4739 group
= peer
->group
;
4740 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4741 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4742 peer
->routeadv
= routeadv
;
4743 peer
->v_routeadv
= routeadv
;
4744 update_group_adjust_peer_afs(peer
);
4745 if (peer
->status
== Established
)
4746 bgp_announce_route_all(peer
);
4752 int peer_advertise_interval_unset(struct peer
*peer
)
4754 struct peer_group
*group
;
4755 struct listnode
*node
, *nnode
;
4757 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4760 if (peer
->sort
== BGP_PEER_IBGP
)
4761 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4763 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4765 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4766 update_group_adjust_peer_afs(peer
);
4767 if (peer
->status
== Established
)
4768 bgp_announce_route_all(peer
);
4772 /* peer-group member updates. */
4773 group
= peer
->group
;
4774 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4775 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4778 if (peer
->sort
== BGP_PEER_IBGP
)
4779 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4781 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4783 update_group_adjust_peer_afs(peer
);
4784 if (peer
->status
== Established
)
4785 bgp_announce_route_all(peer
);
4791 /* neighbor interface */
4792 void peer_interface_set(struct peer
*peer
, const char *str
)
4795 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4796 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4799 void peer_interface_unset(struct peer
*peer
)
4802 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4803 peer
->ifname
= NULL
;
4807 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4808 int allow_num
, int origin
)
4810 struct peer_group
*group
;
4811 struct listnode
*node
, *nnode
;
4814 if (peer
->allowas_in
[afi
][safi
]
4815 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4816 PEER_FLAG_ALLOWAS_IN
)
4817 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4818 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4819 peer
->allowas_in
[afi
][safi
] = 0;
4820 peer_af_flag_unset(peer
, afi
, safi
,
4821 PEER_FLAG_ALLOWAS_IN
);
4822 peer_af_flag_set(peer
, afi
, safi
,
4823 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4824 peer_on_policy_change(peer
, afi
, safi
, 0);
4827 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4830 group
= peer
->group
;
4831 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4832 if (peer
->allowas_in
[afi
][safi
]
4833 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4834 PEER_FLAG_ALLOWAS_IN
)
4835 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4836 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4837 peer
->allowas_in
[afi
][safi
] = 0;
4838 peer_af_flag_unset(peer
, afi
, safi
,
4839 PEER_FLAG_ALLOWAS_IN
);
4840 peer_af_flag_set(peer
, afi
, safi
,
4841 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4842 peer_on_policy_change(peer
, afi
, safi
, 0);
4846 if (allow_num
< 1 || allow_num
> 10)
4847 return BGP_ERR_INVALID_VALUE
;
4849 if (peer
->allowas_in
[afi
][safi
] != allow_num
4850 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4851 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4852 peer
->allowas_in
[afi
][safi
] = allow_num
;
4853 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4854 peer_af_flag_unset(peer
, afi
, safi
,
4855 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4856 peer_on_policy_change(peer
, afi
, safi
, 0);
4859 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4862 group
= peer
->group
;
4863 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4864 if (peer
->allowas_in
[afi
][safi
] != allow_num
4865 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4866 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4867 peer
->allowas_in
[afi
][safi
] = allow_num
;
4868 peer_af_flag_set(peer
, afi
, safi
,
4869 PEER_FLAG_ALLOWAS_IN
);
4870 peer_af_flag_unset(peer
, afi
, safi
,
4871 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4872 peer_on_policy_change(peer
, afi
, safi
, 0);
4880 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4882 struct peer_group
*group
;
4883 struct peer
*tmp_peer
;
4884 struct listnode
*node
, *nnode
;
4886 /* If this is a peer-group we must first clear the flags for all of the
4887 * peer-group members
4889 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4890 group
= peer
->group
;
4891 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4892 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4893 PEER_FLAG_ALLOWAS_IN
)
4894 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4895 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4896 tmp_peer
->allowas_in
[afi
][safi
] = 0;
4897 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4898 PEER_FLAG_ALLOWAS_IN
);
4899 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4900 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4901 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
4906 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
4907 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4908 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4909 peer
->allowas_in
[afi
][safi
] = 0;
4910 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4911 peer_af_flag_unset(peer
, afi
, safi
,
4912 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4913 peer_on_policy_change(peer
, afi
, safi
, 0);
4919 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
4922 struct bgp
*bgp
= peer
->bgp
;
4923 struct peer_group
*group
;
4924 struct listnode
*node
, *nnode
;
4926 if (peer_sort(peer
) != BGP_PEER_EBGP
4927 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
4928 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
4931 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
4934 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
4936 if (peer
->change_local_as
== as
4937 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4939 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4941 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4943 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4947 peer
->change_local_as
= as
;
4949 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4951 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4954 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4956 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4958 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4959 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4960 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4961 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4962 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4964 bgp_session_reset(peer
);
4968 group
= peer
->group
;
4969 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4970 peer
->change_local_as
= as
;
4972 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4974 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4977 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4979 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4981 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4982 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4983 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4984 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4986 BGP_EVENT_ADD(peer
, BGP_Stop
);
4992 int peer_local_as_unset(struct peer
*peer
)
4994 struct peer_group
*group
;
4995 struct listnode
*node
, *nnode
;
4997 if (!peer
->change_local_as
)
5000 peer
->change_local_as
= 0;
5001 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5002 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5004 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5005 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5006 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5007 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5008 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5010 BGP_EVENT_ADD(peer
, BGP_Stop
);
5015 group
= peer
->group
;
5016 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5017 peer
->change_local_as
= 0;
5018 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5019 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5021 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5022 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5023 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5024 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5026 bgp_session_reset(peer
);
5031 /* Set password for authenticating with the peer. */
5032 int peer_password_set(struct peer
*peer
, const char *password
)
5034 struct listnode
*nn
, *nnode
;
5035 int len
= password
? strlen(password
) : 0;
5036 int ret
= BGP_SUCCESS
;
5038 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5039 return BGP_ERR_INVALID_VALUE
;
5041 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5042 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5046 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5048 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5050 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5051 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5052 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5053 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5055 bgp_session_reset(peer
);
5057 if (BGP_PEER_SU_UNSPEC(peer
))
5060 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5061 : BGP_ERR_TCPSIG_FAILED
;
5064 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5065 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5069 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5071 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5073 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5074 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5075 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5077 bgp_session_reset(peer
);
5079 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5080 if (bgp_md5_set(peer
) < 0)
5081 ret
= BGP_ERR_TCPSIG_FAILED
;
5088 int peer_password_unset(struct peer
*peer
)
5090 struct listnode
*nn
, *nnode
;
5092 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5095 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5096 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5097 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5098 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5100 bgp_session_reset(peer
);
5103 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5105 peer
->password
= NULL
;
5107 if (!BGP_PEER_SU_UNSPEC(peer
))
5108 bgp_md5_unset(peer
);
5113 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5114 peer
->password
= NULL
;
5116 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5117 if (!peer
->password
)
5120 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5121 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5122 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5124 bgp_session_reset(peer
);
5126 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5127 peer
->password
= NULL
;
5129 if (!BGP_PEER_SU_UNSPEC(peer
))
5130 bgp_md5_unset(peer
);
5137 /* Set distribute list to the peer. */
5138 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5141 struct bgp_filter
*filter
;
5142 struct peer_group
*group
;
5143 struct listnode
*node
, *nnode
;
5145 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5146 return BGP_ERR_INVALID_VALUE
;
5148 filter
= &peer
->filter
[afi
][safi
];
5150 if (filter
->plist
[direct
].name
)
5151 return BGP_ERR_PEER_FILTER_CONFLICT
;
5153 if (filter
->dlist
[direct
].name
)
5154 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5155 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5156 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5158 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5159 peer_on_policy_change(peer
, afi
, safi
,
5160 (direct
== FILTER_OUT
) ? 1 : 0);
5164 group
= peer
->group
;
5165 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5166 filter
= &peer
->filter
[afi
][safi
];
5168 if (filter
->dlist
[direct
].name
)
5169 XFREE(MTYPE_BGP_FILTER_NAME
,
5170 filter
->dlist
[direct
].name
);
5171 filter
->dlist
[direct
].name
=
5172 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5173 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5174 peer_on_policy_change(peer
, afi
, safi
,
5175 (direct
== FILTER_OUT
) ? 1 : 0);
5181 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5183 struct bgp_filter
*filter
;
5184 struct bgp_filter
*gfilter
;
5185 struct peer_group
*group
;
5186 struct listnode
*node
, *nnode
;
5188 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5189 return BGP_ERR_INVALID_VALUE
;
5191 filter
= &peer
->filter
[afi
][safi
];
5193 /* apply peer-group filter */
5194 if (peer_group_active(peer
)) {
5195 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5197 if (gfilter
->dlist
[direct
].name
) {
5198 if (filter
->dlist
[direct
].name
)
5199 XFREE(MTYPE_BGP_FILTER_NAME
,
5200 filter
->dlist
[direct
].name
);
5201 filter
->dlist
[direct
].name
=
5202 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5203 gfilter
->dlist
[direct
].name
);
5204 filter
->dlist
[direct
].alist
=
5205 gfilter
->dlist
[direct
].alist
;
5206 peer_on_policy_change(peer
, afi
, safi
,
5207 (direct
== FILTER_OUT
) ? 1 : 0);
5212 if (filter
->dlist
[direct
].name
)
5213 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5214 filter
->dlist
[direct
].name
= NULL
;
5215 filter
->dlist
[direct
].alist
= NULL
;
5217 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5218 peer_on_policy_change(peer
, afi
, safi
,
5219 (direct
== FILTER_OUT
) ? 1 : 0);
5223 group
= peer
->group
;
5224 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5225 filter
= &peer
->filter
[afi
][safi
];
5227 if (filter
->dlist
[direct
].name
)
5228 XFREE(MTYPE_BGP_FILTER_NAME
,
5229 filter
->dlist
[direct
].name
);
5230 filter
->dlist
[direct
].name
= NULL
;
5231 filter
->dlist
[direct
].alist
= NULL
;
5232 peer_on_policy_change(peer
, afi
, safi
,
5233 (direct
== FILTER_OUT
) ? 1 : 0);
5239 /* Update distribute list. */
5240 static void peer_distribute_update(struct access_list
*access
)
5245 struct listnode
*mnode
, *mnnode
;
5246 struct listnode
*node
, *nnode
;
5249 struct peer_group
*group
;
5250 struct bgp_filter
*filter
;
5252 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5254 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5255 access
->name
, 0, 0);
5256 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5257 FOREACH_AFI_SAFI (afi
, safi
) {
5258 filter
= &peer
->filter
[afi
][safi
];
5260 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5262 if (filter
->dlist
[direct
].name
)
5263 filter
->dlist
[direct
]
5264 .alist
= access_list_lookup(
5266 filter
->dlist
[direct
]
5269 filter
->dlist
[direct
].alist
=
5274 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5275 FOREACH_AFI_SAFI (afi
, safi
) {
5276 filter
= &group
->conf
->filter
[afi
][safi
];
5278 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5280 if (filter
->dlist
[direct
].name
)
5281 filter
->dlist
[direct
]
5282 .alist
= access_list_lookup(
5284 filter
->dlist
[direct
]
5287 filter
->dlist
[direct
].alist
=
5293 vnc_prefix_list_update(bgp
);
5298 /* Set prefix list to the peer. */
5299 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5302 struct bgp_filter
*filter
;
5303 struct peer_group
*group
;
5304 struct listnode
*node
, *nnode
;
5306 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5307 return BGP_ERR_INVALID_VALUE
;
5309 filter
= &peer
->filter
[afi
][safi
];
5311 if (filter
->dlist
[direct
].name
)
5312 return BGP_ERR_PEER_FILTER_CONFLICT
;
5314 if (filter
->plist
[direct
].name
)
5315 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5316 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5317 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5319 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5320 peer_on_policy_change(peer
, afi
, safi
,
5321 (direct
== FILTER_OUT
) ? 1 : 0);
5325 group
= peer
->group
;
5326 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5327 filter
= &peer
->filter
[afi
][safi
];
5329 if (filter
->plist
[direct
].name
)
5330 XFREE(MTYPE_BGP_FILTER_NAME
,
5331 filter
->plist
[direct
].name
);
5332 filter
->plist
[direct
].name
=
5333 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5334 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5335 peer_on_policy_change(peer
, afi
, safi
,
5336 (direct
== FILTER_OUT
) ? 1 : 0);
5341 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5344 struct bgp_filter
*filter
;
5345 struct bgp_filter
*gfilter
;
5346 struct peer_group
*group
;
5347 struct listnode
*node
, *nnode
;
5349 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5350 return BGP_ERR_INVALID_VALUE
;
5352 filter
= &peer
->filter
[afi
][safi
];
5354 /* apply peer-group filter */
5355 if (peer_group_active(peer
)) {
5356 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5358 if (gfilter
->plist
[direct
].name
) {
5359 if (filter
->plist
[direct
].name
)
5360 XFREE(MTYPE_BGP_FILTER_NAME
,
5361 filter
->plist
[direct
].name
);
5362 filter
->plist
[direct
].name
=
5363 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5364 gfilter
->plist
[direct
].name
);
5365 filter
->plist
[direct
].plist
=
5366 gfilter
->plist
[direct
].plist
;
5367 peer_on_policy_change(peer
, afi
, safi
,
5368 (direct
== FILTER_OUT
) ? 1 : 0);
5373 if (filter
->plist
[direct
].name
)
5374 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5375 filter
->plist
[direct
].name
= NULL
;
5376 filter
->plist
[direct
].plist
= NULL
;
5378 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5379 peer_on_policy_change(peer
, afi
, safi
,
5380 (direct
== FILTER_OUT
) ? 1 : 0);
5384 group
= peer
->group
;
5385 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5386 filter
= &peer
->filter
[afi
][safi
];
5388 if (filter
->plist
[direct
].name
)
5389 XFREE(MTYPE_BGP_FILTER_NAME
,
5390 filter
->plist
[direct
].name
);
5391 filter
->plist
[direct
].name
= NULL
;
5392 filter
->plist
[direct
].plist
= NULL
;
5393 peer_on_policy_change(peer
, afi
, safi
,
5394 (direct
== FILTER_OUT
) ? 1 : 0);
5400 /* Update prefix-list list. */
5401 static void peer_prefix_list_update(struct prefix_list
*plist
)
5403 struct listnode
*mnode
, *mnnode
;
5404 struct listnode
*node
, *nnode
;
5407 struct peer_group
*group
;
5408 struct bgp_filter
*filter
;
5413 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5416 * Update the prefix-list on update groups.
5418 update_group_policy_update(
5419 bgp
, BGP_POLICY_PREFIX_LIST
,
5420 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5422 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5423 FOREACH_AFI_SAFI (afi
, safi
) {
5424 filter
= &peer
->filter
[afi
][safi
];
5426 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5428 if (filter
->plist
[direct
].name
)
5429 filter
->plist
[direct
]
5430 .plist
= prefix_list_lookup(
5432 filter
->plist
[direct
]
5435 filter
->plist
[direct
].plist
=
5440 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5441 FOREACH_AFI_SAFI (afi
, safi
) {
5442 filter
= &group
->conf
->filter
[afi
][safi
];
5444 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5446 if (filter
->plist
[direct
].name
)
5447 filter
->plist
[direct
]
5448 .plist
= prefix_list_lookup(
5450 filter
->plist
[direct
]
5453 filter
->plist
[direct
].plist
=
5461 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5464 struct bgp_filter
*filter
;
5465 struct peer_group
*group
;
5466 struct listnode
*node
, *nnode
;
5468 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5469 return BGP_ERR_INVALID_VALUE
;
5471 filter
= &peer
->filter
[afi
][safi
];
5473 if (filter
->aslist
[direct
].name
)
5474 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5475 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5476 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5478 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5479 peer_on_policy_change(peer
, afi
, safi
,
5480 (direct
== FILTER_OUT
) ? 1 : 0);
5484 group
= peer
->group
;
5485 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5486 filter
= &peer
->filter
[afi
][safi
];
5488 if (filter
->aslist
[direct
].name
)
5489 XFREE(MTYPE_BGP_FILTER_NAME
,
5490 filter
->aslist
[direct
].name
);
5491 filter
->aslist
[direct
].name
=
5492 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5493 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5494 peer_on_policy_change(peer
, afi
, safi
,
5495 (direct
== FILTER_OUT
) ? 1 : 0);
5500 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
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
->aslist
[direct
].name
) {
5517 if (filter
->aslist
[direct
].name
)
5518 XFREE(MTYPE_BGP_FILTER_NAME
,
5519 filter
->aslist
[direct
].name
);
5520 filter
->aslist
[direct
].name
=
5521 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5522 gfilter
->aslist
[direct
].name
);
5523 filter
->aslist
[direct
].aslist
=
5524 gfilter
->aslist
[direct
].aslist
;
5525 peer_on_policy_change(peer
, afi
, safi
,
5526 (direct
== FILTER_OUT
) ? 1 : 0);
5531 if (filter
->aslist
[direct
].name
)
5532 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5533 filter
->aslist
[direct
].name
= NULL
;
5534 filter
->aslist
[direct
].aslist
= 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
->aslist
[direct
].name
)
5547 XFREE(MTYPE_BGP_FILTER_NAME
,
5548 filter
->aslist
[direct
].name
);
5549 filter
->aslist
[direct
].name
= NULL
;
5550 filter
->aslist
[direct
].aslist
= NULL
;
5551 peer_on_policy_change(peer
, afi
, safi
,
5552 (direct
== FILTER_OUT
) ? 1 : 0);
5558 static void peer_aslist_update(const char *aslist_name
)
5563 struct listnode
*mnode
, *mnnode
;
5564 struct listnode
*node
, *nnode
;
5567 struct peer_group
*group
;
5568 struct bgp_filter
*filter
;
5570 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5571 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5574 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5575 FOREACH_AFI_SAFI (afi
, safi
) {
5576 filter
= &peer
->filter
[afi
][safi
];
5578 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5580 if (filter
->aslist
[direct
].name
)
5581 filter
->aslist
[direct
]
5582 .aslist
= as_list_lookup(
5583 filter
->aslist
[direct
]
5586 filter
->aslist
[direct
].aslist
=
5591 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5592 FOREACH_AFI_SAFI (afi
, safi
) {
5593 filter
= &group
->conf
->filter
[afi
][safi
];
5595 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5597 if (filter
->aslist
[direct
].name
)
5598 filter
->aslist
[direct
]
5599 .aslist
= as_list_lookup(
5600 filter
->aslist
[direct
]
5603 filter
->aslist
[direct
].aslist
=
5611 static void peer_aslist_add(char *aslist_name
)
5613 peer_aslist_update(aslist_name
);
5614 route_map_notify_dependencies((char *)aslist_name
,
5615 RMAP_EVENT_ASLIST_ADDED
);
5618 static void peer_aslist_del(const char *aslist_name
)
5620 peer_aslist_update(aslist_name
);
5621 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5625 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5628 struct bgp_filter
*filter
;
5629 struct peer_group
*group
;
5630 struct listnode
*node
, *nnode
;
5632 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5633 return BGP_ERR_INVALID_VALUE
;
5635 filter
= &peer
->filter
[afi
][safi
];
5637 if (filter
->map
[direct
].name
)
5638 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5640 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5641 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5643 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5644 peer_on_policy_change(peer
, afi
, safi
,
5645 (direct
== RMAP_OUT
) ? 1 : 0);
5649 group
= peer
->group
;
5650 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5651 filter
= &peer
->filter
[afi
][safi
];
5653 if (filter
->map
[direct
].name
)
5654 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5655 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5656 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5657 peer_on_policy_change(peer
, afi
, safi
,
5658 (direct
== RMAP_OUT
) ? 1 : 0);
5663 /* Unset route-map from the peer. */
5664 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5666 struct bgp_filter
*filter
;
5667 struct bgp_filter
*gfilter
;
5668 struct peer_group
*group
;
5669 struct listnode
*node
, *nnode
;
5671 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5672 return BGP_ERR_INVALID_VALUE
;
5674 filter
= &peer
->filter
[afi
][safi
];
5676 /* apply peer-group filter */
5677 if (peer_group_active(peer
)) {
5678 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5680 if (gfilter
->map
[direct
].name
) {
5681 if (filter
->map
[direct
].name
)
5682 XFREE(MTYPE_BGP_FILTER_NAME
,
5683 filter
->map
[direct
].name
);
5684 filter
->map
[direct
].name
=
5685 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5686 gfilter
->map
[direct
].name
);
5687 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5688 peer_on_policy_change(peer
, afi
, safi
,
5689 (direct
== RMAP_OUT
) ? 1 : 0);
5694 if (filter
->map
[direct
].name
)
5695 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5696 filter
->map
[direct
].name
= NULL
;
5697 filter
->map
[direct
].map
= NULL
;
5699 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5700 peer_on_policy_change(peer
, afi
, safi
,
5701 (direct
== RMAP_OUT
) ? 1 : 0);
5705 group
= peer
->group
;
5706 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5707 filter
= &peer
->filter
[afi
][safi
];
5709 if (filter
->map
[direct
].name
)
5710 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5711 filter
->map
[direct
].name
= NULL
;
5712 filter
->map
[direct
].map
= NULL
;
5713 peer_on_policy_change(peer
, afi
, safi
,
5714 (direct
== RMAP_OUT
) ? 1 : 0);
5719 /* Set unsuppress-map to the peer. */
5720 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5723 struct bgp_filter
*filter
;
5724 struct peer_group
*group
;
5725 struct listnode
*node
, *nnode
;
5727 filter
= &peer
->filter
[afi
][safi
];
5729 if (filter
->usmap
.name
)
5730 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5732 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5733 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5735 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5736 peer_on_policy_change(peer
, afi
, safi
, 1);
5740 group
= peer
->group
;
5741 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5742 filter
= &peer
->filter
[afi
][safi
];
5744 if (filter
->usmap
.name
)
5745 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5746 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5747 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5748 peer_on_policy_change(peer
, afi
, safi
, 1);
5753 /* Unset route-map from the peer. */
5754 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5756 struct bgp_filter
*filter
;
5757 struct peer_group
*group
;
5758 struct listnode
*node
, *nnode
;
5760 filter
= &peer
->filter
[afi
][safi
];
5762 if (filter
->usmap
.name
)
5763 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5764 filter
->usmap
.name
= NULL
;
5765 filter
->usmap
.map
= NULL
;
5767 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5768 peer_on_policy_change(peer
, afi
, safi
, 1);
5772 group
= peer
->group
;
5773 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5774 filter
= &peer
->filter
[afi
][safi
];
5776 if (filter
->usmap
.name
)
5777 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5778 filter
->usmap
.name
= NULL
;
5779 filter
->usmap
.map
= NULL
;
5780 peer_on_policy_change(peer
, afi
, safi
, 1);
5785 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5786 u_int32_t max
, u_char threshold
, int warning
,
5789 struct peer_group
*group
;
5790 struct listnode
*node
, *nnode
;
5792 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5793 peer
->pmax
[afi
][safi
] = max
;
5794 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5795 peer
->pmax_restart
[afi
][safi
] = restart
;
5797 SET_FLAG(peer
->af_flags
[afi
][safi
],
5798 PEER_FLAG_MAX_PREFIX_WARNING
);
5800 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5801 PEER_FLAG_MAX_PREFIX_WARNING
);
5803 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5804 group
= peer
->group
;
5805 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5806 SET_FLAG(peer
->af_flags
[afi
][safi
],
5807 PEER_FLAG_MAX_PREFIX
);
5808 peer
->pmax
[afi
][safi
] = max
;
5809 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5810 peer
->pmax_restart
[afi
][safi
] = restart
;
5812 SET_FLAG(peer
->af_flags
[afi
][safi
],
5813 PEER_FLAG_MAX_PREFIX_WARNING
);
5815 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5816 PEER_FLAG_MAX_PREFIX_WARNING
);
5818 if ((peer
->status
== Established
)
5819 && (peer
->afc
[afi
][safi
]))
5820 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5823 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5824 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5830 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5832 struct peer_group
*group
;
5833 struct listnode
*node
, *nnode
;
5835 /* apply peer-group config */
5836 if (peer_group_active(peer
)) {
5837 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5838 PEER_FLAG_MAX_PREFIX
))
5839 SET_FLAG(peer
->af_flags
[afi
][safi
],
5840 PEER_FLAG_MAX_PREFIX
);
5842 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5843 PEER_FLAG_MAX_PREFIX
);
5845 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5846 PEER_FLAG_MAX_PREFIX_WARNING
))
5847 SET_FLAG(peer
->af_flags
[afi
][safi
],
5848 PEER_FLAG_MAX_PREFIX_WARNING
);
5850 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5851 PEER_FLAG_MAX_PREFIX_WARNING
);
5853 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
5854 peer
->pmax_threshold
[afi
][safi
] =
5855 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
5856 peer
->pmax_restart
[afi
][safi
] =
5857 peer
->group
->conf
->pmax_restart
[afi
][safi
];
5861 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5862 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
5863 peer
->pmax
[afi
][safi
] = 0;
5864 peer
->pmax_threshold
[afi
][safi
] = 0;
5865 peer
->pmax_restart
[afi
][safi
] = 0;
5867 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5870 group
= peer
->group
;
5871 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5872 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5873 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5874 PEER_FLAG_MAX_PREFIX_WARNING
);
5875 peer
->pmax
[afi
][safi
] = 0;
5876 peer
->pmax_threshold
[afi
][safi
] = 0;
5877 peer
->pmax_restart
[afi
][safi
] = 0;
5882 int is_ebgp_multihop_configured(struct peer
*peer
)
5884 struct peer_group
*group
;
5885 struct listnode
*node
, *nnode
;
5888 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5889 group
= peer
->group
;
5890 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
5891 && (group
->conf
->ttl
!= 1))
5894 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
5895 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
5896 && (peer1
->ttl
!= 1))
5900 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
5906 /* Set # of hops between us and BGP peer. */
5907 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
5909 struct peer_group
*group
;
5910 struct listnode
*node
, *nnode
;
5913 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
5914 gtsm_hops
, peer
->host
);
5916 /* We cannot configure ttl-security hops when ebgp-multihop is already
5917 set. For non peer-groups, the check is simple. For peer-groups,
5919 slightly messy, because we need to check both the peer-group
5921 and all peer-group members for any trace of ebgp-multihop
5923 before actually applying the ttl-security rules. Cisco really made a
5924 mess of this configuration parameter, and OpenBGPD got it right.
5927 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
5928 if (is_ebgp_multihop_configured(peer
))
5929 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
5931 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5932 peer
->gtsm_hops
= gtsm_hops
;
5934 /* Calling ebgp multihop also resets the session.
5935 * On restart, NHT will get setup correctly as will the
5936 * min & max ttls on the socket. The return value is
5939 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
5944 group
= peer
->group
;
5945 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5947 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5949 /* Calling ebgp multihop also resets the
5951 * On restart, NHT will get setup correctly as
5953 * min & max ttls on the socket. The return
5957 peer_ebgp_multihop_set(peer
, MAXTTL
);
5961 /* Post the first gtsm setup or if its ibgp, maxttl setting
5963 * necessary, just set the minttl.
5965 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5966 peer
->gtsm_hops
= gtsm_hops
;
5969 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
5970 MAXTTL
+ 1 - gtsm_hops
);
5971 if ((peer
->status
< Established
) && peer
->doppelganger
5972 && (peer
->doppelganger
->fd
>= 0))
5973 sockopt_minttl(peer
->su
.sa
.sa_family
,
5974 peer
->doppelganger
->fd
,
5975 MAXTTL
+ 1 - gtsm_hops
);
5977 group
= peer
->group
;
5978 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5980 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5982 /* Change setting of existing peer
5983 * established then change value (may break
5985 * not established yet (teardown session and
5987 * no session then do nothing (will get
5988 * handled by next connection)
5990 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
5992 peer
->su
.sa
.sa_family
, peer
->fd
,
5993 MAXTTL
+ 1 - peer
->gtsm_hops
);
5994 if ((peer
->status
< Established
)
5995 && peer
->doppelganger
5996 && (peer
->doppelganger
->fd
>= 0))
5997 sockopt_minttl(peer
->su
.sa
.sa_family
,
5998 peer
->doppelganger
->fd
,
5999 MAXTTL
+ 1 - gtsm_hops
);
6007 int peer_ttl_security_hops_unset(struct peer
*peer
)
6009 struct peer_group
*group
;
6010 struct listnode
*node
, *nnode
;
6013 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6016 /* if a peer-group member, then reset to peer-group default rather than
6018 if (peer_group_active(peer
))
6019 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6021 peer
->gtsm_hops
= 0;
6023 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6024 /* Invoking ebgp_multihop_set will set the TTL back to the
6026 * value as well as restting the NHT and such. The session is
6029 if (peer
->sort
== BGP_PEER_EBGP
)
6030 ret
= peer_ebgp_multihop_unset(peer
);
6033 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6036 if ((peer
->status
< Established
) && peer
->doppelganger
6037 && (peer
->doppelganger
->fd
>= 0))
6038 sockopt_minttl(peer
->su
.sa
.sa_family
,
6039 peer
->doppelganger
->fd
, 0);
6042 group
= peer
->group
;
6043 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6044 peer
->gtsm_hops
= 0;
6045 if (peer
->sort
== BGP_PEER_EBGP
)
6046 ret
= peer_ebgp_multihop_unset(peer
);
6049 sockopt_minttl(peer
->su
.sa
.sa_family
,
6052 if ((peer
->status
< Established
)
6053 && peer
->doppelganger
6054 && (peer
->doppelganger
->fd
>= 0))
6055 sockopt_minttl(peer
->su
.sa
.sa_family
,
6056 peer
->doppelganger
->fd
,
6066 * If peer clear is invoked in a loop for all peers on the BGP instance,
6067 * it may end up freeing the doppelganger, and if this was the next node
6068 * to the current node, we would end up accessing the freed next node.
6069 * Pass along additional parameter which can be updated if next node
6070 * is freed; only required when walking the peer list on BGP instance.
6072 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6074 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6075 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6076 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6077 if (peer
->t_pmax_restart
) {
6078 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6079 if (bgp_debug_neighbor_events(peer
))
6081 "%s Maximum-prefix restart timer canceled",
6084 BGP_EVENT_ADD(peer
, BGP_Start
);
6088 peer
->v_start
= BGP_INIT_START_TIMER
;
6089 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6090 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6091 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6093 bgp_session_reset_safe(peer
, nnode
);
6098 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6099 enum bgp_clear_type stype
)
6101 struct peer_af
*paf
;
6103 if (peer
->status
!= Established
)
6106 if (!peer
->afc
[afi
][safi
])
6107 return BGP_ERR_AF_UNCONFIGURED
;
6109 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6111 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6112 /* Clear the "neighbor x.x.x.x default-originate" flag */
6113 paf
= peer_af_find(peer
, afi
, safi
);
6114 if (paf
&& paf
->subgroup
6115 && CHECK_FLAG(paf
->subgroup
->sflags
,
6116 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6117 UNSET_FLAG(paf
->subgroup
->sflags
,
6118 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6120 bgp_announce_route(peer
, afi
, safi
);
6123 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6124 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6125 PEER_CAP_ORF_PREFIX_SM_ADV
)
6126 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6127 PEER_CAP_ORF_PREFIX_RM_RCV
)
6128 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6129 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6130 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6133 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6134 PEER_CAP_ORF_PREFIX_RM_RCV
))
6135 prefix_type
= ORF_TYPE_PREFIX
;
6137 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6139 if (filter
->plist
[FILTER_IN
].plist
) {
6140 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6141 PEER_STATUS_ORF_PREFIX_SEND
))
6142 bgp_route_refresh_send(
6143 peer
, afi
, safi
, prefix_type
,
6145 bgp_route_refresh_send(peer
, afi
, safi
,
6147 REFRESH_IMMEDIATE
, 0);
6149 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6150 PEER_STATUS_ORF_PREFIX_SEND
))
6151 bgp_route_refresh_send(
6152 peer
, afi
, safi
, prefix_type
,
6153 REFRESH_IMMEDIATE
, 1);
6155 bgp_route_refresh_send(peer
, afi
, safi
,
6162 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6163 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6164 /* If neighbor has soft reconfiguration inbound flag.
6165 Use Adj-RIB-In database. */
6166 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6167 PEER_FLAG_SOFT_RECONFIG
))
6168 bgp_soft_reconfig_in(peer
, afi
, safi
);
6170 /* If neighbor has route refresh capability, send route
6172 message to the peer. */
6173 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6174 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6175 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6178 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6184 /* Display peer uptime.*/
6185 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, u_char use_json
,
6188 time_t uptime1
, epoch_tbuf
;
6191 /* Check buffer length. */
6192 if (len
< BGP_UPTIME_LEN
) {
6194 zlog_warn("peer_uptime (): buffer shortage %lu",
6196 /* XXX: should return status instead of buf... */
6197 snprintf(buf
, len
, "<error> ");
6202 /* If there is no connection has been done before print `never'. */
6205 json_object_string_add(json
, "peerUptime", "never");
6206 json_object_int_add(json
, "peerUptimeMsec", 0);
6208 snprintf(buf
, len
, "never");
6212 /* Get current time. */
6213 uptime1
= bgp_clock();
6215 tm
= gmtime(&uptime1
);
6217 if (uptime1
< ONE_DAY_SECOND
)
6218 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6220 else if (uptime1
< ONE_WEEK_SECOND
)
6221 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6223 else if (uptime1
< ONE_YEAR_SECOND
)
6224 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6225 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6227 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6229 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6232 epoch_tbuf
= time(NULL
) - uptime1
;
6233 json_object_string_add(json
, "peerUptime", buf
);
6234 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6235 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6242 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6243 afi_t afi
, safi_t safi
)
6245 struct bgp_filter
*filter
;
6246 struct bgp_filter
*gfilter
= NULL
;
6249 int out
= FILTER_OUT
;
6252 filter
= &peer
->filter
[afi
][safi
];
6254 if (peer_group_active(peer
))
6255 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6257 /* distribute-list. */
6258 if (filter
->dlist
[in
].name
)
6259 if (!gfilter
|| !gfilter
->dlist
[in
].name
6260 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6262 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6263 addr
, filter
->dlist
[in
].name
);
6266 if (filter
->dlist
[out
].name
&& !gfilter
) {
6267 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6268 filter
->dlist
[out
].name
);
6272 if (filter
->plist
[in
].name
)
6273 if (!gfilter
|| !gfilter
->plist
[in
].name
6274 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6276 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6277 filter
->plist
[in
].name
);
6280 if (filter
->plist
[out
].name
)
6281 if (!gfilter
|| !gfilter
->plist
[out
].name
6282 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6284 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6285 filter
->plist
[out
].name
);
6289 if (filter
->map
[RMAP_IN
].name
)
6290 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6291 || strcmp(filter
->map
[RMAP_IN
].name
,
6292 gfilter
->map
[RMAP_IN
].name
)
6294 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6295 filter
->map
[RMAP_IN
].name
);
6298 if (filter
->map
[RMAP_OUT
].name
)
6299 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6300 || strcmp(filter
->map
[RMAP_OUT
].name
,
6301 gfilter
->map
[RMAP_OUT
].name
)
6303 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6304 filter
->map
[RMAP_OUT
].name
);
6307 /* unsuppress-map */
6308 if (filter
->usmap
.name
&& !gfilter
) {
6309 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6310 filter
->usmap
.name
);
6314 if (filter
->aslist
[in
].name
)
6315 if (!gfilter
|| !gfilter
->aslist
[in
].name
6316 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6318 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6319 filter
->aslist
[in
].name
);
6322 if (filter
->aslist
[out
].name
&& !gfilter
) {
6323 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6324 filter
->aslist
[out
].name
);
6328 /* BGP peer configuration display function. */
6329 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6332 struct peer
*g_peer
= NULL
;
6333 char buf
[SU_ADDRSTRLEN
];
6335 int if_pg_printed
= FALSE
;
6336 int if_ras_printed
= FALSE
;
6338 /* Skip dynamic neighbors. */
6339 if (peer_dynamic_neighbor(peer
))
6343 addr
= peer
->conf_if
;
6347 /************************************
6348 ****** Global to the neighbor ******
6349 ************************************/
6350 if (peer
->conf_if
) {
6351 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6352 vty_out(vty
, " neighbor %s interface v6only", addr
);
6354 vty_out(vty
, " neighbor %s interface", addr
);
6356 if (peer_group_active(peer
)) {
6357 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6358 if_pg_printed
= TRUE
;
6359 } else if (peer
->as_type
== AS_SPECIFIED
) {
6360 vty_out(vty
, " remote-as %u", peer
->as
);
6361 if_ras_printed
= TRUE
;
6362 } else if (peer
->as_type
== AS_INTERNAL
) {
6363 vty_out(vty
, " remote-as internal");
6364 if_ras_printed
= TRUE
;
6365 } else if (peer
->as_type
== AS_EXTERNAL
) {
6366 vty_out(vty
, " remote-as external");
6367 if_ras_printed
= TRUE
;
6373 /* remote-as and peer-group */
6374 /* peer is a member of a peer-group */
6375 if (peer_group_active(peer
)) {
6376 g_peer
= peer
->group
->conf
;
6378 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6379 if (peer
->as_type
== AS_SPECIFIED
) {
6380 vty_out(vty
, " neighbor %s remote-as %u\n",
6382 } else if (peer
->as_type
== AS_INTERNAL
) {
6384 " neighbor %s remote-as internal\n",
6386 } else if (peer
->as_type
== AS_EXTERNAL
) {
6388 " neighbor %s remote-as external\n",
6393 /* For swpX peers we displayed the peer-group
6394 * via 'neighbor swpX interface peer-group WORD' */
6396 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6400 /* peer is NOT a member of a peer-group */
6402 /* peer is a peer-group, declare the peer-group */
6403 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6404 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6407 if (!if_ras_printed
) {
6408 if (peer
->as_type
== AS_SPECIFIED
) {
6409 vty_out(vty
, " neighbor %s remote-as %u\n",
6411 } else if (peer
->as_type
== AS_INTERNAL
) {
6413 " neighbor %s remote-as internal\n",
6415 } else if (peer
->as_type
== AS_EXTERNAL
) {
6417 " neighbor %s remote-as external\n",
6424 if (peer
->change_local_as
) {
6425 if (!peer_group_active(peer
)
6426 || peer
->change_local_as
!= g_peer
->change_local_as
6427 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6428 != CHECK_FLAG(g_peer
->flags
,
6429 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6430 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6431 != CHECK_FLAG(g_peer
->flags
,
6432 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6433 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6434 peer
->change_local_as
,
6435 CHECK_FLAG(peer
->flags
,
6436 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6439 CHECK_FLAG(peer
->flags
,
6440 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6448 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6452 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6453 if (!peer_group_active(peer
)
6454 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6455 || peer
->tx_shutdown_message
) {
6456 if (peer
->tx_shutdown_message
)
6458 " neighbor %s shutdown message %s\n",
6459 addr
, peer
->tx_shutdown_message
);
6461 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6466 if (peer
->bfd_info
) {
6467 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6468 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6473 if (peer
->password
) {
6474 if (!peer_group_active(peer
) || !g_peer
->password
6475 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6476 vty_out(vty
, " neighbor %s password %s\n", addr
,
6482 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6483 if (!peer_group_active(peer
)) {
6484 vty_out(vty
, " neighbor %s solo\n", addr
);
6489 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6490 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6493 /* Local interface name */
6495 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6499 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6500 if (!peer_group_active(peer
)
6501 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6502 vty_out(vty
, " neighbor %s passive\n", addr
);
6507 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6508 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6509 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6510 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6515 /* ttl-security hops */
6516 if (peer
->gtsm_hops
!= 0) {
6517 if (!peer_group_active(peer
)
6518 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6519 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6520 addr
, peer
->gtsm_hops
);
6524 /* disable-connected-check */
6525 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6526 if (!peer_group_active(peer
)
6527 || !CHECK_FLAG(g_peer
->flags
,
6528 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6529 vty_out(vty
, " neighbor %s disable-connected-check\n",
6535 if (peer
->update_if
) {
6536 if (!peer_group_active(peer
) || !g_peer
->update_if
6537 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6538 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6542 if (peer
->update_source
) {
6543 if (!peer_group_active(peer
) || !g_peer
->update_source
6544 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6546 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6547 sockunion2str(peer
->update_source
, buf
,
6552 /* advertisement-interval */
6553 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6554 && ((!peer_group_active(peer
)
6555 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6556 || (peer_group_active(peer
)
6557 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6558 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6563 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6564 && ((!peer_group_active(peer
)
6565 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6566 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6567 || (peer_group_active(peer
)
6568 && (peer
->keepalive
!= g_peer
->keepalive
6569 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6570 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6571 peer
->keepalive
, peer
->holdtime
);
6574 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6575 && ((!peer_group_active(peer
)
6576 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6577 || (peer_group_active(peer
)
6578 && peer
->connect
!= g_peer
->connect
)))
6581 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6585 /* capability dynamic */
6586 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6587 if (!peer_group_active(peer
)
6588 || !CHECK_FLAG(g_peer
->flags
,
6589 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6590 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6594 /* capability extended-nexthop */
6595 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6596 if (!peer_group_active(peer
)
6597 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6599 " no neighbor %s capability extended-nexthop\n",
6604 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6605 if (!peer_group_active(peer
)
6606 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6608 " neighbor %s capability extended-nexthop\n",
6613 /* dont-capability-negotiation */
6614 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6615 if (!peer_group_active(peer
)
6616 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6617 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6622 /* override-capability */
6623 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6624 if (!peer_group_active(peer
)
6625 || !CHECK_FLAG(g_peer
->flags
,
6626 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6627 vty_out(vty
, " neighbor %s override-capability\n",
6632 /* strict-capability-match */
6633 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6634 if (!peer_group_active(peer
)
6635 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6636 vty_out(vty
, " neighbor %s strict-capability-match\n",
6642 /* BGP peer configuration display function. */
6643 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6644 struct peer
*peer
, afi_t afi
, safi_t safi
)
6646 struct peer
*g_peer
= NULL
;
6649 /* Skip dynamic neighbors. */
6650 if (peer_dynamic_neighbor(peer
))
6654 addr
= peer
->conf_if
;
6658 /************************************
6659 ****** Per AF to the neighbor ******
6660 ************************************/
6661 if (peer_group_active(peer
)) {
6662 g_peer
= peer
->group
->conf
;
6664 /* If the peer-group is active but peer is not, print a 'no
6666 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6667 vty_out(vty
, " no neighbor %s activate\n", addr
);
6670 /* If the peer-group is not active but peer is, print an
6672 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6673 vty_out(vty
, " neighbor %s activate\n", addr
);
6676 if (peer
->afc
[afi
][safi
]) {
6677 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6678 if (bgp_flag_check(bgp
,
6679 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6680 vty_out(vty
, " neighbor %s activate\n",
6684 vty_out(vty
, " neighbor %s activate\n", addr
);
6686 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6687 if (!bgp_flag_check(bgp
,
6688 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6690 " no neighbor %s activate\n",
6697 /* addpath TX knobs */
6698 if (peergroup_af_flag_check(peer
, afi
, safi
,
6699 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6700 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6703 if (peergroup_af_flag_check(peer
, afi
, safi
,
6704 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6705 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6709 /* ORF capability. */
6710 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6711 || peergroup_af_flag_check(peer
, afi
, safi
,
6712 PEER_FLAG_ORF_PREFIX_RM
)) {
6713 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6715 if (peergroup_af_flag_check(peer
, afi
, safi
,
6716 PEER_FLAG_ORF_PREFIX_SM
)
6717 && peergroup_af_flag_check(peer
, afi
, safi
,
6718 PEER_FLAG_ORF_PREFIX_RM
))
6719 vty_out(vty
, " both");
6720 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6721 PEER_FLAG_ORF_PREFIX_SM
))
6722 vty_out(vty
, " send");
6724 vty_out(vty
, " receive");
6728 /* Route reflector client. */
6729 if (peergroup_af_flag_check(peer
, afi
, safi
,
6730 PEER_FLAG_REFLECTOR_CLIENT
)) {
6731 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6734 /* next-hop-self force */
6735 if (peergroup_af_flag_check(peer
, afi
, safi
,
6736 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6737 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6741 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6742 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6745 /* remove-private-AS */
6746 if (peergroup_af_flag_check(peer
, afi
, safi
,
6747 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6748 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6752 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6753 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6754 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6758 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6759 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6760 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6763 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6764 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6765 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6769 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6770 vty_out(vty
, " neighbor %s as-override\n", addr
);
6773 /* send-community print. */
6774 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6775 if (peergroup_af_flag_check(peer
, afi
, safi
,
6776 PEER_FLAG_SEND_COMMUNITY
)
6777 && peergroup_af_flag_check(peer
, afi
, safi
,
6778 PEER_FLAG_SEND_EXT_COMMUNITY
)
6779 && peergroup_af_flag_check(
6781 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6782 vty_out(vty
, " neighbor %s send-community all\n",
6784 } else if (peergroup_af_flag_check(
6786 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6787 vty_out(vty
, " neighbor %s send-community large\n",
6789 } else if (peergroup_af_flag_check(
6791 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6792 vty_out(vty
, " neighbor %s send-community extended\n",
6794 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6795 PEER_FLAG_SEND_COMMUNITY
)) {
6796 vty_out(vty
, " neighbor %s send-community\n", addr
);
6799 if (!peer_af_flag_check(peer
, afi
, safi
,
6800 PEER_FLAG_SEND_COMMUNITY
)
6801 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6802 PEER_FLAG_SEND_COMMUNITY
))
6803 && !peer_af_flag_check(peer
, afi
, safi
,
6804 PEER_FLAG_SEND_EXT_COMMUNITY
)
6806 || peer_af_flag_check(g_peer
, afi
, safi
,
6807 PEER_FLAG_SEND_EXT_COMMUNITY
))
6808 && !peer_af_flag_check(peer
, afi
, safi
,
6809 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6810 && (!g_peer
|| peer_af_flag_check(
6812 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6813 vty_out(vty
, " no neighbor %s send-community all\n",
6816 if (!peer_af_flag_check(peer
, afi
, safi
,
6817 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6819 || peer_af_flag_check(
6821 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6823 " no neighbor %s send-community large\n",
6827 if (!peer_af_flag_check(peer
, afi
, safi
,
6828 PEER_FLAG_SEND_EXT_COMMUNITY
)
6830 || peer_af_flag_check(
6832 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6834 " no neighbor %s send-community extended\n",
6838 if (!peer_af_flag_check(peer
, afi
, safi
,
6839 PEER_FLAG_SEND_COMMUNITY
)
6840 && (!g_peer
|| peer_af_flag_check(
6842 PEER_FLAG_SEND_COMMUNITY
))) {
6844 " no neighbor %s send-community\n",
6850 /* Default information */
6851 if (peergroup_af_flag_check(peer
, afi
, safi
,
6852 PEER_FLAG_DEFAULT_ORIGINATE
)
6854 && ((peer
->default_rmap
[afi
][safi
].name
6855 && !g_peer
->default_rmap
[afi
][safi
].name
)
6856 || (!peer
->default_rmap
[afi
][safi
].name
6857 && g_peer
->default_rmap
[afi
][safi
].name
)
6858 || (peer
->default_rmap
[afi
][safi
].name
6859 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
6860 g_peer
->default_rmap
[afi
][safi
].name
))))) {
6861 vty_out(vty
, " neighbor %s default-originate", addr
);
6862 if (peer
->default_rmap
[afi
][safi
].name
)
6863 vty_out(vty
, " route-map %s",
6864 peer
->default_rmap
[afi
][safi
].name
);
6868 /* Soft reconfiguration inbound. */
6869 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
6870 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
6874 /* maximum-prefix. */
6875 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
6876 if (!peer_group_active(peer
)
6877 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
6878 || g_peer
->pmax_threshold
[afi
][safi
]
6879 != peer
->pmax_threshold
[afi
][safi
]
6880 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
6881 PEER_FLAG_MAX_PREFIX_WARNING
)
6882 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6883 PEER_FLAG_MAX_PREFIX_WARNING
)) {
6884 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
6885 peer
->pmax
[afi
][safi
]);
6886 if (peer
->pmax_threshold
[afi
][safi
]
6887 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
6889 peer
->pmax_threshold
[afi
][safi
]);
6890 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6891 PEER_FLAG_MAX_PREFIX_WARNING
))
6892 vty_out(vty
, " warning-only");
6893 if (peer
->pmax_restart
[afi
][safi
])
6894 vty_out(vty
, " restart %u",
6895 peer
->pmax_restart
[afi
][safi
]);
6899 /* Route server client. */
6900 if (peergroup_af_flag_check(peer
, afi
, safi
,
6901 PEER_FLAG_RSERVER_CLIENT
)) {
6902 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
6905 /* Nexthop-local unchanged. */
6906 if (peergroup_af_flag_check(peer
, afi
, safi
,
6907 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
6908 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
6911 /* allowas-in <1-10> */
6912 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
6913 if (!peer_group_active(peer
)
6914 || !peer_af_flag_check(g_peer
, afi
, safi
,
6915 PEER_FLAG_ALLOWAS_IN
)
6916 || peer
->allowas_in
[afi
][safi
]
6917 != g_peer
->allowas_in
[afi
][safi
]) {
6918 if (peer
->allowas_in
[afi
][safi
] == 3) {
6919 vty_out(vty
, " neighbor %s allowas-in\n",
6922 vty_out(vty
, " neighbor %s allowas-in %d\n",
6923 addr
, peer
->allowas_in
[afi
][safi
]);
6928 /* allowas-in origin */
6929 else if (peer_af_flag_check(peer
, afi
, safi
,
6930 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6931 if (!peer_group_active(peer
)
6932 || !peer_af_flag_check(g_peer
, afi
, safi
,
6933 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6934 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
6939 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
6940 if (!peer_group_active(peer
)
6941 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
6942 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
6943 if (peer
->weight
[afi
][safi
]) {
6944 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
6945 peer
->weight
[afi
][safi
]);
6950 bgp_config_write_filter(vty
, peer
, afi
, safi
);
6952 /* atribute-unchanged. */
6953 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
) ||
6954 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6955 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
6957 if (!peer_group_active(peer
) ||
6958 peergroup_af_flag_check(peer
, afi
, safi
,
6959 PEER_FLAG_AS_PATH_UNCHANGED
) ||
6960 peergroup_af_flag_check(peer
, afi
, safi
,
6961 PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6962 peergroup_af_flag_check(peer
, afi
, safi
,
6963 PEER_FLAG_MED_UNCHANGED
)) {
6966 " neighbor %s attribute-unchanged%s%s%s\n",
6968 peer_af_flag_check(peer
, afi
, safi
,
6969 PEER_FLAG_AS_PATH_UNCHANGED
)
6972 peer_af_flag_check(peer
, afi
, safi
,
6973 PEER_FLAG_NEXTHOP_UNCHANGED
)
6976 peer_af_flag_check(peer
, afi
, safi
,
6977 PEER_FLAG_MED_UNCHANGED
)
6984 /* Address family based peer configuration display. */
6985 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
6989 struct peer_group
*group
;
6990 struct listnode
*node
, *nnode
;
6993 vty_frame(vty
, " !\n address-family ");
6994 if (afi
== AFI_IP
) {
6995 if (safi
== SAFI_UNICAST
)
6996 vty_frame(vty
, "ipv4 unicast");
6997 else if (safi
== SAFI_LABELED_UNICAST
)
6998 vty_frame(vty
, "ipv4 labeled-unicast");
6999 else if (safi
== SAFI_MULTICAST
)
7000 vty_frame(vty
, "ipv4 multicast");
7001 else if (safi
== SAFI_MPLS_VPN
)
7002 vty_frame(vty
, "ipv4 vpn");
7003 else if (safi
== SAFI_ENCAP
)
7004 vty_frame(vty
, "ipv4 encap");
7005 } else if (afi
== AFI_IP6
) {
7006 if (safi
== SAFI_UNICAST
)
7007 vty_frame(vty
, "ipv6 unicast");
7008 else if (safi
== SAFI_LABELED_UNICAST
)
7009 vty_frame(vty
, "ipv6 labeled-unicast");
7010 else if (safi
== SAFI_MULTICAST
)
7011 vty_frame(vty
, "ipv6 multicast");
7012 else if (safi
== SAFI_MPLS_VPN
)
7013 vty_frame(vty
, "ipv6 vpn");
7014 else if (safi
== SAFI_ENCAP
)
7015 vty_frame(vty
, "ipv6 encap");
7016 } else if (afi
== AFI_L2VPN
) {
7017 if (safi
== SAFI_EVPN
)
7018 vty_frame(vty
, "l2vpn evpn");
7020 vty_frame(vty
, "\n");
7022 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7024 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7026 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7028 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7029 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7031 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7032 /* Skip dynamic neighbors. */
7033 if (peer_dynamic_neighbor(peer
))
7036 /* Do not display doppelganger peers */
7037 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7038 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7041 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7042 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7044 if (safi
== SAFI_EVPN
)
7045 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7047 vty_endframe(vty
, " exit-address-family\n");
7050 int bgp_config_write(struct vty
*vty
)
7054 struct peer_group
*group
;
7056 struct listnode
*node
, *nnode
;
7057 struct listnode
*mnode
, *mnnode
;
7059 /* BGP Multiple instance. */
7060 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7061 vty_out(vty
, "no bgp multiple-instance\n");
7065 /* BGP Config type. */
7066 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7067 vty_out(vty
, "bgp config-type cisco\n");
7071 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7072 vty_out(vty
, "bgp route-map delay-timer %u\n",
7073 bm
->rmap_update_timer
);
7076 vty_out(vty
, "!\n");
7078 /* BGP configuration. */
7079 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7080 /* Router bgp ASN */
7081 vty_out(vty
, "router bgp %u", bgp
->as
);
7083 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7085 vty_out(vty
, " %s %s",
7087 == BGP_INSTANCE_TYPE_VIEW
)
7094 /* No Synchronization */
7095 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7096 vty_out(vty
, " no synchronization\n");
7098 /* BGP fast-external-failover. */
7099 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7100 vty_out(vty
, " no bgp fast-external-failover\n");
7102 /* BGP router ID. */
7103 if (bgp
->router_id_static
.s_addr
!= 0)
7104 vty_out(vty
, " bgp router-id %s\n",
7105 inet_ntoa(bgp
->router_id_static
));
7107 /* BGP log-neighbor-changes. */
7108 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7109 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7110 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7112 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7116 /* BGP configuration. */
7117 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7118 vty_out(vty
, " bgp always-compare-med\n");
7120 /* BGP default ipv4-unicast. */
7121 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7122 vty_out(vty
, " no bgp default ipv4-unicast\n");
7124 /* BGP default local-preference. */
7125 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7126 vty_out(vty
, " bgp default local-preference %u\n",
7127 bgp
->default_local_pref
);
7129 /* BGP default show-hostname */
7130 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7131 != DFLT_BGP_SHOW_HOSTNAME
)
7132 vty_out(vty
, " %sbgp default show-hostname\n",
7133 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7137 /* BGP default subgroup-pkt-queue-max. */
7138 if (bgp
->default_subgroup_pkt_queue_max
7139 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7140 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7141 bgp
->default_subgroup_pkt_queue_max
);
7143 /* BGP client-to-client reflection. */
7144 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7145 vty_out(vty
, " no bgp client-to-client reflection\n");
7147 /* BGP cluster ID. */
7148 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7149 vty_out(vty
, " bgp cluster-id %s\n",
7150 inet_ntoa(bgp
->cluster_id
));
7152 /* Disable ebgp connected nexthop check */
7153 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7155 " bgp disable-ebgp-connected-route-check\n");
7157 /* Confederation identifier*/
7158 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7159 vty_out(vty
, " bgp confederation identifier %i\n",
7162 /* Confederation peer */
7163 if (bgp
->confed_peers_cnt
> 0) {
7166 vty_out(vty
, " bgp confederation peers");
7168 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7169 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7174 /* BGP enforce-first-as. */
7175 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7176 vty_out(vty
, " bgp enforce-first-as\n");
7178 /* BGP deterministic-med. */
7179 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7180 != DFLT_BGP_DETERMINISTIC_MED
)
7181 vty_out(vty
, " %sbgp deterministic-med\n",
7182 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7186 /* BGP update-delay. */
7187 bgp_config_write_update_delay(vty
, bgp
);
7189 if (bgp
->v_maxmed_onstartup
7190 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7191 vty_out(vty
, " bgp max-med on-startup %u",
7192 bgp
->v_maxmed_onstartup
);
7193 if (bgp
->maxmed_onstartup_value
7194 != BGP_MAXMED_VALUE_DEFAULT
)
7196 bgp
->maxmed_onstartup_value
);
7199 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7200 vty_out(vty
, " bgp max-med administrative");
7201 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7202 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7207 bgp_config_write_wpkt_quanta(vty
, bgp
);
7209 bgp_config_write_rpkt_quanta(vty
, bgp
);
7212 bgp_config_write_coalesce_time(vty
, bgp
);
7214 /* BGP graceful-restart. */
7215 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7217 " bgp graceful-restart stalepath-time %u\n",
7218 bgp
->stalepath_time
);
7219 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7220 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7222 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7223 vty_out(vty
, " bgp graceful-restart\n");
7225 /* BGP graceful-shutdown */
7226 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7227 vty_out(vty
, " bgp graceful-shutdown\n");
7229 /* BGP graceful-restart Preserve State F bit. */
7230 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7232 " bgp graceful-restart preserve-fw-state\n");
7234 /* BGP bestpath method. */
7235 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7236 vty_out(vty
, " bgp bestpath as-path ignore\n");
7237 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7238 vty_out(vty
, " bgp bestpath as-path confed\n");
7240 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7241 if (bgp_flag_check(bgp
,
7242 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7244 " bgp bestpath as-path multipath-relax as-set\n");
7247 " bgp bestpath as-path multipath-relax\n");
7251 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7253 " bgp route-reflector allow-outbound-policy\n");
7255 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7256 vty_out(vty
, " bgp bestpath compare-routerid\n");
7257 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7258 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7259 vty_out(vty
, " bgp bestpath med");
7260 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7261 vty_out(vty
, " confed");
7262 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7263 vty_out(vty
, " missing-as-worst");
7267 /* BGP network import check. */
7268 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7269 != DFLT_BGP_IMPORT_CHECK
)
7270 vty_out(vty
, " %sbgp network import-check\n",
7271 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7275 /* BGP flag dampening. */
7276 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7277 BGP_CONFIG_DAMPENING
))
7278 bgp_config_write_damp(vty
);
7280 /* BGP timers configuration. */
7281 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7282 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7283 vty_out(vty
, " timers bgp %u %u\n",
7284 bgp
->default_keepalive
, bgp
->default_holdtime
);
7287 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7288 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7291 /* Normal neighbor configuration. */
7292 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7293 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7294 bgp_config_write_peer_global(vty
, bgp
, peer
);
7297 /* listen range and limit for dynamic BGP neighbors */
7298 bgp_config_write_listen(vty
, bgp
);
7300 /* No auto-summary */
7301 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7302 vty_out(vty
, " no auto-summary\n");
7304 /* IPv4 unicast configuration. */
7305 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7307 /* IPv4 multicast configuration. */
7308 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7310 /* IPv4 labeled-unicast configuration. */
7311 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7313 /* IPv4 VPN configuration. */
7314 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7316 /* ENCAPv4 configuration. */
7317 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7319 /* IPv6 unicast configuration. */
7320 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7322 /* IPv6 multicast configuration. */
7323 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7325 /* IPv6 labeled-unicast configuration. */
7326 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7327 SAFI_LABELED_UNICAST
);
7329 /* IPv6 VPN configuration. */
7330 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7332 /* ENCAPv6 configuration. */
7333 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7335 /* EVPN configuration. */
7336 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7339 bgp_rfapi_cfg_write(vty
, bgp
);
7342 vty_out(vty
, "!\n");
7347 void bgp_master_init(struct thread_master
*master
)
7351 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7354 bm
->bgp
= list_new();
7355 bm
->listen_sockets
= list_new();
7356 bm
->port
= BGP_PORT_DEFAULT
;
7357 bm
->master
= master
;
7358 bm
->start_time
= bgp_clock();
7359 bm
->t_rmap_update
= NULL
;
7360 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7362 bgp_process_queue_init();
7364 /* Enable multiple instances by default. */
7365 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7367 QOBJ_REG(bm
, bgp_master
);
7371 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7372 * instance delete (non-default only) or BGP exit.
7374 static void bgp_if_finish(struct bgp
*bgp
)
7376 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7377 struct interface
*ifp
;
7379 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7382 FOR_ALL_INTERFACES (vrf
, ifp
) {
7383 struct listnode
*c_node
, *c_nnode
;
7384 struct connected
*c
;
7386 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7387 bgp_connected_delete(bgp
, c
);
7391 extern void bgp_snmp_init(void);
7393 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7395 struct vrf
*vrf
= NULL
;
7396 struct listnode
*next
;
7399 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7400 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7401 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7404 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7405 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7408 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7412 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7413 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7414 {.completions
= NULL
},
7417 static void bgp_pthreads_init()
7421 frr_pthread_new("BGP i/o thread", PTHREAD_IO
, bgp_io_start
,
7423 frr_pthread_new("BGP keepalives thread", PTHREAD_KEEPALIVES
,
7424 bgp_keepalives_start
, bgp_keepalives_stop
);
7426 /* pre-run initialization */
7427 bgp_keepalives_init();
7431 void bgp_pthreads_run()
7433 pthread_attr_t attr
;
7434 pthread_attr_init(&attr
);
7435 pthread_attr_setschedpolicy(&attr
, SCHED_FIFO
);
7437 frr_pthread_run(PTHREAD_IO
, &attr
, NULL
);
7438 frr_pthread_run(PTHREAD_KEEPALIVES
, &attr
, NULL
);
7441 void bgp_pthreads_finish()
7443 frr_pthread_stop_all();
7444 frr_pthread_finish();
7450 /* allocates some vital data structures used by peer commands in
7453 /* pre-init pthreads */
7454 bgp_pthreads_init();
7457 bgp_zebra_init(bm
->master
);
7460 vnc_zebra_init(bm
->master
);
7463 /* BGP VTY commands installation. */
7471 bgp_route_map_init();
7472 bgp_scan_vty_init();
7477 bgp_ethernetvpn_init();
7479 /* Access list initialize. */
7481 access_list_add_hook(peer_distribute_update
);
7482 access_list_delete_hook(peer_distribute_update
);
7484 /* Filter list initialize. */
7486 as_list_add_hook(peer_aslist_add
);
7487 as_list_delete_hook(peer_aslist_del
);
7489 /* Prefix list initialize.*/
7491 prefix_list_add_hook(peer_prefix_list_update
);
7492 prefix_list_delete_hook(peer_prefix_list_update
);
7494 /* Community list initialize. */
7495 bgp_clist
= community_list_init();
7500 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7503 void bgp_terminate(void)
7507 struct listnode
*node
, *nnode
;
7508 struct listnode
*mnode
, *mnnode
;
7512 /* Close the listener sockets first as this prevents peers from
7514 * to reconnect on receiving the peer unconfig message. In the presence
7515 * of a large number of peers this will ensure that no peer is left with
7516 * a dangling connection
7518 /* reverse bgp_master_init */
7520 if (bm
->listen_sockets
)
7521 list_delete_and_null(&bm
->listen_sockets
);
7523 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7524 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7525 if (peer
->status
== Established
7526 || peer
->status
== OpenSent
7527 || peer
->status
== OpenConfirm
)
7528 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7529 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7531 if (bm
->process_main_queue
) {
7532 work_queue_free(bm
->process_main_queue
);
7533 bm
->process_main_queue
= NULL
;
7536 if (bm
->t_rmap_update
)
7537 BGP_TIMER_OFF(bm
->t_rmap_update
);