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"
82 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
83 DEFINE_QOBJ_TYPE(bgp_master
)
85 DEFINE_QOBJ_TYPE(peer
)
87 /* BGP process wide configuration. */
88 static struct bgp_master bgp_master
;
90 /* BGP process wide configuration pointer to export. */
91 struct bgp_master
*bm
;
93 /* BGP community-list. */
94 struct community_list_handler
*bgp_clist
;
96 unsigned int multipath_num
= MULTIPATH_NUM
;
98 static void bgp_if_finish(struct bgp
*bgp
);
100 extern struct zclient
*zclient
;
102 void bgp_session_reset(struct peer
*peer
)
104 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
105 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
106 peer_delete(peer
->doppelganger
);
108 BGP_EVENT_ADD(peer
, BGP_Stop
);
112 * During session reset, we may delete the doppelganger peer, which would
113 * be the next node to the current node. If the session reset was invoked
114 * during walk of peer list, we would end up accessing the freed next
115 * node. This function moves the next node along.
117 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
122 n
= (nnode
) ? *nnode
: NULL
;
123 npeer
= (n
) ? listgetdata(n
) : NULL
;
125 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
126 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
127 PEER_FLAG_CONFIG_NODE
))) {
128 if (peer
->doppelganger
== npeer
)
129 /* nnode and *nnode are confirmed to be non-NULL here */
130 *nnode
= (*nnode
)->next
;
131 peer_delete(peer
->doppelganger
);
134 BGP_EVENT_ADD(peer
, BGP_Stop
);
137 /* BGP global flag manipulation. */
138 int bgp_option_set(int flag
)
142 case BGP_OPT_MULTIPLE_INSTANCE
:
143 case BGP_OPT_CONFIG_CISCO
:
144 case BGP_OPT_NO_LISTEN
:
145 SET_FLAG(bm
->options
, flag
);
148 return BGP_ERR_INVALID_FLAG
;
153 int bgp_option_unset(int flag
)
156 case BGP_OPT_MULTIPLE_INSTANCE
:
157 if (listcount(bm
->bgp
) > 1)
158 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
161 case BGP_OPT_CONFIG_CISCO
:
162 UNSET_FLAG(bm
->options
, flag
);
165 return BGP_ERR_INVALID_FLAG
;
170 int bgp_option_check(int flag
)
172 return CHECK_FLAG(bm
->options
, flag
);
175 /* BGP flag manipulation. */
176 int bgp_flag_set(struct bgp
*bgp
, int flag
)
178 SET_FLAG(bgp
->flags
, flag
);
182 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
184 UNSET_FLAG(bgp
->flags
, flag
);
188 int bgp_flag_check(struct bgp
*bgp
, int flag
)
190 return CHECK_FLAG(bgp
->flags
, flag
);
193 /* Internal function to set BGP structure configureation flag. */
194 static void bgp_config_set(struct bgp
*bgp
, int config
)
196 SET_FLAG(bgp
->config
, config
);
199 static void bgp_config_unset(struct bgp
*bgp
, int config
)
201 UNSET_FLAG(bgp
->config
, config
);
204 static int bgp_config_check(struct bgp
*bgp
, int config
)
206 return CHECK_FLAG(bgp
->config
, config
);
209 /* Set BGP router identifier. */
210 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
213 struct listnode
*node
, *nnode
;
215 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
218 /* EVPN uses router id in RD, withdraw them */
219 if (bgp
->advertise_all_vni
)
220 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
222 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
224 /* Set all peer's local identifier with this value. */
225 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
226 IPV4_ADDR_COPY(&peer
->local_id
, id
);
228 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
229 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
230 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
231 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
235 /* EVPN uses router id in RD, update them */
236 if (bgp
->advertise_all_vni
)
237 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
242 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
244 struct listnode
*node
, *nnode
;
247 if (vrf_id
== VRF_DEFAULT
) {
248 /* Router-id change for default VRF has to also update all
250 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
251 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
254 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
255 if (!bgp
->router_id_static
.s_addr
)
256 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
259 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
261 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
263 if (!bgp
->router_id_static
.s_addr
)
264 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
269 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
271 bgp
->router_id_static
= id
;
272 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
276 /* BGP's cluster-id control. */
277 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
280 struct listnode
*node
, *nnode
;
282 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
283 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
286 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
287 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
289 /* Clear all IBGP peer. */
290 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
291 if (peer
->sort
!= BGP_PEER_IBGP
)
294 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
295 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
296 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
297 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
303 int bgp_cluster_id_unset(struct bgp
*bgp
)
306 struct listnode
*node
, *nnode
;
308 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
311 bgp
->cluster_id
.s_addr
= 0;
312 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
314 /* Clear all IBGP peer. */
315 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
316 if (peer
->sort
!= BGP_PEER_IBGP
)
319 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
320 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
321 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
322 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
328 /* time_t value that is monotonicly increasing
329 * and uneffected by adjustments to system clock
331 time_t bgp_clock(void)
339 /* BGP timer configuration. */
340 int bgp_timers_set(struct bgp
*bgp
, u_int32_t keepalive
, u_int32_t holdtime
)
342 bgp
->default_keepalive
=
343 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
344 bgp
->default_holdtime
= holdtime
;
349 int bgp_timers_unset(struct bgp
*bgp
)
351 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
352 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
357 /* BGP confederation configuration. */
358 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
361 struct listnode
*node
, *nnode
;
365 return BGP_ERR_INVALID_AS
;
367 /* Remember - were we doing confederation before? */
368 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
370 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
372 /* If we were doing confederation already, this is just an external
373 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
374 were not doing confederation before, reset all EBGP sessions. */
375 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
376 /* We're looking for peers who's AS is not local or part of our
378 if (already_confed
) {
379 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
381 if (BGP_IS_VALID_STATE_FOR_NOTIF(
384 PEER_DOWN_CONFED_ID_CHANGE
;
386 peer
, BGP_NOTIFY_CEASE
,
387 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
389 bgp_session_reset_safe(peer
, &nnode
);
392 /* Not doign confederation before, so reset every
395 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
396 /* Reset the local_as to be our EBGP one */
397 if (peer_sort(peer
) == BGP_PEER_EBGP
)
399 if (BGP_IS_VALID_STATE_FOR_NOTIF(
402 PEER_DOWN_CONFED_ID_CHANGE
;
404 peer
, BGP_NOTIFY_CEASE
,
405 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
407 bgp_session_reset_safe(peer
, &nnode
);
414 int bgp_confederation_id_unset(struct bgp
*bgp
)
417 struct listnode
*node
, *nnode
;
420 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
422 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
423 /* We're looking for peers who's AS is not local */
424 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
425 peer
->local_as
= bgp
->as
;
426 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
427 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
428 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
429 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
433 bgp_session_reset_safe(peer
, &nnode
);
439 /* Is an AS part of the confed or not? */
440 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
447 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
448 if (bgp
->confed_peers
[i
] == as
)
454 /* Add an AS to the confederation set. */
455 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
458 struct listnode
*node
, *nnode
;
461 return BGP_ERR_INVALID_BGP
;
464 return BGP_ERR_INVALID_AS
;
466 if (bgp_confederation_peers_check(bgp
, as
))
469 if (bgp
->confed_peers
)
471 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
472 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
475 XMALLOC(MTYPE_BGP_CONFED_LIST
,
476 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
478 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
479 bgp
->confed_peers_cnt
++;
481 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
482 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
483 if (peer
->as
== as
) {
484 peer
->local_as
= bgp
->as
;
485 if (BGP_IS_VALID_STATE_FOR_NOTIF(
488 PEER_DOWN_CONFED_PEER_CHANGE
;
490 peer
, BGP_NOTIFY_CEASE
,
491 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
493 bgp_session_reset_safe(peer
, &nnode
);
500 /* Delete an AS from the confederation set. */
501 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
506 struct listnode
*node
, *nnode
;
511 if (!bgp_confederation_peers_check(bgp
, as
))
514 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
515 if (bgp
->confed_peers
[i
] == as
)
516 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
517 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
519 bgp
->confed_peers_cnt
--;
521 if (bgp
->confed_peers_cnt
== 0) {
522 if (bgp
->confed_peers
)
523 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
524 bgp
->confed_peers
= NULL
;
527 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
528 bgp
->confed_peers_cnt
* sizeof(as_t
));
530 /* Now reset any peer who's remote AS has just been removed from the
532 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
533 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
534 if (peer
->as
== as
) {
535 peer
->local_as
= bgp
->confed_id
;
536 if (BGP_IS_VALID_STATE_FOR_NOTIF(
539 PEER_DOWN_CONFED_PEER_CHANGE
;
541 peer
, BGP_NOTIFY_CEASE
,
542 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
544 bgp_session_reset_safe(peer
, &nnode
);
552 /* Local preference configuration. */
553 int bgp_default_local_preference_set(struct bgp
*bgp
, u_int32_t local_pref
)
558 bgp
->default_local_pref
= local_pref
;
563 int bgp_default_local_preference_unset(struct bgp
*bgp
)
568 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
573 /* Local preference configuration. */
574 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
,
575 u_int32_t queue_size
)
580 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
585 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
589 bgp
->default_subgroup_pkt_queue_max
=
590 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
595 /* Listen limit configuration. */
596 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
601 bgp
->dynamic_neighbors_limit
= listen_limit
;
606 int bgp_listen_limit_unset(struct bgp
*bgp
)
611 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
616 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
617 afi_t
*afi
, safi_t
*safi
)
619 /* Map from IANA values to internal values, return error if
620 * values are unrecognized.
622 *afi
= afi_iana2int(pkt_afi
);
623 *safi
= safi_iana2int(pkt_safi
);
624 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
630 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
631 iana_safi_t
*pkt_safi
)
633 /* Map from internal values to IANA values, return error if
634 * internal values are bad (unexpected).
636 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
638 *pkt_afi
= afi_int2iana(afi
);
639 *pkt_safi
= safi_int2iana(safi
);
643 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
651 afid
= afindex(afi
, safi
);
652 if (afid
>= BGP_AF_MAX
)
655 assert(peer
->peer_af_array
[afid
] == NULL
);
657 /* Allocate new peer af */
658 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
661 zlog_err("Could not create af structure for peer %s",
666 peer
->peer_af_array
[afid
] = af
;
675 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
682 afid
= afindex(afi
, safi
);
683 if (afid
>= BGP_AF_MAX
)
686 return peer
->peer_af_array
[afid
];
689 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
697 afid
= afindex(afi
, safi
);
698 if (afid
>= BGP_AF_MAX
)
701 af
= peer
->peer_af_array
[afid
];
705 bgp_stop_announce_route_timer(af
);
707 if (PAF_SUBGRP(af
)) {
708 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
709 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
710 af
->subgroup
->update_group
->id
,
711 af
->subgroup
->id
, peer
->host
);
714 update_subgroup_remove_peer(af
->subgroup
, af
);
716 peer
->peer_af_array
[afid
] = NULL
;
717 XFREE(MTYPE_BGP_PEER_AF
, af
);
721 /* Peer comparison function for sorting. */
722 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
724 if (p1
->group
&& !p2
->group
)
727 if (!p1
->group
&& p2
->group
)
730 if (p1
->group
== p2
->group
) {
731 if (p1
->conf_if
&& !p2
->conf_if
)
734 if (!p1
->conf_if
&& p2
->conf_if
)
737 if (p1
->conf_if
&& p2
->conf_if
)
738 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
740 return strcmp(p1
->group
->name
, p2
->group
->name
);
742 return sockunion_cmp(&p1
->su
, &p2
->su
);
745 static unsigned int peer_hash_key_make(void *p
)
747 struct peer
*peer
= p
;
748 return sockunion_hash(&peer
->su
);
751 static int peer_hash_same(const void *p1
, const void *p2
)
753 const struct peer
*peer1
= p1
;
754 const struct peer
*peer2
= p2
;
755 return (sockunion_same(&peer1
->su
, &peer2
->su
)
756 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
757 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
760 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
763 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
766 /* Return true if flag is set for the peer but not the peer-group */
767 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
770 struct peer
*g_peer
= NULL
;
772 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
773 if (peer_group_active(peer
)) {
774 g_peer
= peer
->group
->conf
;
776 /* If this flag is not set for the peer's peer-group
777 * then return true */
778 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
783 /* peer is not in a peer-group but the flag is set to return
793 /* Reset all address family specific configuration. */
794 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
797 struct bgp_filter
*filter
;
798 char orf_name
[BUFSIZ
];
800 filter
= &peer
->filter
[afi
][safi
];
802 /* Clear neighbor filter and route-map */
803 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
804 if (filter
->dlist
[i
].name
) {
805 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
806 filter
->dlist
[i
].name
= NULL
;
808 if (filter
->plist
[i
].name
) {
809 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
810 filter
->plist
[i
].name
= NULL
;
812 if (filter
->aslist
[i
].name
) {
813 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
814 filter
->aslist
[i
].name
= NULL
;
817 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
818 if (filter
->map
[i
].name
) {
819 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
820 filter
->map
[i
].name
= NULL
;
824 /* Clear unsuppress map. */
825 if (filter
->usmap
.name
)
826 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
827 filter
->usmap
.name
= NULL
;
828 filter
->usmap
.map
= NULL
;
830 /* Clear neighbor's all address family flags. */
831 peer
->af_flags
[afi
][safi
] = 0;
833 /* Clear neighbor's all address family sflags. */
834 peer
->af_sflags
[afi
][safi
] = 0;
836 /* Clear neighbor's all address family capabilities. */
837 peer
->af_cap
[afi
][safi
] = 0;
840 peer
->orf_plist
[afi
][safi
] = NULL
;
841 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
842 prefix_bgp_orf_remove_all(afi
, orf_name
);
844 /* Set default neighbor send-community. */
845 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
846 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
847 SET_FLAG(peer
->af_flags
[afi
][safi
],
848 PEER_FLAG_SEND_EXT_COMMUNITY
);
849 SET_FLAG(peer
->af_flags
[afi
][safi
],
850 PEER_FLAG_SEND_LARGE_COMMUNITY
);
853 /* Clear neighbor default_originate_rmap */
854 if (peer
->default_rmap
[afi
][safi
].name
)
855 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
856 peer
->default_rmap
[afi
][safi
].name
= NULL
;
857 peer
->default_rmap
[afi
][safi
].map
= NULL
;
859 /* Clear neighbor maximum-prefix */
860 peer
->pmax
[afi
][safi
] = 0;
861 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
864 /* peer global config reset */
865 static void peer_global_config_reset(struct peer
*peer
)
870 peer
->change_local_as
= 0;
871 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
872 if (peer
->update_source
) {
873 sockunion_free(peer
->update_source
);
874 peer
->update_source
= NULL
;
876 if (peer
->update_if
) {
877 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
878 peer
->update_if
= NULL
;
881 if (peer_sort(peer
) == BGP_PEER_IBGP
)
882 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
884 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
886 /* This is a per-peer specific flag and so we must preserve it */
887 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
892 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
898 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
900 /* Reset some other configs back to defaults. */
901 peer
->v_start
= BGP_INIT_START_TIMER
;
902 peer
->password
= NULL
;
903 peer
->local_id
= peer
->bgp
->router_id
;
904 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
905 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
907 bfd_info_free(&(peer
->bfd_info
));
909 /* Set back the CONFIG_NODE flag. */
910 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
913 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
914 static bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
921 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
922 if (peer
->as_type
== AS_INTERNAL
)
923 return BGP_PEER_IBGP
;
925 else if (peer
->as_type
== AS_EXTERNAL
)
926 return BGP_PEER_EBGP
;
928 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
929 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
934 peer1
= listnode_head(peer
->group
->peer
);
939 return BGP_PEER_INTERNAL
;
943 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
944 if (peer
->local_as
== 0)
945 return BGP_PEER_INTERNAL
;
947 if (peer
->local_as
== peer
->as
) {
948 if (bgp
->as
== bgp
->confed_id
) {
949 if (peer
->local_as
== bgp
->as
)
950 return BGP_PEER_IBGP
;
952 return BGP_PEER_EBGP
;
954 if (peer
->local_as
== bgp
->confed_id
)
955 return BGP_PEER_EBGP
;
957 return BGP_PEER_IBGP
;
961 if (bgp_confederation_peers_check(bgp
, peer
->as
))
962 return BGP_PEER_CONFED
;
964 return BGP_PEER_EBGP
;
966 if (peer
->as_type
!= AS_SPECIFIED
)
967 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
970 return (peer
->local_as
== 0
972 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
977 /* Calculate and cache the peer "sort" */
978 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
980 peer
->sort
= peer_calc_sort(peer
);
984 static void peer_free(struct peer
*peer
)
986 assert(peer
->status
== Deleted
);
990 /* this /ought/ to have been done already through bgp_stop earlier,
991 * but just to be sure..
994 BGP_READ_OFF(peer
->t_read
);
995 peer_writes_off(peer
);
996 BGP_EVENT_FLUSH(peer
);
998 /* Free connected nexthop, if present */
999 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1000 && !peer_dynamic_neighbor(peer
))
1001 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1004 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1007 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1011 /* Free allocated host character. */
1013 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1017 if (peer
->domainname
) {
1018 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1019 peer
->domainname
= NULL
;
1023 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1024 peer
->ifname
= NULL
;
1027 /* Update source configuration. */
1028 if (peer
->update_source
) {
1029 sockunion_free(peer
->update_source
);
1030 peer
->update_source
= NULL
;
1033 if (peer
->update_if
) {
1034 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1035 peer
->update_if
= NULL
;
1038 if (peer
->notify
.data
)
1039 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1040 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1042 if (peer
->clear_node_queue
) {
1043 work_queue_free(peer
->clear_node_queue
);
1044 peer
->clear_node_queue
= NULL
;
1047 bgp_sync_delete(peer
);
1049 if (peer
->conf_if
) {
1050 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1051 peer
->conf_if
= NULL
;
1054 bfd_info_free(&(peer
->bfd_info
));
1056 bgp_unlock(peer
->bgp
);
1058 memset(peer
, 0, sizeof(struct peer
));
1060 XFREE(MTYPE_BGP_PEER
, peer
);
1063 /* increase reference count on a struct peer */
1064 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1066 assert(peer
&& (peer
->lock
>= 0));
1069 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1077 /* decrease reference count on a struct peer
1078 * struct peer is freed and NULL returned if last reference
1080 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1082 assert(peer
&& (peer
->lock
> 0));
1085 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1090 if (peer
->lock
== 0) {
1098 /* Allocate new peer object, implicitely locked. */
1099 struct peer
*peer_new(struct bgp
*bgp
)
1106 /* bgp argument is absolutely required */
1111 /* Allocate new peer. */
1112 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1114 /* Set default value. */
1116 peer
->v_start
= BGP_INIT_START_TIMER
;
1117 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1118 peer
->status
= Idle
;
1119 peer
->ostatus
= Idle
;
1120 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1121 peer
->bgp
= bgp_lock(bgp
);
1122 peer
= peer_lock(peer
); /* initial reference */
1123 peer
->password
= NULL
;
1125 /* Set default flags. */
1126 FOREACH_AFI_SAFI (afi
, safi
) {
1127 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1128 SET_FLAG(peer
->af_flags
[afi
][safi
],
1129 PEER_FLAG_SEND_COMMUNITY
);
1130 SET_FLAG(peer
->af_flags
[afi
][safi
],
1131 PEER_FLAG_SEND_EXT_COMMUNITY
);
1132 SET_FLAG(peer
->af_flags
[afi
][safi
],
1133 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1135 peer
->orf_plist
[afi
][safi
] = NULL
;
1137 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1139 /* Create buffers. */
1140 peer
->ibuf
= stream_new(BGP_MAX_PACKET_SIZE
);
1141 peer
->obuf
= stream_fifo_new();
1142 pthread_mutex_init(&peer
->obuf_mtx
, NULL
);
1144 /* We use a larger buffer for peer->work in the event that:
1145 * - We RX a BGP_UPDATE where the attributes alone are just
1146 * under BGP_MAX_PACKET_SIZE
1147 * - The user configures an outbound route-map that does many as-path
1148 * prepends or adds many communities. At most they can have
1150 * args in a route-map so there is a finite limit on how large they
1152 * make the attributes.
1154 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1156 * checking for every single attribute as we construct an UPDATE.
1159 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1160 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1163 bgp_sync_init(peer
);
1165 /* Get service port number. */
1166 sp
= getservbyname("bgp", "tcp");
1167 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1169 QOBJ_REG(peer
, peer
);
1174 * This function is invoked when a duplicate peer structure associated with
1175 * a neighbor is being deleted. If this about-to-be-deleted structure is
1176 * the one with all the config, then we have to copy over the info.
1178 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1180 struct peer_af
*paf
;
1188 /* The following function is used by both peer group config copy to
1189 * individual peer and when we transfer config
1191 if (peer_src
->change_local_as
)
1192 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1194 /* peer flags apply */
1195 peer_dst
->flags
= peer_src
->flags
;
1196 peer_dst
->cap
= peer_src
->cap
;
1197 peer_dst
->config
= peer_src
->config
;
1199 peer_dst
->local_as
= peer_src
->local_as
;
1200 peer_dst
->ifindex
= peer_src
->ifindex
;
1201 peer_dst
->port
= peer_src
->port
;
1202 peer_sort(peer_dst
);
1203 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1206 peer_dst
->holdtime
= peer_src
->holdtime
;
1207 peer_dst
->keepalive
= peer_src
->keepalive
;
1208 peer_dst
->connect
= peer_src
->connect
;
1209 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1210 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1211 peer_dst
->routeadv
= peer_src
->routeadv
;
1212 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1214 /* password apply */
1215 if (peer_src
->password
&& !peer_dst
->password
)
1216 peer_dst
->password
=
1217 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1219 FOREACH_AFI_SAFI (afi
, safi
) {
1220 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1221 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1222 peer_dst
->allowas_in
[afi
][safi
] =
1223 peer_src
->allowas_in
[afi
][safi
];
1224 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1227 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1228 paf
= peer_src
->peer_af_array
[afidx
];
1230 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1233 /* update-source apply */
1234 if (peer_src
->update_source
) {
1235 if (peer_dst
->update_source
)
1236 sockunion_free(peer_dst
->update_source
);
1237 if (peer_dst
->update_if
) {
1238 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1239 peer_dst
->update_if
= NULL
;
1241 peer_dst
->update_source
=
1242 sockunion_dup(peer_src
->update_source
);
1243 } else if (peer_src
->update_if
) {
1244 if (peer_dst
->update_if
)
1245 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1246 if (peer_dst
->update_source
) {
1247 sockunion_free(peer_dst
->update_source
);
1248 peer_dst
->update_source
= NULL
;
1250 peer_dst
->update_if
=
1251 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1254 if (peer_src
->ifname
) {
1255 if (peer_dst
->ifname
)
1256 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1259 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1263 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1264 struct interface
*ifp
)
1266 struct connected
*ifc
;
1269 struct listnode
*node
;
1271 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1272 * IPv4 address of the other end.
1274 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1275 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1276 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1277 if (p
.prefixlen
== 30) {
1278 peer
->su
.sa
.sa_family
= AF_INET
;
1279 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1281 peer
->su
.sin
.sin_addr
.s_addr
=
1283 else if (addr
% 4 == 2)
1284 peer
->su
.sin
.sin_addr
.s_addr
=
1286 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1287 peer
->su
.sin
.sin_len
=
1288 sizeof(struct sockaddr_in
);
1289 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1291 } else if (p
.prefixlen
== 31) {
1292 peer
->su
.sa
.sa_family
= AF_INET
;
1293 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1295 peer
->su
.sin
.sin_addr
.s_addr
=
1298 peer
->su
.sin
.sin_addr
.s_addr
=
1300 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1301 peer
->su
.sin
.sin_len
=
1302 sizeof(struct sockaddr_in
);
1303 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1305 } else if (bgp_debug_neighbor_events(peer
))
1307 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1315 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1316 struct interface
*ifp
)
1318 struct nbr_connected
*ifc_nbr
;
1320 /* Have we learnt the peer's IPv6 link-local address? */
1321 if (ifp
->nbr_connected
1322 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1323 peer
->su
.sa
.sa_family
= AF_INET6
;
1324 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1325 sizeof(struct in6_addr
));
1327 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1329 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1337 * Set or reset the peer address socketunion structure based on the
1338 * learnt/derived peer address. If the address has changed, update the
1339 * password on the listen socket, if needed.
1341 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1343 struct interface
*ifp
;
1345 int peer_addr_updated
= 0;
1350 prev_family
= peer
->su
.sa
.sa_family
;
1351 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1353 /* If BGP unnumbered is not "v6only", we first see if we can
1355 * peer's IPv4 address.
1357 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1359 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1361 /* If "v6only" or we can't derive peer's IPv4 address, see if
1363 * learnt the peer's IPv6 link-local address. This is from the
1365 * IPv6 address in router advertisement.
1367 if (!peer_addr_updated
)
1369 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1371 /* If we could derive the peer address, we may need to install the
1373 * configured for the peer, if any, on the listen socket. Otherwise,
1375 * that peer's address is not available and uninstall the password, if
1378 if (peer_addr_updated
) {
1379 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1382 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1383 bgp_md5_unset(peer
);
1384 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1385 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1388 /* Since our su changed we need to del/add peer to the peerhash */
1389 hash_release(peer
->bgp
->peerhash
, peer
);
1390 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1393 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1396 struct bgp_node
*rn
, *nrn
;
1398 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1399 rn
= bgp_route_next(rn
)) {
1400 if (rn
->info
!= NULL
) {
1401 /* Special handling for 2-level routing
1403 if (safi
== SAFI_MPLS_VPN
1404 || safi
== SAFI_ENCAP
1405 || safi
== SAFI_EVPN
) {
1406 for (nrn
= bgp_table_top((
1410 nrn
= bgp_route_next(nrn
))
1411 bgp_process(bgp
, nrn
,
1414 bgp_process(bgp
, rn
, afi
, safi
);
1419 /* Force a bestpath recalculation for all prefixes. This is used
1420 * when 'bgp bestpath' commands are entered.
1422 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1427 FOREACH_AFI_SAFI (afi
, safi
) {
1428 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1432 /* Create new BGP peer. */
1433 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1434 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1435 int as_type
, afi_t afi
, safi_t safi
,
1436 struct peer_group
*group
)
1440 char buf
[SU_ADDRSTRLEN
];
1442 peer
= peer_new(bgp
);
1444 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1445 bgp_peer_conf_if_to_su_update(peer
);
1447 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1448 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1451 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1453 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1454 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1456 peer
->local_as
= local_as
;
1457 peer
->as
= remote_as
;
1458 peer
->as_type
= as_type
;
1459 peer
->local_id
= bgp
->router_id
;
1460 peer
->v_holdtime
= bgp
->default_holdtime
;
1461 peer
->v_keepalive
= bgp
->default_keepalive
;
1462 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1463 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1465 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1467 peer
= peer_lock(peer
); /* bgp peer list reference */
1468 peer
->group
= group
;
1469 listnode_add_sort(bgp
->peer
, peer
);
1470 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1472 active
= peer_active(peer
);
1474 /* Last read and reset time set */
1475 peer
->readtime
= peer
->resettime
= bgp_clock();
1477 /* Default TTL set. */
1478 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1480 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1483 peer
->afc
[afi
][safi
] = 1;
1484 peer_af_create(peer
, afi
, safi
);
1487 /* Set up peer's events and timers. */
1488 if (!active
&& peer_active(peer
))
1489 bgp_timer_set(peer
);
1494 /* Make accept BGP peer. This function is only called from the test code */
1495 struct peer
*peer_create_accept(struct bgp
*bgp
)
1499 peer
= peer_new(bgp
);
1501 peer
= peer_lock(peer
); /* bgp peer list reference */
1502 listnode_add_sort(bgp
->peer
, peer
);
1508 * Return true if we have a peer configured to use this afi/safi
1510 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1512 struct listnode
*node
;
1515 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1516 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1519 if (peer
->afc
[afi
][safi
])
1526 /* Change peer's AS number. */
1527 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1529 bgp_peer_sort_t type
;
1533 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1534 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1535 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1536 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1537 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1539 bgp_session_reset(peer
);
1541 type
= peer_sort(peer
);
1543 peer
->as_type
= as_specified
;
1545 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1546 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1547 && peer
->bgp
->as
!= as
)
1548 peer
->local_as
= peer
->bgp
->confed_id
;
1550 peer
->local_as
= peer
->bgp
->as
;
1552 /* Advertisement-interval reset */
1555 conf
= peer
->group
->conf
;
1557 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1558 peer
->v_routeadv
= conf
->routeadv
;
1560 /* Only go back to the default advertisement-interval if the user had
1562 * already configured it */
1563 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1564 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1565 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1567 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1570 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1572 else if (type
== BGP_PEER_IBGP
)
1575 /* reflector-client reset */
1576 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1577 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1578 PEER_FLAG_REFLECTOR_CLIENT
);
1579 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1580 PEER_FLAG_REFLECTOR_CLIENT
);
1581 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1582 PEER_FLAG_REFLECTOR_CLIENT
);
1583 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1584 PEER_FLAG_REFLECTOR_CLIENT
);
1585 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1586 PEER_FLAG_REFLECTOR_CLIENT
);
1587 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1588 PEER_FLAG_REFLECTOR_CLIENT
);
1589 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1590 PEER_FLAG_REFLECTOR_CLIENT
);
1591 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1592 PEER_FLAG_REFLECTOR_CLIENT
);
1593 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1594 PEER_FLAG_REFLECTOR_CLIENT
);
1595 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1596 PEER_FLAG_REFLECTOR_CLIENT
);
1597 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1598 PEER_FLAG_REFLECTOR_CLIENT
);
1601 /* local-as reset */
1602 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1603 peer
->change_local_as
= 0;
1604 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1605 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1609 /* If peer does not exist, create new one. If peer already exists,
1610 set AS number to the peer. */
1611 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1612 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1618 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1620 peer
= peer_lookup(bgp
, su
);
1623 /* Not allowed for a dynamic peer. */
1624 if (peer_dynamic_neighbor(peer
)) {
1626 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1629 /* When this peer is a member of peer-group. */
1631 if (peer
->group
->conf
->as
) {
1632 /* Return peer group's AS number. */
1633 *as
= peer
->group
->conf
->as
;
1634 return BGP_ERR_PEER_GROUP_MEMBER
;
1636 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1637 if ((as_type
!= AS_INTERNAL
)
1638 && (bgp
->as
!= *as
)) {
1640 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1643 if ((as_type
!= AS_EXTERNAL
)
1644 && (bgp
->as
== *as
)) {
1646 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1651 /* Existing peer's AS number change. */
1652 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1653 || (peer
->as_type
!= as_type
))
1654 peer_as_change(peer
, *as
, as_type
);
1657 return BGP_ERR_NO_INTERFACE_CONFIG
;
1659 /* If the peer is not part of our confederation, and its not an
1660 iBGP peer then spoof the source AS */
1661 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1662 && !bgp_confederation_peers_check(bgp
, *as
)
1664 local_as
= bgp
->confed_id
;
1668 /* If this is IPv4 unicast configuration and "no bgp default
1669 ipv4-unicast" is specified. */
1671 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1672 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1673 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1676 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1683 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1684 struct peer
*peer
, afi_t afi
,
1688 int out
= FILTER_OUT
;
1690 struct bgp_filter
*pfilter
;
1691 struct bgp_filter
*gfilter
;
1694 pfilter
= &peer
->filter
[afi
][safi
];
1695 gfilter
= &conf
->filter
[afi
][safi
];
1697 /* peer af_flags apply */
1698 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1700 /* maximum-prefix */
1701 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1702 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1703 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1706 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1709 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1711 /* default-originate route-map */
1712 if (conf
->default_rmap
[afi
][safi
].name
) {
1713 if (peer
->default_rmap
[afi
][safi
].name
)
1714 XFREE(MTYPE_BGP_FILTER_NAME
,
1715 peer
->default_rmap
[afi
][safi
].name
);
1716 peer
->default_rmap
[afi
][safi
].name
=
1717 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1718 conf
->default_rmap
[afi
][safi
].name
);
1719 peer
->default_rmap
[afi
][safi
].map
=
1720 conf
->default_rmap
[afi
][safi
].map
;
1723 /* inbound filter apply */
1724 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1725 if (pfilter
->dlist
[in
].name
)
1726 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1727 pfilter
->dlist
[in
].name
=
1728 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1729 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1732 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1733 if (pfilter
->plist
[in
].name
)
1734 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1735 pfilter
->plist
[in
].name
=
1736 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1737 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1740 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1741 if (pfilter
->aslist
[in
].name
)
1742 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1743 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1744 gfilter
->aslist
[in
].name
);
1745 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1748 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1749 if (pfilter
->map
[RMAP_IN
].name
)
1750 XFREE(MTYPE_BGP_FILTER_NAME
,
1751 pfilter
->map
[RMAP_IN
].name
);
1752 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1753 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1754 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1757 /* outbound filter apply */
1758 if (gfilter
->dlist
[out
].name
) {
1759 if (pfilter
->dlist
[out
].name
)
1760 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1761 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1762 gfilter
->dlist
[out
].name
);
1763 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1765 if (pfilter
->dlist
[out
].name
)
1766 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1767 pfilter
->dlist
[out
].name
= NULL
;
1768 pfilter
->dlist
[out
].alist
= NULL
;
1771 if (gfilter
->plist
[out
].name
) {
1772 if (pfilter
->plist
[out
].name
)
1773 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1774 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1775 gfilter
->plist
[out
].name
);
1776 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1778 if (pfilter
->plist
[out
].name
)
1779 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1780 pfilter
->plist
[out
].name
= NULL
;
1781 pfilter
->plist
[out
].plist
= NULL
;
1784 if (gfilter
->aslist
[out
].name
) {
1785 if (pfilter
->aslist
[out
].name
)
1786 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1787 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1788 gfilter
->aslist
[out
].name
);
1789 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1791 if (pfilter
->aslist
[out
].name
)
1792 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1793 pfilter
->aslist
[out
].name
= NULL
;
1794 pfilter
->aslist
[out
].aslist
= NULL
;
1797 if (gfilter
->map
[RMAP_OUT
].name
) {
1798 if (pfilter
->map
[RMAP_OUT
].name
)
1799 XFREE(MTYPE_BGP_FILTER_NAME
,
1800 pfilter
->map
[RMAP_OUT
].name
);
1801 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1802 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1803 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1805 if (pfilter
->map
[RMAP_OUT
].name
)
1806 XFREE(MTYPE_BGP_FILTER_NAME
,
1807 pfilter
->map
[RMAP_OUT
].name
);
1808 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1809 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1812 if (gfilter
->usmap
.name
) {
1813 if (pfilter
->usmap
.name
)
1814 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1815 pfilter
->usmap
.name
=
1816 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1817 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1819 if (pfilter
->usmap
.name
)
1820 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1821 pfilter
->usmap
.name
= NULL
;
1822 pfilter
->usmap
.map
= NULL
;
1826 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1830 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1831 zlog_err("%s was called for peer-group %s", __func__
,
1836 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1838 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1839 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1840 return BGP_ERR_PEER_SAFI_CONFLICT
;
1842 /* Nothing to do if we've already activated this peer */
1843 if (peer
->afc
[afi
][safi
])
1846 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1849 active
= peer_active(peer
);
1850 peer
->afc
[afi
][safi
] = 1;
1853 peer_group2peer_config_copy_af(peer
->group
, peer
,
1856 if (!active
&& peer_active(peer
)) {
1857 bgp_timer_set(peer
);
1859 if (peer
->status
== Established
) {
1860 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1861 peer
->afc_adv
[afi
][safi
] = 1;
1862 bgp_capability_send(peer
, afi
, safi
,
1864 CAPABILITY_ACTION_SET
);
1865 if (peer
->afc_recv
[afi
][safi
]) {
1866 peer
->afc_nego
[afi
][safi
] = 1;
1867 bgp_announce_route(peer
, afi
, safi
);
1870 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1871 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1872 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1880 /* Activate the peer or peer group for specified AFI and SAFI. */
1881 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1884 struct peer_group
*group
;
1885 struct listnode
*node
, *nnode
;
1886 struct peer
*tmp_peer
;
1889 /* Nothing to do if we've already activated this peer */
1890 if (peer
->afc
[afi
][safi
])
1895 /* This is a peer-group so activate all of the members of the
1896 * peer-group as well */
1897 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1899 /* Do not activate a peer for both SAFI_UNICAST and
1900 * SAFI_LABELED_UNICAST */
1901 if ((safi
== SAFI_UNICAST
1902 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1903 || (safi
== SAFI_LABELED_UNICAST
1904 && peer
->afc
[afi
][SAFI_UNICAST
]))
1905 return BGP_ERR_PEER_SAFI_CONFLICT
;
1907 peer
->afc
[afi
][safi
] = 1;
1908 group
= peer
->group
;
1910 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1911 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1914 ret
|= peer_activate_af(peer
, afi
, safi
);
1917 /* If this is the first peer to be activated for this afi/labeled-unicast
1918 * recalc bestpaths to trigger label allocation */
1919 if (safi
== SAFI_LABELED_UNICAST
&& !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1921 if (BGP_DEBUG(zebra
, ZEBRA
))
1922 zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels");
1924 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1925 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1931 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1934 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1935 zlog_err("%s was called for peer-group %s", __func__
,
1940 /* Nothing to do if we've already deactivated this peer */
1941 if (!peer
->afc
[afi
][safi
])
1944 /* De-activate the address family configuration. */
1945 peer
->afc
[afi
][safi
] = 0;
1947 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1948 zlog_err("couldn't delete af structure for peer %s",
1953 if (peer
->status
== Established
) {
1954 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1955 peer
->afc_adv
[afi
][safi
] = 0;
1956 peer
->afc_nego
[afi
][safi
] = 0;
1958 if (peer_active_nego(peer
)) {
1959 bgp_capability_send(peer
, afi
, safi
,
1961 CAPABILITY_ACTION_UNSET
);
1962 bgp_clear_route(peer
, afi
, safi
);
1963 peer
->pcount
[afi
][safi
] = 0;
1965 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1966 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1967 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1970 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1971 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1972 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1979 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1982 struct peer_group
*group
;
1983 struct peer
*tmp_peer
;
1984 struct listnode
*node
, *nnode
;
1987 /* Nothing to do if we've already de-activated this peer */
1988 if (!peer
->afc
[afi
][safi
])
1991 /* This is a peer-group so de-activate all of the members of the
1992 * peer-group as well */
1993 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1994 peer
->afc
[afi
][safi
] = 0;
1995 group
= peer
->group
;
1997 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1998 zlog_err("couldn't delete af structure for peer %s",
2002 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2003 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2006 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2011 /* If this is the last peer to be deactivated for this afi/labeled-unicast
2012 * recalc bestpaths to trigger label deallocation */
2013 if (safi
== SAFI_LABELED_UNICAST
&&
2014 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] &&
2015 !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2017 if (BGP_DEBUG(zebra
, ZEBRA
))
2018 zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2020 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2021 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2026 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2029 return peer_activate(peer
, afi
, safi
);
2031 return peer_deactivate(peer
, afi
, safi
);
2034 static void peer_nsf_stop(struct peer
*peer
)
2039 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2040 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2042 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2043 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2044 peer
->nsf
[afi
][safi
] = 0;
2046 if (peer
->t_gr_restart
) {
2047 BGP_TIMER_OFF(peer
->t_gr_restart
);
2048 if (bgp_debug_neighbor_events(peer
))
2049 zlog_debug("%s graceful restart timer stopped",
2052 if (peer
->t_gr_stale
) {
2053 BGP_TIMER_OFF(peer
->t_gr_stale
);
2054 if (bgp_debug_neighbor_events(peer
))
2056 "%s graceful restart stalepath timer stopped",
2059 bgp_clear_route_all(peer
);
2062 /* Delete peer from confguration.
2064 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2065 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2067 * This function /should/ take care to be idempotent, to guard against
2068 * it being called multiple times through stray events that come in
2069 * that happen to result in this function being called again. That
2070 * said, getting here for a "Deleted" peer is a bug in the neighbour
2073 int peer_delete(struct peer
*peer
)
2079 struct bgp_filter
*filter
;
2080 struct listnode
*pn
;
2083 assert(peer
->status
!= Deleted
);
2086 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2088 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2089 peer_nsf_stop(peer
);
2091 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2093 /* If this peer belongs to peer group, clear up the
2096 if (peer_dynamic_neighbor(peer
))
2097 peer_drop_dynamic_neighbor(peer
);
2099 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2101 peer
); /* group->peer list reference */
2102 list_delete_node(peer
->group
->peer
, pn
);
2107 /* Withdraw all information from routing table. We can not use
2108 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2109 * executed after peer structure is deleted.
2111 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2113 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2115 if (peer
->doppelganger
) {
2116 peer
->doppelganger
->doppelganger
= NULL
;
2117 peer
->doppelganger
= NULL
;
2120 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2121 bgp_fsm_change_status(peer
, Deleted
);
2123 /* Remove from NHT */
2124 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2125 bgp_unlink_nexthop_by_peer(peer
);
2127 /* Password configuration */
2128 if (peer
->password
) {
2129 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2130 peer
->password
= NULL
;
2132 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2133 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2134 bgp_md5_unset(peer
);
2137 bgp_timer_set(peer
); /* stops all timers for Deleted */
2139 /* Delete from all peer list. */
2140 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2141 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2142 peer_unlock(peer
); /* bgp peer list reference */
2143 list_delete_node(bgp
->peer
, pn
);
2144 hash_release(bgp
->peerhash
, peer
);
2149 stream_free(peer
->ibuf
);
2154 stream_fifo_free(peer
->obuf
);
2159 stream_free(peer
->work
);
2163 if (peer
->scratch
) {
2164 stream_free(peer
->scratch
);
2165 peer
->scratch
= NULL
;
2168 /* Local and remote addresses. */
2169 if (peer
->su_local
) {
2170 sockunion_free(peer
->su_local
);
2171 peer
->su_local
= NULL
;
2174 if (peer
->su_remote
) {
2175 sockunion_free(peer
->su_remote
);
2176 peer
->su_remote
= NULL
;
2179 /* Free filter related memory. */
2180 FOREACH_AFI_SAFI (afi
, safi
) {
2181 filter
= &peer
->filter
[afi
][safi
];
2183 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2184 if (filter
->dlist
[i
].name
) {
2185 XFREE(MTYPE_BGP_FILTER_NAME
,
2186 filter
->dlist
[i
].name
);
2187 filter
->dlist
[i
].name
= NULL
;
2190 if (filter
->plist
[i
].name
) {
2191 XFREE(MTYPE_BGP_FILTER_NAME
,
2192 filter
->plist
[i
].name
);
2193 filter
->plist
[i
].name
= NULL
;
2196 if (filter
->aslist
[i
].name
) {
2197 XFREE(MTYPE_BGP_FILTER_NAME
,
2198 filter
->aslist
[i
].name
);
2199 filter
->aslist
[i
].name
= NULL
;
2203 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2204 if (filter
->map
[i
].name
) {
2205 XFREE(MTYPE_BGP_FILTER_NAME
,
2206 filter
->map
[i
].name
);
2207 filter
->map
[i
].name
= NULL
;
2211 if (filter
->usmap
.name
) {
2212 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2213 filter
->usmap
.name
= NULL
;
2216 if (peer
->default_rmap
[afi
][safi
].name
) {
2217 XFREE(MTYPE_ROUTE_MAP_NAME
,
2218 peer
->default_rmap
[afi
][safi
].name
);
2219 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2223 FOREACH_AFI_SAFI (afi
, safi
)
2224 peer_af_delete(peer
, afi
, safi
);
2226 if (peer
->hostname
) {
2227 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2228 peer
->hostname
= NULL
;
2231 if (peer
->domainname
) {
2232 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2233 peer
->domainname
= NULL
;
2236 peer_unlock(peer
); /* initial reference */
2241 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2243 return strcmp(g1
->name
, g2
->name
);
2246 /* Peer group cofiguration. */
2247 static struct peer_group
*peer_group_new(void)
2249 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2250 sizeof(struct peer_group
));
2253 static void peer_group_free(struct peer_group
*group
)
2255 XFREE(MTYPE_PEER_GROUP
, group
);
2258 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2260 struct peer_group
*group
;
2261 struct listnode
*node
, *nnode
;
2263 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2264 if (strcmp(group
->name
, name
) == 0)
2270 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2272 struct peer_group
*group
;
2275 group
= peer_group_lookup(bgp
, name
);
2279 group
= peer_group_new();
2282 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2283 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2284 group
->peer
= list_new();
2285 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2286 group
->listen_range
[afi
] = list_new();
2287 group
->conf
= peer_new(bgp
);
2288 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2289 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2290 if (group
->conf
->host
)
2291 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2292 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2293 group
->conf
->group
= group
;
2294 group
->conf
->as
= 0;
2295 group
->conf
->ttl
= 1;
2296 group
->conf
->gtsm_hops
= 0;
2297 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2298 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2299 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2300 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2301 group
->conf
->keepalive
= 0;
2302 group
->conf
->holdtime
= 0;
2303 group
->conf
->connect
= 0;
2304 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2305 listnode_add_sort(bgp
->group
, group
);
2310 static void peer_group2peer_config_copy(struct peer_group
*group
,
2320 peer
->as
= conf
->as
;
2323 if (conf
->change_local_as
)
2324 peer
->change_local_as
= conf
->change_local_as
;
2327 peer
->ttl
= conf
->ttl
;
2330 peer
->gtsm_hops
= conf
->gtsm_hops
;
2332 /* this flag is per-neighbor and so has to be preserved */
2333 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2335 /* peer flags apply */
2336 peer
->flags
= conf
->flags
;
2339 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2341 /* peer config apply */
2342 peer
->config
= conf
->config
;
2344 /* peer timers apply */
2345 peer
->holdtime
= conf
->holdtime
;
2346 peer
->keepalive
= conf
->keepalive
;
2347 peer
->connect
= conf
->connect
;
2348 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2349 peer
->v_connect
= conf
->connect
;
2351 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2353 /* advertisement-interval reset */
2354 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2355 peer
->v_routeadv
= conf
->routeadv
;
2356 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2357 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2359 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2361 /* password apply */
2362 if (conf
->password
&& !peer
->password
)
2363 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2365 if (!BGP_PEER_SU_UNSPEC(peer
))
2368 /* update-source apply */
2369 if (conf
->update_source
) {
2370 if (peer
->update_source
)
2371 sockunion_free(peer
->update_source
);
2372 if (peer
->update_if
) {
2373 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2374 peer
->update_if
= NULL
;
2376 peer
->update_source
= sockunion_dup(conf
->update_source
);
2377 } else if (conf
->update_if
) {
2378 if (peer
->update_if
)
2379 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2380 if (peer
->update_source
) {
2381 sockunion_free(peer
->update_source
);
2382 peer
->update_source
= NULL
;
2385 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2388 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2391 /* Peer group's remote AS configuration. */
2392 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2395 struct peer_group
*group
;
2397 struct listnode
*node
, *nnode
;
2399 group
= peer_group_lookup(bgp
, group_name
);
2403 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2407 /* When we setup peer-group AS number all peer group member's AS
2408 number must be updated to same number. */
2409 peer_as_change(group
->conf
, *as
, as_type
);
2411 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2412 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2413 || (peer
->as_type
!= as_type
))
2414 peer_as_change(peer
, *as
, as_type
);
2420 int peer_group_delete(struct peer_group
*group
)
2424 struct prefix
*prefix
;
2426 struct listnode
*node
, *nnode
;
2431 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2432 other
= peer
->doppelganger
;
2434 if (other
&& other
->status
!= Deleted
) {
2435 other
->group
= NULL
;
2439 list_delete_and_null(&group
->peer
);
2441 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2442 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2444 prefix_free(prefix
);
2446 list_delete_and_null(&group
->listen_range
[afi
]);
2449 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2452 bfd_info_free(&(group
->conf
->bfd_info
));
2454 group
->conf
->group
= NULL
;
2455 peer_delete(group
->conf
);
2457 /* Delete from all peer_group list. */
2458 listnode_delete(bgp
->group
, group
);
2460 peer_group_free(group
);
2465 int peer_group_remote_as_delete(struct peer_group
*group
)
2467 struct peer
*peer
, *other
;
2468 struct listnode
*node
, *nnode
;
2470 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2471 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2474 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2475 other
= peer
->doppelganger
;
2479 if (other
&& other
->status
!= Deleted
) {
2480 other
->group
= NULL
;
2484 list_delete_all_node(group
->peer
);
2486 group
->conf
->as
= 0;
2487 group
->conf
->as_type
= AS_UNSPECIFIED
;
2492 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2494 struct prefix
*prefix
;
2495 struct listnode
*node
, *nnode
;
2498 afi
= family2afi(range
->family
);
2500 /* Group needs remote AS configured. */
2501 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2502 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2504 /* Ensure no duplicates. Currently we don't care about overlaps. */
2505 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2506 if (prefix_same(range
, prefix
))
2510 prefix
= prefix_new();
2511 prefix_copy(prefix
, range
);
2512 listnode_add(group
->listen_range
[afi
], prefix
);
2516 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2518 struct prefix
*prefix
, prefix2
;
2519 struct listnode
*node
, *nnode
;
2522 char buf
[PREFIX2STR_BUFFER
];
2524 afi
= family2afi(range
->family
);
2526 /* Identify the listen range. */
2527 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2528 if (prefix_same(range
, prefix
))
2533 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2535 prefix2str(prefix
, buf
, sizeof(buf
));
2537 /* Dispose off any dynamic neighbors that exist due to this listen range
2539 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2540 if (!peer_dynamic_neighbor(peer
))
2543 sockunion2hostprefix(&peer
->su
, &prefix2
);
2544 if (prefix_match(prefix
, &prefix2
)) {
2545 if (bgp_debug_neighbor_events(peer
))
2547 "Deleting dynamic neighbor %s group %s upon "
2548 "delete of listen range %s",
2549 peer
->host
, group
->name
, buf
);
2554 /* Get rid of the listen range */
2555 listnode_delete(group
->listen_range
[afi
], prefix
);
2560 /* Bind specified peer to peer group. */
2561 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2562 struct peer_group
*group
, as_t
*as
)
2564 int first_member
= 0;
2567 int cap_enhe_preset
= 0;
2569 /* Lookup the peer. */
2571 peer
= peer_lookup(bgp
, su
);
2573 /* The peer exist, bind it to the peer-group */
2575 /* When the peer already belongs to a peer-group, check the
2577 if (peer_group_active(peer
)) {
2579 /* The peer is already bound to the peer-group,
2582 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2585 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2588 /* The peer has not specified a remote-as, inherit it from the
2590 if (peer
->as_type
== AS_UNSPECIFIED
) {
2591 peer
->as_type
= group
->conf
->as_type
;
2592 peer
->as
= group
->conf
->as
;
2595 if (!group
->conf
->as
) {
2596 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2597 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2600 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2603 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2607 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2608 cap_enhe_preset
= 1;
2610 peer_group2peer_config_copy(group
, peer
);
2613 * Capability extended-nexthop is enabled for an interface
2615 * default. So, fix that up here.
2617 if (peer
->conf_if
&& cap_enhe_preset
)
2618 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2620 FOREACH_AFI_SAFI (afi
, safi
) {
2621 if (group
->conf
->afc
[afi
][safi
]) {
2622 peer
->afc
[afi
][safi
] = 1;
2624 if (peer_af_find(peer
, afi
, safi
)
2625 || peer_af_create(peer
, afi
, safi
)) {
2626 peer_group2peer_config_copy_af(
2627 group
, peer
, afi
, safi
);
2629 } else if (peer
->afc
[afi
][safi
])
2630 peer_deactivate(peer
, afi
, safi
);
2634 assert(group
&& peer
->group
== group
);
2636 struct listnode
*pn
;
2637 pn
= listnode_lookup(bgp
->peer
, peer
);
2638 list_delete_node(bgp
->peer
, pn
);
2639 peer
->group
= group
;
2640 listnode_add_sort(bgp
->peer
, peer
);
2642 peer
= peer_lock(peer
); /* group->peer list reference */
2643 listnode_add(group
->peer
, peer
);
2647 /* Advertisement-interval reset */
2648 if (!CHECK_FLAG(group
->conf
->config
,
2649 PEER_CONFIG_ROUTEADV
)) {
2650 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2651 group
->conf
->v_routeadv
=
2652 BGP_DEFAULT_IBGP_ROUTEADV
;
2654 group
->conf
->v_routeadv
=
2655 BGP_DEFAULT_EBGP_ROUTEADV
;
2658 /* ebgp-multihop reset */
2659 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2660 group
->conf
->ttl
= MAXTTL
;
2662 /* local-as reset */
2663 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2664 group
->conf
->change_local_as
= 0;
2665 UNSET_FLAG(peer
->flags
,
2666 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2667 UNSET_FLAG(peer
->flags
,
2668 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2672 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2674 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2675 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2676 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2677 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2679 bgp_session_reset(peer
);
2683 /* Create a new peer. */
2685 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2686 && (!group
->conf
->as
)) {
2687 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2690 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2691 group
->conf
->as_type
, 0, 0, group
);
2693 peer
= peer_lock(peer
); /* group->peer list reference */
2694 listnode_add(group
->peer
, peer
);
2696 peer_group2peer_config_copy(group
, peer
);
2698 /* If the peer-group is active for this afi/safi then activate
2700 FOREACH_AFI_SAFI (afi
, safi
) {
2701 if (group
->conf
->afc
[afi
][safi
]) {
2702 peer
->afc
[afi
][safi
] = 1;
2703 peer_af_create(peer
, afi
, safi
);
2704 peer_group2peer_config_copy_af(group
, peer
, afi
,
2706 } else if (peer
->afc
[afi
][safi
])
2707 peer_deactivate(peer
, afi
, safi
);
2710 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2712 /* Set up peer's events and timers. */
2713 if (peer_active(peer
))
2714 bgp_timer_set(peer
);
2720 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2721 struct peer_group
*group
)
2727 if (group
!= peer
->group
)
2728 return BGP_ERR_PEER_GROUP_MISMATCH
;
2730 FOREACH_AFI_SAFI (afi
, safi
) {
2731 if (peer
->afc
[afi
][safi
]) {
2732 peer
->afc
[afi
][safi
] = 0;
2733 peer_af_flag_reset(peer
, afi
, safi
);
2735 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2737 "couldn't delete af structure for peer %s",
2743 assert(listnode_lookup(group
->peer
, peer
));
2744 peer_unlock(peer
); /* peer group list reference */
2745 listnode_delete(group
->peer
, peer
);
2747 other
= peer
->doppelganger
;
2749 if (group
->conf
->as
) {
2751 if (other
&& other
->status
!= Deleted
) {
2754 listnode_delete(group
->peer
, other
);
2756 other
->group
= NULL
;
2762 bgp_bfd_deregister_peer(peer
);
2763 peer_global_config_reset(peer
);
2765 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2766 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2767 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2768 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2770 bgp_session_reset(peer
);
2775 static int bgp_startup_timer_expire(struct thread
*thread
)
2779 bgp
= THREAD_ARG(thread
);
2780 bgp
->t_startup
= NULL
;
2785 /* BGP instance creation by `router bgp' commands. */
2786 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2787 enum bgp_instance_type inst_type
)
2793 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2796 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2797 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2798 zlog_debug("Creating Default VRF, AS %u", *as
);
2800 zlog_debug("Creating %s %s, AS %u",
2801 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2808 bgp
->inst_type
= inst_type
;
2809 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2811 bgp
->peer_self
= peer_new(bgp
);
2812 if (bgp
->peer_self
->host
)
2813 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2814 bgp
->peer_self
->host
=
2815 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2816 if (bgp
->peer_self
->hostname
!= NULL
) {
2817 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2818 bgp
->peer_self
->hostname
= NULL
;
2820 if (cmd_hostname_get())
2821 bgp
->peer_self
->hostname
=
2822 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2824 if (bgp
->peer_self
->domainname
!= NULL
) {
2825 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2826 bgp
->peer_self
->domainname
= NULL
;
2828 if (cmd_domainname_get())
2829 bgp
->peer_self
->domainname
=
2830 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2831 bgp
->peer
= list_new();
2832 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2833 bgp
->peerhash
= hash_create(peer_hash_key_make
,
2836 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2838 bgp
->group
= list_new();
2839 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2841 FOREACH_AFI_SAFI (afi
, safi
) {
2842 bgp
->route
[afi
][safi
] = bgp_table_init(afi
, safi
);
2843 bgp
->aggregate
[afi
][safi
] = bgp_table_init(afi
, safi
);
2844 bgp
->rib
[afi
][safi
] = bgp_table_init(afi
, safi
);
2846 /* Enable maximum-paths */
2847 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2849 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2853 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2854 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2855 bgp
->default_subgroup_pkt_queue_max
=
2856 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2857 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2858 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2859 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2860 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2861 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2862 bgp
->dynamic_neighbors_count
= 0;
2863 #if DFLT_BGP_IMPORT_CHECK
2864 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2866 #if DFLT_BGP_SHOW_HOSTNAME
2867 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2869 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2870 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2872 #if DFLT_BGP_DETERMINISTIC_MED
2873 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2875 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2880 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2881 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2883 assert(bgp
->rfapi_cfg
);
2885 #endif /* ENABLE_BGP_VNC */
2888 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2890 /* TODO - The startup timer needs to be run for the whole of BGP
2892 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2893 bgp
->restart_time
, &bgp
->t_startup
);
2896 bgp
->wpkt_quanta
= BGP_WRITE_PACKET_MAX
;
2897 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2901 update_bgp_group_init(bgp
);
2906 /* Return the "default VRF" instance of BGP. */
2907 struct bgp
*bgp_get_default(void)
2910 struct listnode
*node
, *nnode
;
2912 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2913 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2918 /* Lookup BGP entry. */
2919 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2922 struct listnode
*node
, *nnode
;
2924 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2926 && ((bgp
->name
== NULL
&& name
== NULL
)
2927 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2932 /* Lookup BGP structure by view name. */
2933 struct bgp
*bgp_lookup_by_name(const char *name
)
2936 struct listnode
*node
, *nnode
;
2938 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2939 if ((bgp
->name
== NULL
&& name
== NULL
)
2940 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2945 /* Lookup BGP instance based on VRF id. */
2946 /* Note: Only to be used for incoming messages from Zebra. */
2947 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2951 /* Lookup VRF (in tree) and follow link. */
2952 vrf
= vrf_lookup_by_id(vrf_id
);
2955 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2958 /* Called from VTY commands. */
2959 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
2960 enum bgp_instance_type inst_type
)
2964 /* Multiple instance check. */
2965 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
2967 bgp
= bgp_lookup_by_name(name
);
2969 bgp
= bgp_get_default();
2971 /* Already exists. */
2973 if (bgp
->as
!= *as
) {
2975 return BGP_ERR_INSTANCE_MISMATCH
;
2977 if (bgp
->inst_type
!= inst_type
)
2978 return BGP_ERR_INSTANCE_MISMATCH
;
2983 /* BGP instance name can not be specified for single instance.
2986 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
2988 /* Get default BGP structure if exists. */
2989 bgp
= bgp_get_default();
2992 if (bgp
->as
!= *as
) {
2994 return BGP_ERR_AS_MISMATCH
;
3001 bgp
= bgp_create(as
, name
, inst_type
);
3002 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3003 bgp_address_init(bgp
);
3004 bgp_tip_hash_init(bgp
);
3008 bgp
->t_rmap_def_originate_eval
= NULL
;
3010 /* Create BGP server socket, if first instance. */
3011 if (list_isempty(bm
->bgp
) && !bgp_option_check(BGP_OPT_NO_LISTEN
)) {
3012 if (bgp_socket(bm
->port
, bm
->address
) < 0)
3013 return BGP_ERR_INVALID_VALUE
;
3016 listnode_add(bm
->bgp
, bgp
);
3018 /* If Default instance or VRF, link to the VRF structure, if present. */
3019 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3020 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3023 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3025 bgp_vrf_link(bgp
, vrf
);
3028 /* Register with Zebra, if needed */
3029 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3030 bgp_zebra_instance_register(bgp
);
3037 * Make BGP instance "up". Applies only to VRFs (non-default) and
3038 * implies the VRF has been learnt from Zebra.
3040 void bgp_instance_up(struct bgp
*bgp
)
3043 struct listnode
*node
, *next
;
3045 /* Register with zebra. */
3046 bgp_zebra_instance_register(bgp
);
3048 /* Kick off any peers that may have been configured. */
3049 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3050 if (!BGP_PEER_START_SUPPRESSED(peer
))
3051 BGP_EVENT_ADD(peer
, BGP_Start
);
3054 /* Process any networks that have been configured. */
3055 bgp_static_add(bgp
);
3059 * Make BGP instance "down". Applies only to VRFs (non-default) and
3060 * implies the VRF has been deleted by Zebra.
3062 void bgp_instance_down(struct bgp
*bgp
)
3065 struct listnode
*node
;
3066 struct listnode
*next
;
3069 if (bgp
->t_rmap_def_originate_eval
) {
3070 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3071 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3075 /* Bring down peers, so corresponding routes are purged. */
3076 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3077 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3078 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3079 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3081 bgp_session_reset(peer
);
3084 /* Purge network and redistributed routes. */
3085 bgp_purge_static_redist_routes(bgp
);
3087 /* Cleanup registered nexthops (flags) */
3088 bgp_cleanup_nexthops(bgp
);
3091 /* Delete BGP instance. */
3092 int bgp_delete(struct bgp
*bgp
)
3095 struct peer_group
*group
;
3096 struct listnode
*node
, *next
;
3101 THREAD_OFF(bgp
->t_startup
);
3103 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3104 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3105 zlog_debug("Deleting Default VRF");
3107 zlog_debug("Deleting %s %s",
3108 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3115 if (bgp
->t_rmap_def_originate_eval
) {
3116 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3117 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3121 /* Inform peers we're going down. */
3122 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3123 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3124 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3125 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3128 /* Delete static routes (networks). */
3129 bgp_static_delete(bgp
);
3131 /* Unset redistribution. */
3132 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3133 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3134 if (i
!= ZEBRA_ROUTE_BGP
)
3135 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3137 /* Free peers and peer-groups. */
3138 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3139 peer_group_delete(group
);
3141 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3144 if (bgp
->peer_self
) {
3145 peer_delete(bgp
->peer_self
);
3146 bgp
->peer_self
= NULL
;
3149 update_bgp_group_free(bgp
);
3151 /* TODO - Other memory may need to be freed - e.g., NHT */
3156 bgp_cleanup_routes(bgp
);
3158 /* Remove visibility via the master list - there may however still be
3159 * routes to be processed still referencing the struct bgp.
3161 listnode_delete(bm
->bgp
, bgp
);
3162 if (list_isempty(bm
->bgp
))
3165 /* Deregister from Zebra, if needed */
3166 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3167 bgp_zebra_instance_deregister(bgp
);
3169 /* Free interfaces in this instance. */
3172 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3174 bgp_vrf_unlink(bgp
, vrf
);
3176 thread_master_free_unused(bm
->master
);
3177 bgp_unlock(bgp
); /* initial reference */
3182 void bgp_free(struct bgp
*bgp
)
3186 struct bgp_table
*table
;
3187 struct bgp_node
*rn
;
3188 struct bgp_rmap
*rmap
;
3192 list_delete_and_null(&bgp
->group
);
3193 list_delete_and_null(&bgp
->peer
);
3195 if (bgp
->peerhash
) {
3196 hash_free(bgp
->peerhash
);
3197 bgp
->peerhash
= NULL
;
3200 FOREACH_AFI_SAFI (afi
, safi
) {
3201 /* Special handling for 2-level routing tables. */
3202 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3203 || safi
== SAFI_EVPN
) {
3204 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3205 rn
= bgp_route_next(rn
)) {
3206 table
= (struct bgp_table
*)rn
->info
;
3207 bgp_table_finish(&table
);
3210 if (bgp
->route
[afi
][safi
])
3211 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3212 if (bgp
->aggregate
[afi
][safi
])
3213 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3214 if (bgp
->rib
[afi
][safi
])
3215 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3216 rmap
= &bgp
->table_map
[afi
][safi
];
3218 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3221 bgp_scan_finish(bgp
);
3222 bgp_address_destroy(bgp
);
3223 bgp_tip_hash_destroy(bgp
);
3225 bgp_evpn_cleanup(bgp
);
3228 XFREE(MTYPE_BGP
, bgp
->name
);
3230 XFREE(MTYPE_BGP
, bgp
);
3233 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3236 struct listnode
*node
, *nnode
;
3242 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3243 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3244 && !CHECK_FLAG(peer
->sflags
,
3245 PEER_STATUS_ACCEPT_PEER
))
3247 } else if (bm
->bgp
!= NULL
) {
3248 struct listnode
*bgpnode
, *nbgpnode
;
3250 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3251 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3253 && !strcmp(peer
->conf_if
, conf_if
)
3254 && !CHECK_FLAG(peer
->sflags
,
3255 PEER_STATUS_ACCEPT_PEER
))
3261 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3264 struct listnode
*node
, *nnode
;
3270 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3271 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
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
->hostname
, hostname
)
3282 && !CHECK_FLAG(peer
->sflags
,
3283 PEER_STATUS_ACCEPT_PEER
))
3289 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3291 struct peer
*peer
= NULL
;
3292 struct peer tmp_peer
;
3294 memset(&tmp_peer
, 0, sizeof(struct peer
));
3297 * We do not want to find the doppelganger peer so search for the peer
3299 * the hash that has PEER_FLAG_CONFIG_NODE
3301 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3306 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3307 } else if (bm
->bgp
!= NULL
) {
3308 struct listnode
*bgpnode
, *nbgpnode
;
3310 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3311 /* Skip VRFs, this function will not be invoked without
3313 * when examining VRFs.
3315 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3318 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3328 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3329 union sockunion
*su
,
3330 struct peer_group
*group
)
3336 /* Create peer first; we've already checked group config is valid. */
3337 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3338 group
->conf
->as_type
, 0, 0, group
);
3343 peer
= peer_lock(peer
);
3344 listnode_add(group
->peer
, peer
);
3346 peer_group2peer_config_copy(group
, peer
);
3349 * Bind peer for all AFs configured for the group. We don't call
3350 * peer_group_bind as that is sub-optimal and does some stuff we don't
3353 FOREACH_AFI_SAFI (afi
, safi
) {
3354 if (!group
->conf
->afc
[afi
][safi
])
3356 peer
->afc
[afi
][safi
] = 1;
3358 if (!peer_af_find(peer
, afi
, safi
))
3359 peer_af_create(peer
, afi
, safi
);
3361 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3364 /* Mark as dynamic, but also as a "config node" for other things to
3366 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3367 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3373 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3374 struct prefix
*prefix
)
3376 struct listnode
*node
, *nnode
;
3377 struct prefix
*range
;
3380 afi
= family2afi(prefix
->family
);
3382 if (group
->listen_range
[afi
])
3383 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3385 if (prefix_match(range
, prefix
))
3392 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3393 struct prefix
**listen_range
)
3395 struct prefix
*range
= NULL
;
3396 struct peer_group
*group
= NULL
;
3397 struct listnode
*node
, *nnode
;
3399 *listen_range
= NULL
;
3401 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3402 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3405 } else if (bm
->bgp
!= NULL
) {
3406 struct listnode
*bgpnode
, *nbgpnode
;
3408 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3409 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3410 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3416 *listen_range
= range
;
3417 return (group
&& range
) ? group
: NULL
;
3420 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3422 struct peer_group
*group
;
3425 struct prefix prefix
;
3426 struct prefix
*listen_range
;
3428 char buf
[PREFIX2STR_BUFFER
];
3429 char buf1
[PREFIX2STR_BUFFER
];
3431 sockunion2hostprefix(su
, &prefix
);
3433 /* See if incoming connection matches a configured listen range. */
3434 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3445 prefix2str(&prefix
, buf
, sizeof(buf
));
3446 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3448 if (bgp_debug_neighbor_events(NULL
))
3450 "Dynamic Neighbor %s matches group %s listen range %s",
3451 buf
, group
->name
, buf1
);
3453 /* Are we within the listen limit? */
3454 dncount
= gbgp
->dynamic_neighbors_count
;
3456 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3457 if (bgp_debug_neighbor_events(NULL
))
3458 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3459 inet_sutop(su
, buf
),
3460 gbgp
->dynamic_neighbors_limit
);
3464 /* Ensure group is not disabled. */
3465 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3466 if (bgp_debug_neighbor_events(NULL
))
3468 "Dynamic Neighbor %s rejected - group %s disabled",
3473 /* Check that at least one AF is activated for the group. */
3474 if (!peer_group_af_configured(group
)) {
3475 if (bgp_debug_neighbor_events(NULL
))
3477 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3482 /* Create dynamic peer and bind to associated group. */
3483 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3486 gbgp
->dynamic_neighbors_count
= ++dncount
;
3488 if (bgp_debug_neighbor_events(peer
))
3489 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3490 peer
->host
, group
->name
, dncount
);
3495 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3498 if (peer
->group
&& peer
->group
->bgp
) {
3499 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3501 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3503 if (bgp_debug_neighbor_events(peer
))
3504 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3505 peer
->group
->name
, dncount
);
3509 /* If peer is configured at least one address family return 1. */
3510 int peer_active(struct peer
*peer
)
3512 if (BGP_PEER_SU_UNSPEC(peer
))
3514 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3515 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3516 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3517 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3518 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3519 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3520 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3521 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3522 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3527 /* If peer is negotiated at least one address family return 1. */
3528 int peer_active_nego(struct peer
*peer
)
3530 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3531 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3532 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3533 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3534 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3535 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3536 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3537 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3538 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3539 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3540 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3545 /* peer_flag_change_type. */
3546 enum peer_change_type
{
3549 peer_change_reset_in
,
3550 peer_change_reset_out
,
3553 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3554 enum peer_change_type type
)
3556 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3559 if (peer
->status
!= Established
)
3562 if (type
== peer_change_reset
) {
3563 /* If we're resetting session, we've to delete both peer struct
3565 if ((peer
->doppelganger
)
3566 && (peer
->doppelganger
->status
!= Deleted
)
3567 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3568 PEER_FLAG_CONFIG_NODE
)))
3569 peer_delete(peer
->doppelganger
);
3571 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3572 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3573 } else if (type
== peer_change_reset_in
) {
3574 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3575 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3576 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3578 if ((peer
->doppelganger
)
3579 && (peer
->doppelganger
->status
!= Deleted
)
3580 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3581 PEER_FLAG_CONFIG_NODE
)))
3582 peer_delete(peer
->doppelganger
);
3584 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3585 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3587 } else if (type
== peer_change_reset_out
) {
3588 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3589 bgp_announce_route(peer
, afi
, safi
);
3593 struct peer_flag_action
{
3597 /* This flag can be set for peer-group member. */
3598 u_char not_for_member
;
3600 /* Action when the flag is changed. */
3601 enum peer_change_type type
;
3603 /* Peer down cause */
3607 static const struct peer_flag_action peer_flag_action_list
[] = {
3608 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3609 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3610 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3611 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3612 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3613 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3614 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3615 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3618 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3619 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3620 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3621 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3622 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3623 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3624 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3625 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3626 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3627 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3628 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3629 // PEER_FLAG_DEFAULT_ORIGINATE
3630 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3631 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3632 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3633 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3634 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3635 // PEER_FLAG_MAX_PREFIX
3636 // PEER_FLAG_MAX_PREFIX_WARNING
3637 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3638 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3639 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3640 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3641 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3642 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3643 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3644 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3645 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3648 /* Proper action set. */
3649 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3650 int size
, struct peer_flag_action
*action
,
3657 const struct peer_flag_action
*match
= NULL
;
3659 /* Check peer's frag action. */
3660 for (i
= 0; i
< size
; i
++) {
3661 match
= &action_list
[i
];
3663 if (match
->flag
== 0)
3666 if (match
->flag
& flag
) {
3669 if (match
->type
== peer_change_reset_in
)
3671 if (match
->type
== peer_change_reset_out
)
3673 if (match
->type
== peer_change_reset
) {
3677 if (match
->not_for_member
)
3678 action
->not_for_member
= 1;
3682 /* Set peer clear type. */
3683 if (reset_in
&& reset_out
)
3684 action
->type
= peer_change_reset
;
3686 action
->type
= peer_change_reset_in
;
3688 action
->type
= peer_change_reset_out
;
3690 action
->type
= peer_change_none
;
3695 static void peer_flag_modify_action(struct peer
*peer
, u_int32_t flag
)
3697 if (flag
== PEER_FLAG_SHUTDOWN
) {
3698 if (CHECK_FLAG(peer
->flags
, flag
)) {
3699 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3700 peer_nsf_stop(peer
);
3702 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3703 if (peer
->t_pmax_restart
) {
3704 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3705 if (bgp_debug_neighbor_events(peer
))
3707 "%s Maximum-prefix restart timer canceled",
3711 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3712 peer_nsf_stop(peer
);
3714 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3715 char *msg
= peer
->tx_shutdown_message
;
3718 if (!msg
&& peer_group_active(peer
))
3719 msg
= peer
->group
->conf
3720 ->tx_shutdown_message
;
3721 msglen
= msg
? strlen(msg
) : 0;
3729 memcpy(msgbuf
+ 1, msg
, msglen
);
3731 bgp_notify_send_with_data(
3732 peer
, BGP_NOTIFY_CEASE
,
3733 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3734 msgbuf
, msglen
+ 1);
3737 peer
, BGP_NOTIFY_CEASE
,
3738 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3740 bgp_session_reset(peer
);
3742 peer
->v_start
= BGP_INIT_START_TIMER
;
3743 BGP_EVENT_ADD(peer
, BGP_Stop
);
3745 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3746 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3747 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3748 else if (flag
== PEER_FLAG_PASSIVE
)
3749 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3750 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3751 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3753 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3754 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3756 bgp_session_reset(peer
);
3759 /* Change specified peer flag. */
3760 static int peer_flag_modify(struct peer
*peer
, u_int32_t flag
, int set
)
3764 struct peer_group
*group
;
3765 struct peer
*tmp_peer
;
3766 struct listnode
*node
, *nnode
;
3767 struct peer_flag_action action
;
3769 memset(&action
, 0, sizeof(struct peer_flag_action
));
3770 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3772 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3775 /* No flag action is found. */
3777 return BGP_ERR_INVALID_FLAG
;
3779 /* When unset the peer-group member's flag we have to check
3780 peer-group configuration. */
3781 if (!set
&& peer_group_active(peer
))
3782 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3783 if (flag
== PEER_FLAG_SHUTDOWN
)
3784 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3787 /* Flag conflict check. */
3788 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3789 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3790 return BGP_ERR_PEER_FLAG_CONFLICT
;
3792 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3793 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3795 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3800 SET_FLAG(peer
->flags
, flag
);
3802 UNSET_FLAG(peer
->flags
, flag
);
3804 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3805 if (action
.type
== peer_change_reset
)
3806 peer_flag_modify_action(peer
, flag
);
3811 /* peer-group member updates. */
3812 group
= peer
->group
;
3814 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3816 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
3819 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
3823 SET_FLAG(tmp_peer
->flags
, flag
);
3825 UNSET_FLAG(tmp_peer
->flags
, flag
);
3827 if (action
.type
== peer_change_reset
)
3828 peer_flag_modify_action(tmp_peer
, flag
);
3833 int peer_flag_set(struct peer
*peer
, u_int32_t flag
)
3835 return peer_flag_modify(peer
, flag
, 1);
3838 int peer_flag_unset(struct peer
*peer
, u_int32_t flag
)
3840 return peer_flag_modify(peer
, flag
, 0);
3843 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3844 u_int32_t flag
, int set
)
3848 struct listnode
*node
, *nnode
;
3849 struct peer_group
*group
;
3850 struct peer_flag_action action
;
3851 struct peer
*tmp_peer
;
3853 int addpath_tx_used
;
3855 memset(&action
, 0, sizeof(struct peer_flag_action
));
3856 size
= sizeof peer_af_flag_action_list
3857 / sizeof(struct peer_flag_action
);
3859 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3862 /* No flag action is found. */
3864 return BGP_ERR_INVALID_FLAG
;
3866 /* Special check for reflector client. */
3867 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3868 && peer_sort(peer
) != BGP_PEER_IBGP
)
3869 return BGP_ERR_NOT_INTERNAL_PEER
;
3871 /* Special check for remove-private-AS. */
3872 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3873 && peer_sort(peer
) == BGP_PEER_IBGP
)
3874 return BGP_ERR_REMOVE_PRIVATE_AS
;
3876 /* as-override is not allowed for IBGP peers */
3877 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3878 return BGP_ERR_AS_OVERRIDE
;
3880 /* When current flag configuration is same as requested one. */
3881 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3882 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
3884 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
3889 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3891 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3893 /* Execute action when peer is established. */
3894 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
3895 && peer
->status
== Established
) {
3896 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3897 bgp_clear_adj_in(peer
, afi
, safi
);
3899 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3900 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
3901 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
3902 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
3903 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
3904 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3905 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
3906 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3908 peer_change_action(peer
, afi
, safi
, action
.type
);
3912 /* Peer group member updates. */
3913 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3914 group
= peer
->group
;
3916 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3918 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
3923 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
3927 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3929 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3931 if (tmp_peer
->status
== Established
) {
3932 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3933 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
3935 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3936 tmp_peer
->last_reset
=
3937 PEER_DOWN_RR_CLIENT_CHANGE
;
3939 == PEER_FLAG_RSERVER_CLIENT
)
3940 tmp_peer
->last_reset
=
3941 PEER_DOWN_RS_CLIENT_CHANGE
;
3943 == PEER_FLAG_ORF_PREFIX_SM
)
3944 tmp_peer
->last_reset
=
3945 PEER_DOWN_CAPABILITY_CHANGE
;
3947 == PEER_FLAG_ORF_PREFIX_RM
)
3948 tmp_peer
->last_reset
=
3949 PEER_DOWN_CAPABILITY_CHANGE
;
3951 peer_change_action(tmp_peer
, afi
, safi
,
3958 /* Track if addpath TX is in use */
3959 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
3960 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
3962 addpath_tx_used
= 0;
3965 addpath_tx_used
= 1;
3967 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
3968 if (!bgp_flag_check(
3969 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
3971 "%s: enabling bgp deterministic-med, this is required"
3972 " for addpath-tx-bestpath-per-AS",
3976 BGP_FLAG_DETERMINISTIC_MED
);
3977 bgp_recalculate_all_bestpaths(bgp
);
3981 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
3983 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
3984 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
3986 tmp_peer
->af_flags
[afi
][safi
],
3987 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
3988 addpath_tx_used
= 1;
3994 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4000 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int32_t flag
)
4002 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4005 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
4008 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4012 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4014 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4015 peer
->tx_shutdown_message
=
4016 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4020 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4022 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4027 /* EBGP multihop configuration. */
4028 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4030 struct peer_group
*group
;
4031 struct listnode
*node
, *nnode
;
4034 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4037 /* see comment in peer_ttl_security_hops_set() */
4038 if (ttl
!= MAXTTL
) {
4039 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4040 group
= peer
->group
;
4041 if (group
->conf
->gtsm_hops
!= 0)
4042 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4044 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4046 if (peer1
->sort
== BGP_PEER_IBGP
)
4049 if (peer1
->gtsm_hops
!= 0)
4050 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4053 if (peer
->gtsm_hops
!= 0)
4054 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4060 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4061 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4062 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4063 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4064 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4066 bgp_session_reset(peer
);
4069 group
= peer
->group
;
4070 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4071 if (peer
->sort
== BGP_PEER_IBGP
)
4074 peer
->ttl
= group
->conf
->ttl
;
4076 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4077 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4078 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4080 bgp_session_reset(peer
);
4086 int peer_ebgp_multihop_unset(struct peer
*peer
)
4088 struct peer_group
*group
;
4089 struct listnode
*node
, *nnode
;
4091 if (peer
->sort
== BGP_PEER_IBGP
)
4094 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4095 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4097 if (peer_group_active(peer
))
4098 peer
->ttl
= peer
->group
->conf
->ttl
;
4102 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4103 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4104 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4105 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4107 bgp_session_reset(peer
);
4109 group
= peer
->group
;
4110 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4111 if (peer
->sort
== BGP_PEER_IBGP
)
4116 if (peer
->fd
>= 0) {
4117 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4119 peer
, BGP_NOTIFY_CEASE
,
4120 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4122 bgp_session_reset(peer
);
4129 /* Neighbor description. */
4130 int peer_description_set(struct peer
*peer
, const char *desc
)
4133 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4135 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4140 int peer_description_unset(struct peer
*peer
)
4143 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4150 /* Neighbor update-source. */
4151 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4153 struct peer_group
*group
;
4154 struct listnode
*node
, *nnode
;
4156 if (peer
->update_if
) {
4157 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4158 && strcmp(peer
->update_if
, ifname
) == 0)
4161 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4162 peer
->update_if
= NULL
;
4165 if (peer
->update_source
) {
4166 sockunion_free(peer
->update_source
);
4167 peer
->update_source
= NULL
;
4170 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4172 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4173 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4174 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4175 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4176 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4178 bgp_session_reset(peer
);
4182 /* peer-group member updates. */
4183 group
= peer
->group
;
4184 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4185 if (peer
->update_if
) {
4186 if (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 (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4201 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4202 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4203 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4205 bgp_session_reset(peer
);
4210 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4212 struct peer_group
*group
;
4213 struct listnode
*node
, *nnode
;
4215 if (peer
->update_source
) {
4216 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4217 && sockunion_cmp(peer
->update_source
, su
) == 0)
4219 sockunion_free(peer
->update_source
);
4220 peer
->update_source
= NULL
;
4223 if (peer
->update_if
) {
4224 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4225 peer
->update_if
= NULL
;
4228 peer
->update_source
= sockunion_dup(su
);
4230 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4231 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4232 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4233 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4234 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4236 bgp_session_reset(peer
);
4240 /* peer-group member updates. */
4241 group
= peer
->group
;
4242 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4243 if (peer
->update_source
) {
4244 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4246 sockunion_free(peer
->update_source
);
4247 peer
->update_source
= NULL
;
4250 if (peer
->update_if
) {
4251 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4252 peer
->update_if
= NULL
;
4255 peer
->update_source
= sockunion_dup(su
);
4257 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4258 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4259 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4260 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4262 bgp_session_reset(peer
);
4267 int peer_update_source_unset(struct peer
*peer
)
4269 union sockunion
*su
;
4270 struct peer_group
*group
;
4271 struct listnode
*node
, *nnode
;
4273 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4274 && !peer
->update_if
)
4277 if (peer
->update_source
) {
4278 sockunion_free(peer
->update_source
);
4279 peer
->update_source
= NULL
;
4281 if (peer
->update_if
) {
4282 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4283 peer
->update_if
= NULL
;
4286 if (peer_group_active(peer
)) {
4287 group
= peer
->group
;
4289 if (group
->conf
->update_source
) {
4290 su
= sockunion_dup(group
->conf
->update_source
);
4291 peer
->update_source
= su
;
4292 } else if (group
->conf
->update_if
)
4293 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4294 group
->conf
->update_if
);
4297 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4298 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4299 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4300 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4301 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4303 bgp_session_reset(peer
);
4307 /* peer-group member updates. */
4308 group
= peer
->group
;
4309 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4310 if (!peer
->update_source
&& !peer
->update_if
)
4313 if (peer
->update_source
) {
4314 sockunion_free(peer
->update_source
);
4315 peer
->update_source
= NULL
;
4318 if (peer
->update_if
) {
4319 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4320 peer
->update_if
= NULL
;
4323 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4324 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4325 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4326 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4328 bgp_session_reset(peer
);
4333 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4336 struct peer_group
*group
;
4337 struct listnode
*node
, *nnode
;
4339 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4340 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4342 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4343 SET_FLAG(peer
->af_flags
[afi
][safi
],
4344 PEER_FLAG_DEFAULT_ORIGINATE
);
4347 if (peer
->default_rmap
[afi
][safi
].name
)
4348 XFREE(MTYPE_ROUTE_MAP_NAME
,
4349 peer
->default_rmap
[afi
][safi
].name
);
4350 peer
->default_rmap
[afi
][safi
].name
=
4351 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4352 peer
->default_rmap
[afi
][safi
].map
=
4353 route_map_lookup_by_name(rmap
);
4357 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4358 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4359 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4360 bgp_default_originate(peer
, afi
, safi
, 0);
4361 bgp_announce_route(peer
, afi
, safi
);
4366 /* peer-group member updates. */
4367 group
= peer
->group
;
4368 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4369 SET_FLAG(peer
->af_flags
[afi
][safi
],
4370 PEER_FLAG_DEFAULT_ORIGINATE
);
4373 if (peer
->default_rmap
[afi
][safi
].name
)
4374 XFREE(MTYPE_ROUTE_MAP_NAME
,
4375 peer
->default_rmap
[afi
][safi
].name
);
4376 peer
->default_rmap
[afi
][safi
].name
=
4377 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4378 peer
->default_rmap
[afi
][safi
].map
=
4379 route_map_lookup_by_name(rmap
);
4382 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4383 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4384 bgp_default_originate(peer
, afi
, safi
, 0);
4385 bgp_announce_route(peer
, afi
, safi
);
4391 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4393 struct peer_group
*group
;
4394 struct listnode
*node
, *nnode
;
4396 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4397 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4398 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4399 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
= NULL
;
4405 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4408 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4409 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4410 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4411 bgp_default_originate(peer
, afi
, safi
, 1);
4412 bgp_announce_route(peer
, afi
, safi
);
4417 /* peer-group member updates. */
4418 group
= peer
->group
;
4419 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4420 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4421 PEER_FLAG_DEFAULT_ORIGINATE
);
4423 if (peer
->default_rmap
[afi
][safi
].name
)
4424 XFREE(MTYPE_ROUTE_MAP_NAME
,
4425 peer
->default_rmap
[afi
][safi
].name
);
4426 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4427 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4429 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4430 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4431 bgp_default_originate(peer
, afi
, safi
, 1);
4432 bgp_announce_route(peer
, afi
, safi
);
4438 int peer_port_set(struct peer
*peer
, u_int16_t port
)
4444 int peer_port_unset(struct peer
*peer
)
4446 peer
->port
= BGP_PORT_DEFAULT
;
4451 * Helper function that is called after the name of the policy
4452 * being used by a peer has changed (AF specific). Automatically
4453 * initiates inbound or outbound processing as needed.
4455 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4459 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4460 if (peer
->status
== Established
)
4461 bgp_announce_route(peer
, afi
, safi
);
4463 if (peer
->status
!= Established
)
4466 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4467 PEER_FLAG_SOFT_RECONFIG
))
4468 bgp_soft_reconfig_in(peer
, afi
, safi
);
4469 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4470 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4471 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4476 /* neighbor weight. */
4477 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int16_t weight
)
4479 struct peer_group
*group
;
4480 struct listnode
*node
, *nnode
;
4482 if (peer
->weight
[afi
][safi
] != weight
) {
4483 peer
->weight
[afi
][safi
] = weight
;
4484 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4485 peer_on_policy_change(peer
, afi
, safi
, 0);
4488 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4491 /* peer-group member updates. */
4492 group
= peer
->group
;
4493 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4494 if (peer
->weight
[afi
][safi
] != weight
) {
4495 peer
->weight
[afi
][safi
] = weight
;
4496 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4497 peer_on_policy_change(peer
, afi
, safi
, 0);
4503 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4505 struct peer_group
*group
;
4506 struct listnode
*node
, *nnode
;
4508 /* not the peer-group itself but a peer in a peer-group */
4509 if (peer_group_active(peer
)) {
4510 group
= peer
->group
;
4512 /* inherit weight from the peer-group */
4513 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4514 PEER_FLAG_WEIGHT
)) {
4515 peer
->weight
[afi
][safi
] =
4516 group
->conf
->weight
[afi
][safi
];
4517 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4518 peer_on_policy_change(peer
, afi
, safi
, 0);
4520 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4521 PEER_FLAG_WEIGHT
)) {
4522 peer
->weight
[afi
][safi
] = 0;
4523 peer_af_flag_unset(peer
, afi
, safi
,
4525 peer_on_policy_change(peer
, afi
, safi
, 0);
4531 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4532 peer
->weight
[afi
][safi
] = 0;
4533 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4534 peer_on_policy_change(peer
, afi
, safi
, 0);
4537 /* peer-group member updates. */
4538 group
= peer
->group
;
4541 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4543 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4544 PEER_FLAG_WEIGHT
)) {
4545 peer
->weight
[afi
][safi
] = 0;
4546 peer_af_flag_unset(peer
, afi
, safi
,
4548 peer_on_policy_change(peer
, afi
, safi
,
4557 int peer_timers_set(struct peer
*peer
, u_int32_t keepalive
, u_int32_t holdtime
)
4559 struct peer_group
*group
;
4560 struct listnode
*node
, *nnode
;
4562 /* keepalive value check. */
4563 if (keepalive
> 65535)
4564 return BGP_ERR_INVALID_VALUE
;
4566 /* Holdtime value check. */
4567 if (holdtime
> 65535)
4568 return BGP_ERR_INVALID_VALUE
;
4570 /* Holdtime value must be either 0 or greater than 3. */
4571 if (holdtime
< 3 && holdtime
!= 0)
4572 return BGP_ERR_INVALID_VALUE
;
4574 /* Set value to the configuration. */
4575 peer
->holdtime
= holdtime
;
4576 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4578 /* First work on real peers with timers */
4579 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4580 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4581 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4583 /* Now work on the peer-group timers */
4584 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4586 /* peer-group member updates. */
4587 group
= peer
->group
;
4588 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4589 /* Skip peers that have their own timers */
4590 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4593 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4594 peer
->holdtime
= group
->conf
->holdtime
;
4595 peer
->keepalive
= group
->conf
->keepalive
;
4602 int peer_timers_unset(struct peer
*peer
)
4604 struct peer_group
*group
;
4605 struct listnode
*node
, *nnode
;
4607 /* First work on real peers vs the peer-group */
4608 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4609 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4610 peer
->keepalive
= 0;
4613 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4614 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4615 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4616 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4619 /* peer-group member updates. */
4620 group
= peer
->group
;
4621 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4622 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4623 UNSET_FLAG(peer
->config
,
4624 PEER_GROUP_CONFIG_TIMER
);
4626 peer
->keepalive
= 0;
4630 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4631 group
->conf
->holdtime
= 0;
4632 group
->conf
->keepalive
= 0;
4638 int peer_timers_connect_set(struct peer
*peer
, u_int32_t connect
)
4640 struct peer_group
*group
;
4641 struct listnode
*node
, *nnode
;
4643 if (connect
> 65535)
4644 return BGP_ERR_INVALID_VALUE
;
4646 /* Set value to the configuration. */
4647 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4648 peer
->connect
= connect
;
4650 /* Set value to timer setting. */
4651 peer
->v_connect
= connect
;
4653 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4656 /* peer-group member updates. */
4657 group
= peer
->group
;
4658 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4659 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4660 peer
->connect
= connect
;
4661 peer
->v_connect
= connect
;
4666 int peer_timers_connect_unset(struct peer
*peer
)
4668 struct peer_group
*group
;
4669 struct listnode
*node
, *nnode
;
4671 /* Clear configuration. */
4672 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4675 /* Set timer setting to default value. */
4676 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4678 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4681 /* peer-group member updates. */
4682 group
= peer
->group
;
4683 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4684 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4686 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4691 int peer_advertise_interval_set(struct peer
*peer
, u_int32_t routeadv
)
4693 struct peer_group
*group
;
4694 struct listnode
*node
, *nnode
;
4697 return BGP_ERR_INVALID_VALUE
;
4699 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4700 peer
->routeadv
= routeadv
;
4701 peer
->v_routeadv
= routeadv
;
4703 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4704 update_group_adjust_peer_afs(peer
);
4705 if (peer
->status
== Established
)
4706 bgp_announce_route_all(peer
);
4710 /* peer-group member updates. */
4711 group
= peer
->group
;
4712 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4713 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4714 peer
->routeadv
= routeadv
;
4715 peer
->v_routeadv
= routeadv
;
4716 update_group_adjust_peer_afs(peer
);
4717 if (peer
->status
== Established
)
4718 bgp_announce_route_all(peer
);
4724 int peer_advertise_interval_unset(struct peer
*peer
)
4726 struct peer_group
*group
;
4727 struct listnode
*node
, *nnode
;
4729 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4732 if (peer
->sort
== BGP_PEER_IBGP
)
4733 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4735 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4737 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4738 update_group_adjust_peer_afs(peer
);
4739 if (peer
->status
== Established
)
4740 bgp_announce_route_all(peer
);
4744 /* peer-group member updates. */
4745 group
= peer
->group
;
4746 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4747 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4750 if (peer
->sort
== BGP_PEER_IBGP
)
4751 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4753 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4755 update_group_adjust_peer_afs(peer
);
4756 if (peer
->status
== Established
)
4757 bgp_announce_route_all(peer
);
4763 /* neighbor interface */
4764 void peer_interface_set(struct peer
*peer
, const char *str
)
4767 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4768 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4771 void peer_interface_unset(struct peer
*peer
)
4774 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4775 peer
->ifname
= NULL
;
4779 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4780 int allow_num
, int origin
)
4782 struct peer_group
*group
;
4783 struct listnode
*node
, *nnode
;
4786 if (peer
->allowas_in
[afi
][safi
]
4787 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4788 PEER_FLAG_ALLOWAS_IN
)
4789 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4790 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4791 peer
->allowas_in
[afi
][safi
] = 0;
4792 peer_af_flag_unset(peer
, afi
, safi
,
4793 PEER_FLAG_ALLOWAS_IN
);
4794 peer_af_flag_set(peer
, afi
, safi
,
4795 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4796 peer_on_policy_change(peer
, afi
, safi
, 0);
4799 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4802 group
= peer
->group
;
4803 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4804 if (peer
->allowas_in
[afi
][safi
]
4805 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4806 PEER_FLAG_ALLOWAS_IN
)
4807 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4808 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4809 peer
->allowas_in
[afi
][safi
] = 0;
4810 peer_af_flag_unset(peer
, afi
, safi
,
4811 PEER_FLAG_ALLOWAS_IN
);
4812 peer_af_flag_set(peer
, afi
, safi
,
4813 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4814 peer_on_policy_change(peer
, afi
, safi
, 0);
4818 if (allow_num
< 1 || allow_num
> 10)
4819 return BGP_ERR_INVALID_VALUE
;
4821 if (peer
->allowas_in
[afi
][safi
] != allow_num
4822 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4823 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4824 peer
->allowas_in
[afi
][safi
] = allow_num
;
4825 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4826 peer_af_flag_unset(peer
, afi
, safi
,
4827 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4828 peer_on_policy_change(peer
, afi
, safi
, 0);
4831 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4834 group
= peer
->group
;
4835 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4836 if (peer
->allowas_in
[afi
][safi
] != allow_num
4837 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4838 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4839 peer
->allowas_in
[afi
][safi
] = allow_num
;
4840 peer_af_flag_set(peer
, afi
, safi
,
4841 PEER_FLAG_ALLOWAS_IN
);
4842 peer_af_flag_unset(peer
, afi
, safi
,
4843 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4844 peer_on_policy_change(peer
, afi
, safi
, 0);
4852 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4854 struct peer_group
*group
;
4855 struct peer
*tmp_peer
;
4856 struct listnode
*node
, *nnode
;
4858 /* If this is a peer-group we must first clear the flags for all of the
4859 * peer-group members
4861 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4862 group
= peer
->group
;
4863 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4864 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4865 PEER_FLAG_ALLOWAS_IN
)
4866 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4867 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4868 tmp_peer
->allowas_in
[afi
][safi
] = 0;
4869 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4870 PEER_FLAG_ALLOWAS_IN
);
4871 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4872 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4873 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
4878 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
4879 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4880 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4881 peer
->allowas_in
[afi
][safi
] = 0;
4882 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4883 peer_af_flag_unset(peer
, afi
, safi
,
4884 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4885 peer_on_policy_change(peer
, afi
, safi
, 0);
4891 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
4894 struct bgp
*bgp
= peer
->bgp
;
4895 struct peer_group
*group
;
4896 struct listnode
*node
, *nnode
;
4898 if (peer_sort(peer
) != BGP_PEER_EBGP
4899 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
4900 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
4903 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
4906 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
4908 if (peer
->change_local_as
== as
4909 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4911 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4913 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4915 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4919 peer
->change_local_as
= as
;
4921 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4923 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4926 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4928 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4930 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4931 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4932 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4933 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4934 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4936 bgp_session_reset(peer
);
4940 group
= peer
->group
;
4941 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4942 peer
->change_local_as
= as
;
4944 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4946 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4949 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4951 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4953 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4954 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4955 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4956 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4958 BGP_EVENT_ADD(peer
, BGP_Stop
);
4964 int peer_local_as_unset(struct peer
*peer
)
4966 struct peer_group
*group
;
4967 struct listnode
*node
, *nnode
;
4969 if (!peer
->change_local_as
)
4972 peer
->change_local_as
= 0;
4973 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4974 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4976 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4977 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4978 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4979 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4980 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4982 BGP_EVENT_ADD(peer
, BGP_Stop
);
4987 group
= peer
->group
;
4988 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4989 peer
->change_local_as
= 0;
4990 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4991 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4993 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4994 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4995 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4996 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4998 bgp_session_reset(peer
);
5003 /* Set password for authenticating with the peer. */
5004 int peer_password_set(struct peer
*peer
, const char *password
)
5006 struct listnode
*nn
, *nnode
;
5007 int len
= password
? strlen(password
) : 0;
5008 int ret
= BGP_SUCCESS
;
5010 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5011 return BGP_ERR_INVALID_VALUE
;
5013 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5014 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5018 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5020 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5022 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5023 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5024 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5025 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5027 bgp_session_reset(peer
);
5029 if (BGP_PEER_SU_UNSPEC(peer
))
5032 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5033 : BGP_ERR_TCPSIG_FAILED
;
5036 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5037 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5041 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5043 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5045 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5046 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5047 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5049 bgp_session_reset(peer
);
5051 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5052 if (bgp_md5_set(peer
) < 0)
5053 ret
= BGP_ERR_TCPSIG_FAILED
;
5060 int peer_password_unset(struct peer
*peer
)
5062 struct listnode
*nn
, *nnode
;
5064 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5067 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5068 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5069 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5070 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5072 bgp_session_reset(peer
);
5075 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5077 peer
->password
= NULL
;
5079 if (!BGP_PEER_SU_UNSPEC(peer
))
5080 bgp_md5_unset(peer
);
5085 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5086 peer
->password
= NULL
;
5088 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5089 if (!peer
->password
)
5092 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5093 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5094 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5096 bgp_session_reset(peer
);
5098 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5099 peer
->password
= NULL
;
5101 if (!BGP_PEER_SU_UNSPEC(peer
))
5102 bgp_md5_unset(peer
);
5109 /* Set distribute list to the peer. */
5110 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5113 struct bgp_filter
*filter
;
5114 struct peer_group
*group
;
5115 struct listnode
*node
, *nnode
;
5117 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5118 return BGP_ERR_INVALID_VALUE
;
5120 filter
= &peer
->filter
[afi
][safi
];
5122 if (filter
->plist
[direct
].name
)
5123 return BGP_ERR_PEER_FILTER_CONFLICT
;
5125 if (filter
->dlist
[direct
].name
)
5126 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5127 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5128 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5130 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5131 peer_on_policy_change(peer
, afi
, safi
,
5132 (direct
== FILTER_OUT
) ? 1 : 0);
5136 group
= peer
->group
;
5137 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5138 filter
= &peer
->filter
[afi
][safi
];
5140 if (filter
->dlist
[direct
].name
)
5141 XFREE(MTYPE_BGP_FILTER_NAME
,
5142 filter
->dlist
[direct
].name
);
5143 filter
->dlist
[direct
].name
=
5144 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5145 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5146 peer_on_policy_change(peer
, afi
, safi
,
5147 (direct
== FILTER_OUT
) ? 1 : 0);
5153 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5155 struct bgp_filter
*filter
;
5156 struct bgp_filter
*gfilter
;
5157 struct peer_group
*group
;
5158 struct listnode
*node
, *nnode
;
5160 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5161 return BGP_ERR_INVALID_VALUE
;
5163 filter
= &peer
->filter
[afi
][safi
];
5165 /* apply peer-group filter */
5166 if (peer_group_active(peer
)) {
5167 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5169 if (gfilter
->dlist
[direct
].name
) {
5170 if (filter
->dlist
[direct
].name
)
5171 XFREE(MTYPE_BGP_FILTER_NAME
,
5172 filter
->dlist
[direct
].name
);
5173 filter
->dlist
[direct
].name
=
5174 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5175 gfilter
->dlist
[direct
].name
);
5176 filter
->dlist
[direct
].alist
=
5177 gfilter
->dlist
[direct
].alist
;
5178 peer_on_policy_change(peer
, afi
, safi
,
5179 (direct
== FILTER_OUT
) ? 1 : 0);
5184 if (filter
->dlist
[direct
].name
)
5185 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5186 filter
->dlist
[direct
].name
= NULL
;
5187 filter
->dlist
[direct
].alist
= NULL
;
5189 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5190 peer_on_policy_change(peer
, afi
, safi
,
5191 (direct
== FILTER_OUT
) ? 1 : 0);
5195 group
= peer
->group
;
5196 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5197 filter
= &peer
->filter
[afi
][safi
];
5199 if (filter
->dlist
[direct
].name
)
5200 XFREE(MTYPE_BGP_FILTER_NAME
,
5201 filter
->dlist
[direct
].name
);
5202 filter
->dlist
[direct
].name
= NULL
;
5203 filter
->dlist
[direct
].alist
= NULL
;
5204 peer_on_policy_change(peer
, afi
, safi
,
5205 (direct
== FILTER_OUT
) ? 1 : 0);
5211 /* Update distribute list. */
5212 static void peer_distribute_update(struct access_list
*access
)
5217 struct listnode
*mnode
, *mnnode
;
5218 struct listnode
*node
, *nnode
;
5221 struct peer_group
*group
;
5222 struct bgp_filter
*filter
;
5224 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5226 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5227 access
->name
, 0, 0);
5228 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5229 FOREACH_AFI_SAFI (afi
, safi
) {
5230 filter
= &peer
->filter
[afi
][safi
];
5232 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5234 if (filter
->dlist
[direct
].name
)
5235 filter
->dlist
[direct
]
5236 .alist
= access_list_lookup(
5238 filter
->dlist
[direct
]
5241 filter
->dlist
[direct
].alist
=
5246 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5247 FOREACH_AFI_SAFI (afi
, safi
) {
5248 filter
= &group
->conf
->filter
[afi
][safi
];
5250 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5252 if (filter
->dlist
[direct
].name
)
5253 filter
->dlist
[direct
]
5254 .alist
= access_list_lookup(
5256 filter
->dlist
[direct
]
5259 filter
->dlist
[direct
].alist
=
5265 vnc_prefix_list_update(bgp
);
5270 /* Set prefix list to the peer. */
5271 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5274 struct bgp_filter
*filter
;
5275 struct peer_group
*group
;
5276 struct listnode
*node
, *nnode
;
5278 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5279 return BGP_ERR_INVALID_VALUE
;
5281 filter
= &peer
->filter
[afi
][safi
];
5283 if (filter
->dlist
[direct
].name
)
5284 return BGP_ERR_PEER_FILTER_CONFLICT
;
5286 if (filter
->plist
[direct
].name
)
5287 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5288 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5289 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5291 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5292 peer_on_policy_change(peer
, afi
, safi
,
5293 (direct
== FILTER_OUT
) ? 1 : 0);
5297 group
= peer
->group
;
5298 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5299 filter
= &peer
->filter
[afi
][safi
];
5301 if (filter
->plist
[direct
].name
)
5302 XFREE(MTYPE_BGP_FILTER_NAME
,
5303 filter
->plist
[direct
].name
);
5304 filter
->plist
[direct
].name
=
5305 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5306 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5307 peer_on_policy_change(peer
, afi
, safi
,
5308 (direct
== FILTER_OUT
) ? 1 : 0);
5313 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5316 struct bgp_filter
*filter
;
5317 struct bgp_filter
*gfilter
;
5318 struct peer_group
*group
;
5319 struct listnode
*node
, *nnode
;
5321 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5322 return BGP_ERR_INVALID_VALUE
;
5324 filter
= &peer
->filter
[afi
][safi
];
5326 /* apply peer-group filter */
5327 if (peer_group_active(peer
)) {
5328 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5330 if (gfilter
->plist
[direct
].name
) {
5331 if (filter
->plist
[direct
].name
)
5332 XFREE(MTYPE_BGP_FILTER_NAME
,
5333 filter
->plist
[direct
].name
);
5334 filter
->plist
[direct
].name
=
5335 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5336 gfilter
->plist
[direct
].name
);
5337 filter
->plist
[direct
].plist
=
5338 gfilter
->plist
[direct
].plist
;
5339 peer_on_policy_change(peer
, afi
, safi
,
5340 (direct
== FILTER_OUT
) ? 1 : 0);
5345 if (filter
->plist
[direct
].name
)
5346 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5347 filter
->plist
[direct
].name
= NULL
;
5348 filter
->plist
[direct
].plist
= NULL
;
5350 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5351 peer_on_policy_change(peer
, afi
, safi
,
5352 (direct
== FILTER_OUT
) ? 1 : 0);
5356 group
= peer
->group
;
5357 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5358 filter
= &peer
->filter
[afi
][safi
];
5360 if (filter
->plist
[direct
].name
)
5361 XFREE(MTYPE_BGP_FILTER_NAME
,
5362 filter
->plist
[direct
].name
);
5363 filter
->plist
[direct
].name
= NULL
;
5364 filter
->plist
[direct
].plist
= NULL
;
5365 peer_on_policy_change(peer
, afi
, safi
,
5366 (direct
== FILTER_OUT
) ? 1 : 0);
5372 /* Update prefix-list list. */
5373 static void peer_prefix_list_update(struct prefix_list
*plist
)
5375 struct listnode
*mnode
, *mnnode
;
5376 struct listnode
*node
, *nnode
;
5379 struct peer_group
*group
;
5380 struct bgp_filter
*filter
;
5385 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5388 * Update the prefix-list on update groups.
5390 update_group_policy_update(
5391 bgp
, BGP_POLICY_PREFIX_LIST
,
5392 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5394 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5395 FOREACH_AFI_SAFI (afi
, safi
) {
5396 filter
= &peer
->filter
[afi
][safi
];
5398 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5400 if (filter
->plist
[direct
].name
)
5401 filter
->plist
[direct
]
5402 .plist
= prefix_list_lookup(
5404 filter
->plist
[direct
]
5407 filter
->plist
[direct
].plist
=
5412 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5413 FOREACH_AFI_SAFI (afi
, safi
) {
5414 filter
= &group
->conf
->filter
[afi
][safi
];
5416 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5418 if (filter
->plist
[direct
].name
)
5419 filter
->plist
[direct
]
5420 .plist
= prefix_list_lookup(
5422 filter
->plist
[direct
]
5425 filter
->plist
[direct
].plist
=
5433 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5436 struct bgp_filter
*filter
;
5437 struct peer_group
*group
;
5438 struct listnode
*node
, *nnode
;
5440 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5441 return BGP_ERR_INVALID_VALUE
;
5443 filter
= &peer
->filter
[afi
][safi
];
5445 if (filter
->aslist
[direct
].name
)
5446 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5447 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5448 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5450 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5451 peer_on_policy_change(peer
, afi
, safi
,
5452 (direct
== FILTER_OUT
) ? 1 : 0);
5456 group
= peer
->group
;
5457 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5458 filter
= &peer
->filter
[afi
][safi
];
5460 if (filter
->aslist
[direct
].name
)
5461 XFREE(MTYPE_BGP_FILTER_NAME
,
5462 filter
->aslist
[direct
].name
);
5463 filter
->aslist
[direct
].name
=
5464 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5465 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5466 peer_on_policy_change(peer
, afi
, safi
,
5467 (direct
== FILTER_OUT
) ? 1 : 0);
5472 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5474 struct bgp_filter
*filter
;
5475 struct bgp_filter
*gfilter
;
5476 struct peer_group
*group
;
5477 struct listnode
*node
, *nnode
;
5479 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5480 return BGP_ERR_INVALID_VALUE
;
5482 filter
= &peer
->filter
[afi
][safi
];
5484 /* apply peer-group filter */
5485 if (peer_group_active(peer
)) {
5486 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5488 if (gfilter
->aslist
[direct
].name
) {
5489 if (filter
->aslist
[direct
].name
)
5490 XFREE(MTYPE_BGP_FILTER_NAME
,
5491 filter
->aslist
[direct
].name
);
5492 filter
->aslist
[direct
].name
=
5493 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5494 gfilter
->aslist
[direct
].name
);
5495 filter
->aslist
[direct
].aslist
=
5496 gfilter
->aslist
[direct
].aslist
;
5497 peer_on_policy_change(peer
, afi
, safi
,
5498 (direct
== FILTER_OUT
) ? 1 : 0);
5503 if (filter
->aslist
[direct
].name
)
5504 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5505 filter
->aslist
[direct
].name
= NULL
;
5506 filter
->aslist
[direct
].aslist
= NULL
;
5508 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5509 peer_on_policy_change(peer
, afi
, safi
,
5510 (direct
== FILTER_OUT
) ? 1 : 0);
5514 group
= peer
->group
;
5515 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5516 filter
= &peer
->filter
[afi
][safi
];
5518 if (filter
->aslist
[direct
].name
)
5519 XFREE(MTYPE_BGP_FILTER_NAME
,
5520 filter
->aslist
[direct
].name
);
5521 filter
->aslist
[direct
].name
= NULL
;
5522 filter
->aslist
[direct
].aslist
= NULL
;
5523 peer_on_policy_change(peer
, afi
, safi
,
5524 (direct
== FILTER_OUT
) ? 1 : 0);
5530 static void peer_aslist_update(const char *aslist_name
)
5535 struct listnode
*mnode
, *mnnode
;
5536 struct listnode
*node
, *nnode
;
5539 struct peer_group
*group
;
5540 struct bgp_filter
*filter
;
5542 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5543 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5546 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5547 FOREACH_AFI_SAFI (afi
, safi
) {
5548 filter
= &peer
->filter
[afi
][safi
];
5550 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5552 if (filter
->aslist
[direct
].name
)
5553 filter
->aslist
[direct
]
5554 .aslist
= as_list_lookup(
5555 filter
->aslist
[direct
]
5558 filter
->aslist
[direct
].aslist
=
5563 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5564 FOREACH_AFI_SAFI (afi
, safi
) {
5565 filter
= &group
->conf
->filter
[afi
][safi
];
5567 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5569 if (filter
->aslist
[direct
].name
)
5570 filter
->aslist
[direct
]
5571 .aslist
= as_list_lookup(
5572 filter
->aslist
[direct
]
5575 filter
->aslist
[direct
].aslist
=
5583 static void peer_aslist_add(char *aslist_name
)
5585 peer_aslist_update(aslist_name
);
5586 route_map_notify_dependencies((char *)aslist_name
,
5587 RMAP_EVENT_ASLIST_ADDED
);
5590 static void peer_aslist_del(const char *aslist_name
)
5592 peer_aslist_update(aslist_name
);
5593 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5597 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5600 struct bgp_filter
*filter
;
5601 struct peer_group
*group
;
5602 struct listnode
*node
, *nnode
;
5604 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5605 return BGP_ERR_INVALID_VALUE
;
5607 filter
= &peer
->filter
[afi
][safi
];
5609 if (filter
->map
[direct
].name
)
5610 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5612 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5613 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5615 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5616 peer_on_policy_change(peer
, afi
, safi
,
5617 (direct
== RMAP_OUT
) ? 1 : 0);
5621 group
= peer
->group
;
5622 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5623 filter
= &peer
->filter
[afi
][safi
];
5625 if (filter
->map
[direct
].name
)
5626 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5627 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5628 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5629 peer_on_policy_change(peer
, afi
, safi
,
5630 (direct
== RMAP_OUT
) ? 1 : 0);
5635 /* Unset route-map from the peer. */
5636 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5638 struct bgp_filter
*filter
;
5639 struct bgp_filter
*gfilter
;
5640 struct peer_group
*group
;
5641 struct listnode
*node
, *nnode
;
5643 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5644 return BGP_ERR_INVALID_VALUE
;
5646 filter
= &peer
->filter
[afi
][safi
];
5648 /* apply peer-group filter */
5649 if (peer_group_active(peer
)) {
5650 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5652 if (gfilter
->map
[direct
].name
) {
5653 if (filter
->map
[direct
].name
)
5654 XFREE(MTYPE_BGP_FILTER_NAME
,
5655 filter
->map
[direct
].name
);
5656 filter
->map
[direct
].name
=
5657 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5658 gfilter
->map
[direct
].name
);
5659 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5660 peer_on_policy_change(peer
, afi
, safi
,
5661 (direct
== RMAP_OUT
) ? 1 : 0);
5666 if (filter
->map
[direct
].name
)
5667 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5668 filter
->map
[direct
].name
= NULL
;
5669 filter
->map
[direct
].map
= NULL
;
5671 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5672 peer_on_policy_change(peer
, afi
, safi
,
5673 (direct
== RMAP_OUT
) ? 1 : 0);
5677 group
= peer
->group
;
5678 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5679 filter
= &peer
->filter
[afi
][safi
];
5681 if (filter
->map
[direct
].name
)
5682 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5683 filter
->map
[direct
].name
= NULL
;
5684 filter
->map
[direct
].map
= NULL
;
5685 peer_on_policy_change(peer
, afi
, safi
,
5686 (direct
== RMAP_OUT
) ? 1 : 0);
5691 /* Set unsuppress-map to the peer. */
5692 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5695 struct bgp_filter
*filter
;
5696 struct peer_group
*group
;
5697 struct listnode
*node
, *nnode
;
5699 filter
= &peer
->filter
[afi
][safi
];
5701 if (filter
->usmap
.name
)
5702 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5704 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5705 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5707 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5708 peer_on_policy_change(peer
, afi
, safi
, 1);
5712 group
= peer
->group
;
5713 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5714 filter
= &peer
->filter
[afi
][safi
];
5716 if (filter
->usmap
.name
)
5717 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5718 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5719 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5720 peer_on_policy_change(peer
, afi
, safi
, 1);
5725 /* Unset route-map from the peer. */
5726 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5728 struct bgp_filter
*filter
;
5729 struct peer_group
*group
;
5730 struct listnode
*node
, *nnode
;
5732 filter
= &peer
->filter
[afi
][safi
];
5734 if (filter
->usmap
.name
)
5735 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5736 filter
->usmap
.name
= NULL
;
5737 filter
->usmap
.map
= NULL
;
5739 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5740 peer_on_policy_change(peer
, afi
, safi
, 1);
5744 group
= peer
->group
;
5745 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5746 filter
= &peer
->filter
[afi
][safi
];
5748 if (filter
->usmap
.name
)
5749 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5750 filter
->usmap
.name
= NULL
;
5751 filter
->usmap
.map
= NULL
;
5752 peer_on_policy_change(peer
, afi
, safi
, 1);
5757 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5758 u_int32_t max
, u_char threshold
, int warning
,
5761 struct peer_group
*group
;
5762 struct listnode
*node
, *nnode
;
5764 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5765 peer
->pmax
[afi
][safi
] = max
;
5766 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5767 peer
->pmax_restart
[afi
][safi
] = restart
;
5769 SET_FLAG(peer
->af_flags
[afi
][safi
],
5770 PEER_FLAG_MAX_PREFIX_WARNING
);
5772 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5773 PEER_FLAG_MAX_PREFIX_WARNING
);
5775 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5776 group
= peer
->group
;
5777 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5778 SET_FLAG(peer
->af_flags
[afi
][safi
],
5779 PEER_FLAG_MAX_PREFIX
);
5780 peer
->pmax
[afi
][safi
] = max
;
5781 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5782 peer
->pmax_restart
[afi
][safi
] = restart
;
5784 SET_FLAG(peer
->af_flags
[afi
][safi
],
5785 PEER_FLAG_MAX_PREFIX_WARNING
);
5787 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5788 PEER_FLAG_MAX_PREFIX_WARNING
);
5790 if ((peer
->status
== Established
)
5791 && (peer
->afc
[afi
][safi
]))
5792 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5795 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5796 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5802 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5804 struct peer_group
*group
;
5805 struct listnode
*node
, *nnode
;
5807 /* apply peer-group config */
5808 if (peer_group_active(peer
)) {
5809 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5810 PEER_FLAG_MAX_PREFIX
))
5811 SET_FLAG(peer
->af_flags
[afi
][safi
],
5812 PEER_FLAG_MAX_PREFIX
);
5814 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5815 PEER_FLAG_MAX_PREFIX
);
5817 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5818 PEER_FLAG_MAX_PREFIX_WARNING
))
5819 SET_FLAG(peer
->af_flags
[afi
][safi
],
5820 PEER_FLAG_MAX_PREFIX_WARNING
);
5822 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5823 PEER_FLAG_MAX_PREFIX_WARNING
);
5825 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
5826 peer
->pmax_threshold
[afi
][safi
] =
5827 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
5828 peer
->pmax_restart
[afi
][safi
] =
5829 peer
->group
->conf
->pmax_restart
[afi
][safi
];
5833 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5834 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
5835 peer
->pmax
[afi
][safi
] = 0;
5836 peer
->pmax_threshold
[afi
][safi
] = 0;
5837 peer
->pmax_restart
[afi
][safi
] = 0;
5839 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5842 group
= peer
->group
;
5843 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5844 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5845 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5846 PEER_FLAG_MAX_PREFIX_WARNING
);
5847 peer
->pmax
[afi
][safi
] = 0;
5848 peer
->pmax_threshold
[afi
][safi
] = 0;
5849 peer
->pmax_restart
[afi
][safi
] = 0;
5854 int is_ebgp_multihop_configured(struct peer
*peer
)
5856 struct peer_group
*group
;
5857 struct listnode
*node
, *nnode
;
5860 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5861 group
= peer
->group
;
5862 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
5863 && (group
->conf
->ttl
!= 1))
5866 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
5867 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
5868 && (peer1
->ttl
!= 1))
5872 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
5878 /* Set # of hops between us and BGP peer. */
5879 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
5881 struct peer_group
*group
;
5882 struct listnode
*node
, *nnode
;
5885 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
5886 gtsm_hops
, peer
->host
);
5888 /* We cannot configure ttl-security hops when ebgp-multihop is already
5889 set. For non peer-groups, the check is simple. For peer-groups,
5891 slightly messy, because we need to check both the peer-group
5893 and all peer-group members for any trace of ebgp-multihop
5895 before actually applying the ttl-security rules. Cisco really made a
5896 mess of this configuration parameter, and OpenBGPD got it right.
5899 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
5900 if (is_ebgp_multihop_configured(peer
))
5901 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
5903 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5904 peer
->gtsm_hops
= gtsm_hops
;
5906 /* Calling ebgp multihop also resets the session.
5907 * On restart, NHT will get setup correctly as will the
5908 * min & max ttls on the socket. The return value is
5911 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
5916 group
= peer
->group
;
5917 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5919 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5921 /* Calling ebgp multihop also resets the
5923 * On restart, NHT will get setup correctly as
5925 * min & max ttls on the socket. The return
5929 peer_ebgp_multihop_set(peer
, MAXTTL
);
5933 /* Post the first gtsm setup or if its ibgp, maxttl setting
5935 * necessary, just set the minttl.
5937 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5938 peer
->gtsm_hops
= gtsm_hops
;
5941 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
5942 MAXTTL
+ 1 - gtsm_hops
);
5943 if ((peer
->status
< Established
) && peer
->doppelganger
5944 && (peer
->doppelganger
->fd
>= 0))
5945 sockopt_minttl(peer
->su
.sa
.sa_family
,
5946 peer
->doppelganger
->fd
,
5947 MAXTTL
+ 1 - gtsm_hops
);
5949 group
= peer
->group
;
5950 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5952 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5954 /* Change setting of existing peer
5955 * established then change value (may break
5957 * not established yet (teardown session and
5959 * no session then do nothing (will get
5960 * handled by next connection)
5962 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
5964 peer
->su
.sa
.sa_family
, peer
->fd
,
5965 MAXTTL
+ 1 - peer
->gtsm_hops
);
5966 if ((peer
->status
< Established
)
5967 && peer
->doppelganger
5968 && (peer
->doppelganger
->fd
>= 0))
5969 sockopt_minttl(peer
->su
.sa
.sa_family
,
5970 peer
->doppelganger
->fd
,
5971 MAXTTL
+ 1 - gtsm_hops
);
5979 int peer_ttl_security_hops_unset(struct peer
*peer
)
5981 struct peer_group
*group
;
5982 struct listnode
*node
, *nnode
;
5985 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
5988 /* if a peer-group member, then reset to peer-group default rather than
5990 if (peer_group_active(peer
))
5991 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
5993 peer
->gtsm_hops
= 0;
5995 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5996 /* Invoking ebgp_multihop_set will set the TTL back to the
5998 * value as well as restting the NHT and such. The session is
6001 if (peer
->sort
== BGP_PEER_EBGP
)
6002 ret
= peer_ebgp_multihop_unset(peer
);
6005 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6008 if ((peer
->status
< Established
) && peer
->doppelganger
6009 && (peer
->doppelganger
->fd
>= 0))
6010 sockopt_minttl(peer
->su
.sa
.sa_family
,
6011 peer
->doppelganger
->fd
, 0);
6014 group
= peer
->group
;
6015 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6016 peer
->gtsm_hops
= 0;
6017 if (peer
->sort
== BGP_PEER_EBGP
)
6018 ret
= peer_ebgp_multihop_unset(peer
);
6021 sockopt_minttl(peer
->su
.sa
.sa_family
,
6024 if ((peer
->status
< Established
)
6025 && peer
->doppelganger
6026 && (peer
->doppelganger
->fd
>= 0))
6027 sockopt_minttl(peer
->su
.sa
.sa_family
,
6028 peer
->doppelganger
->fd
,
6038 * If peer clear is invoked in a loop for all peers on the BGP instance,
6039 * it may end up freeing the doppelganger, and if this was the next node
6040 * to the current node, we would end up accessing the freed next node.
6041 * Pass along additional parameter which can be updated if next node
6042 * is freed; only required when walking the peer list on BGP instance.
6044 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6046 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6047 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6048 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6049 if (peer
->t_pmax_restart
) {
6050 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6051 if (bgp_debug_neighbor_events(peer
))
6053 "%s Maximum-prefix restart timer canceled",
6056 BGP_EVENT_ADD(peer
, BGP_Start
);
6060 peer
->v_start
= BGP_INIT_START_TIMER
;
6061 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6062 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6063 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6065 bgp_session_reset_safe(peer
, nnode
);
6070 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6071 enum bgp_clear_type stype
)
6073 struct peer_af
*paf
;
6075 if (peer
->status
!= Established
)
6078 if (!peer
->afc
[afi
][safi
])
6079 return BGP_ERR_AF_UNCONFIGURED
;
6081 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6083 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6084 /* Clear the "neighbor x.x.x.x default-originate" flag */
6085 paf
= peer_af_find(peer
, afi
, safi
);
6086 if (paf
&& paf
->subgroup
6087 && CHECK_FLAG(paf
->subgroup
->sflags
,
6088 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6089 UNSET_FLAG(paf
->subgroup
->sflags
,
6090 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6092 bgp_announce_route(peer
, afi
, safi
);
6095 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6096 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6097 PEER_CAP_ORF_PREFIX_SM_ADV
)
6098 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6099 PEER_CAP_ORF_PREFIX_RM_RCV
)
6100 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6101 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6102 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6105 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6106 PEER_CAP_ORF_PREFIX_RM_RCV
))
6107 prefix_type
= ORF_TYPE_PREFIX
;
6109 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6111 if (filter
->plist
[FILTER_IN
].plist
) {
6112 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6113 PEER_STATUS_ORF_PREFIX_SEND
))
6114 bgp_route_refresh_send(
6115 peer
, afi
, safi
, prefix_type
,
6117 bgp_route_refresh_send(peer
, afi
, safi
,
6119 REFRESH_IMMEDIATE
, 0);
6121 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6122 PEER_STATUS_ORF_PREFIX_SEND
))
6123 bgp_route_refresh_send(
6124 peer
, afi
, safi
, prefix_type
,
6125 REFRESH_IMMEDIATE
, 1);
6127 bgp_route_refresh_send(peer
, afi
, safi
,
6134 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6135 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6136 /* If neighbor has soft reconfiguration inbound flag.
6137 Use Adj-RIB-In database. */
6138 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6139 PEER_FLAG_SOFT_RECONFIG
))
6140 bgp_soft_reconfig_in(peer
, afi
, safi
);
6142 /* If neighbor has route refresh capability, send route
6144 message to the peer. */
6145 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6146 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6147 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6150 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6156 /* Display peer uptime.*/
6157 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, u_char use_json
,
6160 time_t uptime1
, epoch_tbuf
;
6163 /* Check buffer length. */
6164 if (len
< BGP_UPTIME_LEN
) {
6166 zlog_warn("peer_uptime (): buffer shortage %lu",
6168 /* XXX: should return status instead of buf... */
6169 snprintf(buf
, len
, "<error> ");
6174 /* If there is no connection has been done before print `never'. */
6177 json_object_string_add(json
, "peerUptime", "never");
6178 json_object_int_add(json
, "peerUptimeMsec", 0);
6180 snprintf(buf
, len
, "never");
6184 /* Get current time. */
6185 uptime1
= bgp_clock();
6187 tm
= gmtime(&uptime1
);
6189 if (uptime1
< ONE_DAY_SECOND
)
6190 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6192 else if (uptime1
< ONE_WEEK_SECOND
)
6193 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6195 else if (uptime1
< ONE_YEAR_SECOND
)
6196 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6197 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6199 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6201 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6204 epoch_tbuf
= time(NULL
) - uptime1
;
6205 json_object_string_add(json
, "peerUptime", buf
);
6206 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6207 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6214 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6215 afi_t afi
, safi_t safi
)
6217 struct bgp_filter
*filter
;
6218 struct bgp_filter
*gfilter
= NULL
;
6221 int out
= FILTER_OUT
;
6224 filter
= &peer
->filter
[afi
][safi
];
6226 if (peer_group_active(peer
))
6227 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6229 /* distribute-list. */
6230 if (filter
->dlist
[in
].name
)
6231 if (!gfilter
|| !gfilter
->dlist
[in
].name
6232 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6234 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6235 addr
, filter
->dlist
[in
].name
);
6238 if (filter
->dlist
[out
].name
&& !gfilter
) {
6239 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6240 filter
->dlist
[out
].name
);
6244 if (filter
->plist
[in
].name
)
6245 if (!gfilter
|| !gfilter
->plist
[in
].name
6246 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6248 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6249 filter
->plist
[in
].name
);
6252 if (filter
->plist
[out
].name
)
6253 if (!gfilter
|| !gfilter
->plist
[out
].name
6254 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6256 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6257 filter
->plist
[out
].name
);
6261 if (filter
->map
[RMAP_IN
].name
)
6262 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6263 || strcmp(filter
->map
[RMAP_IN
].name
,
6264 gfilter
->map
[RMAP_IN
].name
)
6266 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6267 filter
->map
[RMAP_IN
].name
);
6270 if (filter
->map
[RMAP_OUT
].name
)
6271 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6272 || strcmp(filter
->map
[RMAP_OUT
].name
,
6273 gfilter
->map
[RMAP_OUT
].name
)
6275 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6276 filter
->map
[RMAP_OUT
].name
);
6279 /* unsuppress-map */
6280 if (filter
->usmap
.name
&& !gfilter
) {
6281 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6282 filter
->usmap
.name
);
6286 if (filter
->aslist
[in
].name
)
6287 if (!gfilter
|| !gfilter
->aslist
[in
].name
6288 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6290 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6291 filter
->aslist
[in
].name
);
6294 if (filter
->aslist
[out
].name
&& !gfilter
) {
6295 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6296 filter
->aslist
[out
].name
);
6300 /* BGP peer configuration display function. */
6301 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6304 struct peer
*g_peer
= NULL
;
6305 char buf
[SU_ADDRSTRLEN
];
6307 int if_pg_printed
= FALSE
;
6308 int if_ras_printed
= FALSE
;
6310 /* Skip dynamic neighbors. */
6311 if (peer_dynamic_neighbor(peer
))
6315 addr
= peer
->conf_if
;
6319 /************************************
6320 ****** Global to the neighbor ******
6321 ************************************/
6322 if (peer
->conf_if
) {
6323 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6324 vty_out(vty
, " neighbor %s interface v6only", addr
);
6326 vty_out(vty
, " neighbor %s interface", addr
);
6328 if (peer_group_active(peer
)) {
6329 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6330 if_pg_printed
= TRUE
;
6331 } else if (peer
->as_type
== AS_SPECIFIED
) {
6332 vty_out(vty
, " remote-as %u", peer
->as
);
6333 if_ras_printed
= TRUE
;
6334 } else if (peer
->as_type
== AS_INTERNAL
) {
6335 vty_out(vty
, " remote-as internal");
6336 if_ras_printed
= TRUE
;
6337 } else if (peer
->as_type
== AS_EXTERNAL
) {
6338 vty_out(vty
, " remote-as external");
6339 if_ras_printed
= TRUE
;
6345 /* remote-as and peer-group */
6346 /* peer is a member of a peer-group */
6347 if (peer_group_active(peer
)) {
6348 g_peer
= peer
->group
->conf
;
6350 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6351 if (peer
->as_type
== AS_SPECIFIED
) {
6352 vty_out(vty
, " neighbor %s remote-as %u\n",
6354 } else if (peer
->as_type
== AS_INTERNAL
) {
6356 " neighbor %s remote-as internal\n",
6358 } else if (peer
->as_type
== AS_EXTERNAL
) {
6360 " neighbor %s remote-as external\n",
6365 /* For swpX peers we displayed the peer-group
6366 * via 'neighbor swpX interface peer-group WORD' */
6368 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6372 /* peer is NOT a member of a peer-group */
6374 /* peer is a peer-group, declare the peer-group */
6375 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6376 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6379 if (!if_ras_printed
) {
6380 if (peer
->as_type
== AS_SPECIFIED
) {
6381 vty_out(vty
, " neighbor %s remote-as %u\n",
6383 } else if (peer
->as_type
== AS_INTERNAL
) {
6385 " neighbor %s remote-as internal\n",
6387 } else if (peer
->as_type
== AS_EXTERNAL
) {
6389 " neighbor %s remote-as external\n",
6396 if (peer
->change_local_as
) {
6397 if (!peer_group_active(peer
)
6398 || peer
->change_local_as
!= g_peer
->change_local_as
6399 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6400 != CHECK_FLAG(g_peer
->flags
,
6401 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6402 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6403 != CHECK_FLAG(g_peer
->flags
,
6404 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6405 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6406 peer
->change_local_as
,
6407 CHECK_FLAG(peer
->flags
,
6408 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6411 CHECK_FLAG(peer
->flags
,
6412 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6420 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6424 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6425 if (!peer_group_active(peer
)
6426 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6427 || peer
->tx_shutdown_message
) {
6428 if (peer
->tx_shutdown_message
)
6430 " neighbor %s shutdown message %s\n",
6431 addr
, peer
->tx_shutdown_message
);
6433 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6438 if (peer
->bfd_info
) {
6439 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6440 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6445 if (peer
->password
) {
6446 if (!peer_group_active(peer
) || !g_peer
->password
6447 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6448 vty_out(vty
, " neighbor %s password %s\n", addr
,
6454 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6455 if (!peer_group_active(peer
)) {
6456 vty_out(vty
, " neighbor %s solo\n", addr
);
6461 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6462 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6465 /* Local interface name */
6467 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6471 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6472 if (!peer_group_active(peer
)
6473 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6474 vty_out(vty
, " neighbor %s passive\n", addr
);
6479 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6480 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6481 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6482 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6487 /* ttl-security hops */
6488 if (peer
->gtsm_hops
!= 0) {
6489 if (!peer_group_active(peer
)
6490 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6491 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6492 addr
, peer
->gtsm_hops
);
6496 /* disable-connected-check */
6497 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6498 if (!peer_group_active(peer
)
6499 || !CHECK_FLAG(g_peer
->flags
,
6500 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6501 vty_out(vty
, " neighbor %s disable-connected-check\n",
6507 if (peer
->update_if
) {
6508 if (!peer_group_active(peer
) || !g_peer
->update_if
6509 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6510 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6514 if (peer
->update_source
) {
6515 if (!peer_group_active(peer
) || !g_peer
->update_source
6516 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6518 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6519 sockunion2str(peer
->update_source
, buf
,
6524 /* advertisement-interval */
6525 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6526 && ((!peer_group_active(peer
)
6527 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6528 || (peer_group_active(peer
)
6529 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6530 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6535 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6536 && ((!peer_group_active(peer
)
6537 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6538 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6539 || (peer_group_active(peer
)
6540 && (peer
->keepalive
!= g_peer
->keepalive
6541 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6542 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6543 peer
->keepalive
, peer
->holdtime
);
6546 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6547 && ((!peer_group_active(peer
)
6548 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6549 || (peer_group_active(peer
)
6550 && peer
->connect
!= g_peer
->connect
)))
6553 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6557 /* capability dynamic */
6558 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6559 if (!peer_group_active(peer
)
6560 || !CHECK_FLAG(g_peer
->flags
,
6561 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6562 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6566 /* capability extended-nexthop */
6567 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6568 if (!peer_group_active(peer
)
6569 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6571 " no neighbor %s capability extended-nexthop\n",
6576 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6577 if (!peer_group_active(peer
)
6578 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6580 " neighbor %s capability extended-nexthop\n",
6585 /* dont-capability-negotiation */
6586 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6587 if (!peer_group_active(peer
)
6588 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6589 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6594 /* override-capability */
6595 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6596 if (!peer_group_active(peer
)
6597 || !CHECK_FLAG(g_peer
->flags
,
6598 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6599 vty_out(vty
, " neighbor %s override-capability\n",
6604 /* strict-capability-match */
6605 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6606 if (!peer_group_active(peer
)
6607 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6608 vty_out(vty
, " neighbor %s strict-capability-match\n",
6614 /* BGP peer configuration display function. */
6615 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6616 struct peer
*peer
, afi_t afi
, safi_t safi
)
6618 struct peer
*g_peer
= NULL
;
6621 /* Skip dynamic neighbors. */
6622 if (peer_dynamic_neighbor(peer
))
6626 addr
= peer
->conf_if
;
6630 /************************************
6631 ****** Per AF to the neighbor ******
6632 ************************************/
6633 if (peer_group_active(peer
)) {
6634 g_peer
= peer
->group
->conf
;
6636 /* If the peer-group is active but peer is not, print a 'no
6638 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6639 vty_out(vty
, " no neighbor %s activate\n", addr
);
6642 /* If the peer-group is not active but peer is, print an
6644 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6645 vty_out(vty
, " neighbor %s activate\n", addr
);
6648 if (peer
->afc
[afi
][safi
]) {
6649 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6650 if (bgp_flag_check(bgp
,
6651 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6652 vty_out(vty
, " neighbor %s activate\n",
6656 vty_out(vty
, " neighbor %s activate\n", addr
);
6658 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6659 if (!bgp_flag_check(bgp
,
6660 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6662 " no neighbor %s activate\n",
6669 /* addpath TX knobs */
6670 if (peergroup_af_flag_check(peer
, afi
, safi
,
6671 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6672 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6675 if (peergroup_af_flag_check(peer
, afi
, safi
,
6676 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6677 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6681 /* ORF capability. */
6682 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6683 || peergroup_af_flag_check(peer
, afi
, safi
,
6684 PEER_FLAG_ORF_PREFIX_RM
)) {
6685 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6687 if (peergroup_af_flag_check(peer
, afi
, safi
,
6688 PEER_FLAG_ORF_PREFIX_SM
)
6689 && peergroup_af_flag_check(peer
, afi
, safi
,
6690 PEER_FLAG_ORF_PREFIX_RM
))
6691 vty_out(vty
, " both");
6692 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6693 PEER_FLAG_ORF_PREFIX_SM
))
6694 vty_out(vty
, " send");
6696 vty_out(vty
, " receive");
6700 /* Route reflector client. */
6701 if (peergroup_af_flag_check(peer
, afi
, safi
,
6702 PEER_FLAG_REFLECTOR_CLIENT
)) {
6703 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6706 /* next-hop-self force */
6707 if (peergroup_af_flag_check(peer
, afi
, safi
,
6708 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6709 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6713 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6714 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6717 /* remove-private-AS */
6718 if (peergroup_af_flag_check(peer
, afi
, safi
,
6719 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6720 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6724 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6725 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6726 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6730 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6731 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6732 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6735 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6736 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6737 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6741 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6742 vty_out(vty
, " neighbor %s as-override\n", addr
);
6745 /* send-community print. */
6746 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6747 if (peergroup_af_flag_check(peer
, afi
, safi
,
6748 PEER_FLAG_SEND_COMMUNITY
)
6749 && peergroup_af_flag_check(peer
, afi
, safi
,
6750 PEER_FLAG_SEND_EXT_COMMUNITY
)
6751 && peergroup_af_flag_check(
6753 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6754 vty_out(vty
, " neighbor %s send-community all\n",
6756 } else if (peergroup_af_flag_check(
6758 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6759 vty_out(vty
, " neighbor %s send-community large\n",
6761 } else if (peergroup_af_flag_check(
6763 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6764 vty_out(vty
, " neighbor %s send-community extended\n",
6766 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6767 PEER_FLAG_SEND_COMMUNITY
)) {
6768 vty_out(vty
, " neighbor %s send-community\n", addr
);
6771 if (!peer_af_flag_check(peer
, afi
, safi
,
6772 PEER_FLAG_SEND_COMMUNITY
)
6773 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6774 PEER_FLAG_SEND_COMMUNITY
))
6775 && !peer_af_flag_check(peer
, afi
, safi
,
6776 PEER_FLAG_SEND_EXT_COMMUNITY
)
6778 || peer_af_flag_check(g_peer
, afi
, safi
,
6779 PEER_FLAG_SEND_EXT_COMMUNITY
))
6780 && !peer_af_flag_check(peer
, afi
, safi
,
6781 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6782 && (!g_peer
|| peer_af_flag_check(
6784 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6785 vty_out(vty
, " no neighbor %s send-community all\n",
6788 if (!peer_af_flag_check(peer
, afi
, safi
,
6789 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6791 || peer_af_flag_check(
6793 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6795 " no neighbor %s send-community large\n",
6799 if (!peer_af_flag_check(peer
, afi
, safi
,
6800 PEER_FLAG_SEND_EXT_COMMUNITY
)
6802 || peer_af_flag_check(
6804 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6806 " no neighbor %s send-community extended\n",
6810 if (!peer_af_flag_check(peer
, afi
, safi
,
6811 PEER_FLAG_SEND_COMMUNITY
)
6812 && (!g_peer
|| peer_af_flag_check(
6814 PEER_FLAG_SEND_COMMUNITY
))) {
6816 " no neighbor %s send-community\n",
6822 /* Default information */
6823 if (peergroup_af_flag_check(peer
, afi
, safi
,
6824 PEER_FLAG_DEFAULT_ORIGINATE
)
6826 && ((peer
->default_rmap
[afi
][safi
].name
6827 && !g_peer
->default_rmap
[afi
][safi
].name
)
6828 || (!peer
->default_rmap
[afi
][safi
].name
6829 && g_peer
->default_rmap
[afi
][safi
].name
)
6830 || (peer
->default_rmap
[afi
][safi
].name
6831 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
6832 g_peer
->default_rmap
[afi
][safi
].name
))))) {
6833 vty_out(vty
, " neighbor %s default-originate", addr
);
6834 if (peer
->default_rmap
[afi
][safi
].name
)
6835 vty_out(vty
, " route-map %s",
6836 peer
->default_rmap
[afi
][safi
].name
);
6840 /* Soft reconfiguration inbound. */
6841 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
6842 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
6846 /* maximum-prefix. */
6847 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
6848 if (!peer_group_active(peer
)
6849 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
6850 || g_peer
->pmax_threshold
[afi
][safi
]
6851 != peer
->pmax_threshold
[afi
][safi
]
6852 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
6853 PEER_FLAG_MAX_PREFIX_WARNING
)
6854 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6855 PEER_FLAG_MAX_PREFIX_WARNING
)) {
6856 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
6857 peer
->pmax
[afi
][safi
]);
6858 if (peer
->pmax_threshold
[afi
][safi
]
6859 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
6861 peer
->pmax_threshold
[afi
][safi
]);
6862 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6863 PEER_FLAG_MAX_PREFIX_WARNING
))
6864 vty_out(vty
, " warning-only");
6865 if (peer
->pmax_restart
[afi
][safi
])
6866 vty_out(vty
, " restart %u",
6867 peer
->pmax_restart
[afi
][safi
]);
6871 /* Route server client. */
6872 if (peergroup_af_flag_check(peer
, afi
, safi
,
6873 PEER_FLAG_RSERVER_CLIENT
)) {
6874 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
6877 /* Nexthop-local unchanged. */
6878 if (peergroup_af_flag_check(peer
, afi
, safi
,
6879 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
6880 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
6883 /* allowas-in <1-10> */
6884 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
6885 if (!peer_group_active(peer
)
6886 || !peer_af_flag_check(g_peer
, afi
, safi
,
6887 PEER_FLAG_ALLOWAS_IN
)
6888 || peer
->allowas_in
[afi
][safi
]
6889 != g_peer
->allowas_in
[afi
][safi
]) {
6890 if (peer
->allowas_in
[afi
][safi
] == 3) {
6891 vty_out(vty
, " neighbor %s allowas-in\n",
6894 vty_out(vty
, " neighbor %s allowas-in %d\n",
6895 addr
, peer
->allowas_in
[afi
][safi
]);
6900 /* allowas-in origin */
6901 else if (peer_af_flag_check(peer
, afi
, safi
,
6902 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6903 if (!peer_group_active(peer
)
6904 || !peer_af_flag_check(g_peer
, afi
, safi
,
6905 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6906 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
6911 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
6912 if (!peer_group_active(peer
)
6913 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
6914 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
6915 if (peer
->weight
[afi
][safi
]) {
6916 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
6917 peer
->weight
[afi
][safi
]);
6922 bgp_config_write_filter(vty
, peer
, afi
, safi
);
6924 /* atribute-unchanged. */
6925 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
) ||
6926 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6927 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
6929 if (!peer_group_active(peer
) ||
6930 peergroup_af_flag_check(peer
, afi
, safi
,
6931 PEER_FLAG_AS_PATH_UNCHANGED
) ||
6932 peergroup_af_flag_check(peer
, afi
, safi
,
6933 PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6934 peergroup_af_flag_check(peer
, afi
, safi
,
6935 PEER_FLAG_MED_UNCHANGED
)) {
6938 " neighbor %s attribute-unchanged%s%s%s\n",
6940 peer_af_flag_check(peer
, afi
, safi
,
6941 PEER_FLAG_AS_PATH_UNCHANGED
)
6944 peer_af_flag_check(peer
, afi
, safi
,
6945 PEER_FLAG_NEXTHOP_UNCHANGED
)
6948 peer_af_flag_check(peer
, afi
, safi
,
6949 PEER_FLAG_MED_UNCHANGED
)
6956 /* Address family based peer configuration display. */
6957 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
6961 struct peer_group
*group
;
6962 struct listnode
*node
, *nnode
;
6965 vty_frame(vty
, " !\n address-family ");
6966 if (afi
== AFI_IP
) {
6967 if (safi
== SAFI_UNICAST
)
6968 vty_frame(vty
, "ipv4 unicast");
6969 else if (safi
== SAFI_LABELED_UNICAST
)
6970 vty_frame(vty
, "ipv4 labeled-unicast");
6971 else if (safi
== SAFI_MULTICAST
)
6972 vty_frame(vty
, "ipv4 multicast");
6973 else if (safi
== SAFI_MPLS_VPN
)
6974 vty_frame(vty
, "ipv4 vpn");
6975 else if (safi
== SAFI_ENCAP
)
6976 vty_frame(vty
, "ipv4 encap");
6977 } else if (afi
== AFI_IP6
) {
6978 if (safi
== SAFI_UNICAST
)
6979 vty_frame(vty
, "ipv6 unicast");
6980 else if (safi
== SAFI_LABELED_UNICAST
)
6981 vty_frame(vty
, "ipv6 labeled-unicast");
6982 else if (safi
== SAFI_MULTICAST
)
6983 vty_frame(vty
, "ipv6 multicast");
6984 else if (safi
== SAFI_MPLS_VPN
)
6985 vty_frame(vty
, "ipv6 vpn");
6986 else if (safi
== SAFI_ENCAP
)
6987 vty_frame(vty
, "ipv6 encap");
6988 } else if (afi
== AFI_L2VPN
) {
6989 if (safi
== SAFI_EVPN
)
6990 vty_frame(vty
, "l2vpn evpn");
6992 vty_frame(vty
, "\n");
6994 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
6996 bgp_config_write_network(vty
, bgp
, afi
, safi
);
6998 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7000 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7001 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7003 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7004 /* Skip dynamic neighbors. */
7005 if (peer_dynamic_neighbor(peer
))
7008 /* Do not display doppelganger peers */
7009 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7010 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7013 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7014 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7016 if (safi
== SAFI_EVPN
)
7017 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7019 vty_endframe(vty
, " exit-address-family\n");
7022 int bgp_config_write(struct vty
*vty
)
7026 struct peer_group
*group
;
7028 struct listnode
*node
, *nnode
;
7029 struct listnode
*mnode
, *mnnode
;
7031 /* BGP Multiple instance. */
7032 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7033 vty_out(vty
, "no bgp multiple-instance\n");
7037 /* BGP Config type. */
7038 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7039 vty_out(vty
, "bgp config-type cisco\n");
7043 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7044 vty_out(vty
, "bgp route-map delay-timer %u\n",
7045 bm
->rmap_update_timer
);
7048 vty_out(vty
, "!\n");
7050 /* BGP configuration. */
7051 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7052 /* Router bgp ASN */
7053 vty_out(vty
, "router bgp %u", bgp
->as
);
7055 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7057 vty_out(vty
, " %s %s",
7059 == BGP_INSTANCE_TYPE_VIEW
)
7066 /* No Synchronization */
7067 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7068 vty_out(vty
, " no synchronization\n");
7070 /* BGP fast-external-failover. */
7071 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7072 vty_out(vty
, " no bgp fast-external-failover\n");
7074 /* BGP router ID. */
7075 if (bgp
->router_id_static
.s_addr
!= 0)
7076 vty_out(vty
, " bgp router-id %s\n",
7077 inet_ntoa(bgp
->router_id_static
));
7079 /* BGP log-neighbor-changes. */
7080 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7081 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7082 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7084 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7088 /* BGP configuration. */
7089 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7090 vty_out(vty
, " bgp always-compare-med\n");
7092 /* BGP default ipv4-unicast. */
7093 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7094 vty_out(vty
, " no bgp default ipv4-unicast\n");
7096 /* BGP default local-preference. */
7097 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7098 vty_out(vty
, " bgp default local-preference %u\n",
7099 bgp
->default_local_pref
);
7101 /* BGP default show-hostname */
7102 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7103 != DFLT_BGP_SHOW_HOSTNAME
)
7104 vty_out(vty
, " %sbgp default show-hostname\n",
7105 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7109 /* BGP default subgroup-pkt-queue-max. */
7110 if (bgp
->default_subgroup_pkt_queue_max
7111 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7112 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7113 bgp
->default_subgroup_pkt_queue_max
);
7115 /* BGP client-to-client reflection. */
7116 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7117 vty_out(vty
, " no bgp client-to-client reflection\n");
7119 /* BGP cluster ID. */
7120 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7121 vty_out(vty
, " bgp cluster-id %s\n",
7122 inet_ntoa(bgp
->cluster_id
));
7124 /* Disable ebgp connected nexthop check */
7125 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7127 " bgp disable-ebgp-connected-route-check\n");
7129 /* Confederation identifier*/
7130 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7131 vty_out(vty
, " bgp confederation identifier %i\n",
7134 /* Confederation peer */
7135 if (bgp
->confed_peers_cnt
> 0) {
7138 vty_out(vty
, " bgp confederation peers");
7140 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7141 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7146 /* BGP enforce-first-as. */
7147 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7148 vty_out(vty
, " bgp enforce-first-as\n");
7150 /* BGP deterministic-med. */
7151 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7152 != DFLT_BGP_DETERMINISTIC_MED
)
7153 vty_out(vty
, " %sbgp deterministic-med\n",
7154 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7158 /* BGP update-delay. */
7159 bgp_config_write_update_delay(vty
, bgp
);
7161 if (bgp
->v_maxmed_onstartup
7162 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7163 vty_out(vty
, " bgp max-med on-startup %u",
7164 bgp
->v_maxmed_onstartup
);
7165 if (bgp
->maxmed_onstartup_value
7166 != BGP_MAXMED_VALUE_DEFAULT
)
7168 bgp
->maxmed_onstartup_value
);
7171 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7172 vty_out(vty
, " bgp max-med administrative");
7173 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7174 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7179 bgp_config_write_wpkt_quanta(vty
, bgp
);
7182 bgp_config_write_coalesce_time(vty
, bgp
);
7184 /* BGP graceful-restart. */
7185 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7187 " bgp graceful-restart stalepath-time %u\n",
7188 bgp
->stalepath_time
);
7189 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7190 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7192 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7193 vty_out(vty
, " bgp graceful-restart\n");
7195 /* BGP graceful-shutdown */
7196 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7197 vty_out(vty
, " bgp graceful-shutdown\n");
7199 /* BGP graceful-restart Preserve State F bit. */
7200 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7202 " bgp graceful-restart preserve-fw-state\n");
7204 /* BGP bestpath method. */
7205 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7206 vty_out(vty
, " bgp bestpath as-path ignore\n");
7207 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7208 vty_out(vty
, " bgp bestpath as-path confed\n");
7210 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7211 if (bgp_flag_check(bgp
,
7212 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7214 " bgp bestpath as-path multipath-relax as-set\n");
7217 " bgp bestpath as-path multipath-relax\n");
7221 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7223 " bgp route-reflector allow-outbound-policy\n");
7225 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7226 vty_out(vty
, " bgp bestpath compare-routerid\n");
7227 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7228 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7229 vty_out(vty
, " bgp bestpath med");
7230 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7231 vty_out(vty
, " confed");
7232 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7233 vty_out(vty
, " missing-as-worst");
7237 /* BGP network import check. */
7238 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7239 != DFLT_BGP_IMPORT_CHECK
)
7240 vty_out(vty
, " %sbgp network import-check\n",
7241 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7245 /* BGP flag dampening. */
7246 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7247 BGP_CONFIG_DAMPENING
))
7248 bgp_config_write_damp(vty
);
7250 /* BGP timers configuration. */
7251 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7252 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7253 vty_out(vty
, " timers bgp %u %u\n",
7254 bgp
->default_keepalive
, bgp
->default_holdtime
);
7257 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7258 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7261 /* Normal neighbor configuration. */
7262 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7263 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7264 bgp_config_write_peer_global(vty
, bgp
, peer
);
7267 /* listen range and limit for dynamic BGP neighbors */
7268 bgp_config_write_listen(vty
, bgp
);
7270 /* No auto-summary */
7271 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7272 vty_out(vty
, " no auto-summary\n");
7274 /* IPv4 unicast configuration. */
7275 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7277 /* IPv4 multicast configuration. */
7278 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7280 /* IPv4 labeled-unicast configuration. */
7281 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7283 /* IPv4 VPN configuration. */
7284 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7286 /* ENCAPv4 configuration. */
7287 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7289 /* IPv6 unicast configuration. */
7290 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7292 /* IPv6 multicast configuration. */
7293 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7295 /* IPv6 labeled-unicast configuration. */
7296 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7297 SAFI_LABELED_UNICAST
);
7299 /* IPv6 VPN configuration. */
7300 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7302 /* ENCAPv6 configuration. */
7303 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7305 /* EVPN configuration. */
7306 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7309 bgp_rfapi_cfg_write(vty
, bgp
);
7312 vty_out(vty
, "!\n");
7317 void bgp_master_init(struct thread_master
*master
)
7321 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7324 bm
->bgp
= list_new();
7325 bm
->listen_sockets
= list_new();
7326 bm
->port
= BGP_PORT_DEFAULT
;
7327 bm
->master
= master
;
7328 bm
->start_time
= bgp_clock();
7329 bm
->t_rmap_update
= NULL
;
7330 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7332 bgp_process_queue_init();
7334 /* Enable multiple instances by default. */
7335 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7337 QOBJ_REG(bm
, bgp_master
);
7341 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7342 * instance delete (non-default only) or BGP exit.
7344 static void bgp_if_finish(struct bgp
*bgp
)
7346 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7347 struct interface
*ifp
;
7349 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7352 FOR_ALL_INTERFACES (vrf
, ifp
) {
7353 struct listnode
*c_node
, *c_nnode
;
7354 struct connected
*c
;
7356 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7357 bgp_connected_delete(bgp
, c
);
7361 extern void bgp_snmp_init(void);
7363 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7365 struct vrf
*vrf
= NULL
;
7366 struct listnode
*next
;
7369 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7370 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7371 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7374 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7375 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7378 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7382 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7383 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7384 {.completions
= NULL
},
7387 void bgp_pthreads_init()
7391 frr_pthread_new("BGP write thread", PTHREAD_WRITE
, peer_writes_start
,
7393 frr_pthread_new("BGP keepalives thread", PTHREAD_KEEPALIVES
,
7394 peer_keepalives_start
, peer_keepalives_stop
);
7396 /* pre-run initialization */
7397 peer_keepalives_init();
7401 void bgp_pthreads_run()
7403 frr_pthread_run(PTHREAD_WRITE
, NULL
, NULL
);
7404 frr_pthread_run(PTHREAD_KEEPALIVES
, NULL
, NULL
);
7407 void bgp_pthreads_finish()
7409 frr_pthread_stop_all();
7410 frr_pthread_finish();
7416 /* allocates some vital data structures used by peer commands in
7419 /* pre-init pthreads */
7420 bgp_pthreads_init();
7423 bgp_zebra_init(bm
->master
);
7426 vnc_zebra_init(bm
->master
);
7429 /* BGP VTY commands installation. */
7437 bgp_route_map_init();
7438 bgp_scan_vty_init();
7443 bgp_ethernetvpn_init();
7445 /* Access list initialize. */
7447 access_list_add_hook(peer_distribute_update
);
7448 access_list_delete_hook(peer_distribute_update
);
7450 /* Filter list initialize. */
7452 as_list_add_hook(peer_aslist_add
);
7453 as_list_delete_hook(peer_aslist_del
);
7455 /* Prefix list initialize.*/
7457 prefix_list_add_hook(peer_prefix_list_update
);
7458 prefix_list_delete_hook(peer_prefix_list_update
);
7460 /* Community list initialize. */
7461 bgp_clist
= community_list_init();
7466 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7469 void bgp_terminate(void)
7473 struct listnode
*node
, *nnode
;
7474 struct listnode
*mnode
, *mnnode
;
7478 /* Close the listener sockets first as this prevents peers from
7480 * to reconnect on receiving the peer unconfig message. In the presence
7481 * of a large number of peers this will ensure that no peer is left with
7482 * a dangling connection
7484 /* reverse bgp_master_init */
7486 if (bm
->listen_sockets
)
7487 list_delete_and_null(&bm
->listen_sockets
);
7489 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7490 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7491 if (peer
->status
== Established
7492 || peer
->status
== OpenSent
7493 || peer
->status
== OpenConfirm
)
7494 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7495 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7497 if (bm
->process_main_queue
) {
7498 work_queue_free(bm
->process_main_queue
);
7499 bm
->process_main_queue
= NULL
;
7502 if (bm
->t_rmap_update
)
7503 BGP_TIMER_OFF(bm
->t_rmap_update
);