1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
49 #include "bgpd/bgpd.h"
50 #include "bgpd/bgp_table.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_route.h"
53 #include "bgpd/bgp_dump.h"
54 #include "bgpd/bgp_debug.h"
55 #include "bgpd/bgp_errors.h"
56 #include "bgpd/bgp_community.h"
57 #include "bgpd/bgp_attr.h"
58 #include "bgpd/bgp_regex.h"
59 #include "bgpd/bgp_clist.h"
60 #include "bgpd/bgp_fsm.h"
61 #include "bgpd/bgp_packet.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_open.h"
64 #include "bgpd/bgp_filter.h"
65 #include "bgpd/bgp_nexthop.h"
66 #include "bgpd/bgp_damp.h"
67 #include "bgpd/bgp_mplsvpn.h"
69 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
70 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/bgp_evpn.h"
73 #include "bgpd/bgp_advertise.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_vty.h"
76 #include "bgpd/bgp_mpath.h"
77 #include "bgpd/bgp_nht.h"
78 #include "bgpd/bgp_updgrp.h"
79 #include "bgpd/bgp_bfd.h"
80 #include "bgpd/bgp_memory.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_keepalives.h"
83 #include "bgpd/bgp_io.h"
84 #include "bgpd/bgp_ecommunity.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_labelpool.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "bgpd/bgp_addpath.h"
89 #include "bgpd/bgp_evpn_private.h"
90 #include "bgpd/bgp_mac.h"
92 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
93 DEFINE_MTYPE_STATIC(BGPD
, BGP_EVPN_INFO
, "BGP EVPN instance information");
94 DEFINE_QOBJ_TYPE(bgp_master
)
96 DEFINE_QOBJ_TYPE(peer
)
98 /* BGP process wide configuration. */
99 static struct bgp_master bgp_master
;
101 /* BGP process wide configuration pointer to export. */
102 struct bgp_master
*bm
;
104 /* BGP community-list. */
105 struct community_list_handler
*bgp_clist
;
107 unsigned int multipath_num
= MULTIPATH_NUM
;
109 static void bgp_if_finish(struct bgp
*bgp
);
110 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
112 extern struct zclient
*zclient
;
114 /* handle main socket creation or deletion */
115 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
117 static int bgp_server_main_created
;
120 if (bgp_server_main_created
)
122 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
123 return BGP_ERR_INVALID_VALUE
;
124 bgp_server_main_created
= 1;
127 if (!bgp_server_main_created
)
130 bgp_server_main_created
= 0;
134 void bgp_session_reset(struct peer
*peer
)
136 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
137 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
138 peer_delete(peer
->doppelganger
);
140 BGP_EVENT_ADD(peer
, BGP_Stop
);
144 * During session reset, we may delete the doppelganger peer, which would
145 * be the next node to the current node. If the session reset was invoked
146 * during walk of peer list, we would end up accessing the freed next
147 * node. This function moves the next node along.
149 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
154 n
= (nnode
) ? *nnode
: NULL
;
155 npeer
= (n
) ? listgetdata(n
) : NULL
;
157 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
158 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
159 PEER_FLAG_CONFIG_NODE
))) {
160 if (peer
->doppelganger
== npeer
)
161 /* nnode and *nnode are confirmed to be non-NULL here */
162 *nnode
= (*nnode
)->next
;
163 peer_delete(peer
->doppelganger
);
166 BGP_EVENT_ADD(peer
, BGP_Stop
);
169 /* BGP global flag manipulation. */
170 int bgp_option_set(int flag
)
174 case BGP_OPT_NO_LISTEN
:
175 case BGP_OPT_NO_ZEBRA
:
176 SET_FLAG(bm
->options
, flag
);
179 return BGP_ERR_INVALID_FLAG
;
184 int bgp_option_unset(int flag
)
188 case BGP_OPT_NO_ZEBRA
:
190 UNSET_FLAG(bm
->options
, flag
);
193 return BGP_ERR_INVALID_FLAG
;
198 int bgp_option_check(int flag
)
200 return CHECK_FLAG(bm
->options
, flag
);
203 /* BGP flag manipulation. */
204 int bgp_flag_set(struct bgp
*bgp
, int flag
)
206 SET_FLAG(bgp
->flags
, flag
);
210 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
212 UNSET_FLAG(bgp
->flags
, flag
);
216 int bgp_flag_check(struct bgp
*bgp
, int flag
)
218 return CHECK_FLAG(bgp
->flags
, flag
);
221 /* Internal function to set BGP structure configureation flag. */
222 static void bgp_config_set(struct bgp
*bgp
, int config
)
224 SET_FLAG(bgp
->config
, config
);
227 static void bgp_config_unset(struct bgp
*bgp
, int config
)
229 UNSET_FLAG(bgp
->config
, config
);
232 static int bgp_config_check(struct bgp
*bgp
, int config
)
234 return CHECK_FLAG(bgp
->config
, config
);
237 /* Set BGP router identifier; distinguish between explicit config and other
240 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
,
244 struct listnode
*node
, *nnode
;
246 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
249 /* EVPN uses router id in RD, withdraw them */
250 if (is_evpn_enabled())
251 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
253 vpn_handle_router_id_update(bgp
, TRUE
, is_config
);
255 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
257 /* Set all peer's local identifier with this value. */
258 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
259 IPV4_ADDR_COPY(&peer
->local_id
, id
);
261 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
262 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
263 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
264 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
268 /* EVPN uses router id in RD, update them */
269 if (is_evpn_enabled())
270 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
272 vpn_handle_router_id_update(bgp
, FALSE
, is_config
);
277 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
279 struct listnode
*node
, *nnode
;
281 struct in_addr
*addr
= NULL
;
283 if (router_id
!= NULL
)
284 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
286 if (vrf_id
== VRF_DEFAULT
) {
287 /* Router-id change for default VRF has to also update all
289 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
290 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
294 bgp
->router_id_zebra
= *addr
;
296 addr
= &bgp
->router_id_zebra
;
298 if (!bgp
->router_id_static
.s_addr
) {
299 /* Router ID is updated if there are no active
302 if (bgp
->established_peers
== 0) {
303 if (BGP_DEBUG(zebra
, ZEBRA
))
304 zlog_debug("RID change : vrf %u, RTR ID %s",
305 bgp
->vrf_id
, inet_ntoa(*addr
));
306 bgp_router_id_set(bgp
, addr
, FALSE
);
311 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
314 bgp
->router_id_zebra
= *addr
;
316 addr
= &bgp
->router_id_zebra
;
318 if (!bgp
->router_id_static
.s_addr
) {
319 /* Router ID is updated if there are no active
322 if (bgp
->established_peers
== 0) {
323 if (BGP_DEBUG(zebra
, ZEBRA
))
324 zlog_debug("RID change : vrf %u, RTR ID %s",
325 bgp
->vrf_id
, inet_ntoa(*addr
));
326 bgp_router_id_set(bgp
, addr
, FALSE
);
334 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
336 bgp
->router_id_static
= id
;
337 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
,
338 TRUE
/* is config */);
342 /* BGP's cluster-id control. */
343 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
346 struct listnode
*node
, *nnode
;
348 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
349 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
352 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
353 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
355 /* Clear all IBGP peer. */
356 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
357 if (peer
->sort
!= BGP_PEER_IBGP
)
360 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
361 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
362 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
363 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
369 int bgp_cluster_id_unset(struct bgp
*bgp
)
372 struct listnode
*node
, *nnode
;
374 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
377 bgp
->cluster_id
.s_addr
= 0;
378 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
380 /* Clear all IBGP peer. */
381 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
382 if (peer
->sort
!= BGP_PEER_IBGP
)
385 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
386 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
387 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
388 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
394 /* time_t value that is monotonicly increasing
395 * and uneffected by adjustments to system clock
397 time_t bgp_clock(void)
405 /* BGP timer configuration. */
406 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
408 bgp
->default_keepalive
=
409 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
410 bgp
->default_holdtime
= holdtime
;
415 int bgp_timers_unset(struct bgp
*bgp
)
417 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
418 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
423 /* BGP confederation configuration. */
424 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
427 struct listnode
*node
, *nnode
;
431 return BGP_ERR_INVALID_AS
;
433 /* Remember - were we doing confederation before? */
434 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
436 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
438 /* If we were doing confederation already, this is just an external
439 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
440 were not doing confederation before, reset all EBGP sessions. */
441 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
442 /* We're looking for peers who's AS is not local or part of our
444 if (already_confed
) {
445 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
447 if (BGP_IS_VALID_STATE_FOR_NOTIF(
450 PEER_DOWN_CONFED_ID_CHANGE
;
452 peer
, BGP_NOTIFY_CEASE
,
453 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
455 bgp_session_reset_safe(peer
, &nnode
);
458 /* Not doign confederation before, so reset every
461 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
462 /* Reset the local_as to be our EBGP one */
463 if (peer_sort(peer
) == BGP_PEER_EBGP
)
465 if (BGP_IS_VALID_STATE_FOR_NOTIF(
468 PEER_DOWN_CONFED_ID_CHANGE
;
470 peer
, BGP_NOTIFY_CEASE
,
471 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
473 bgp_session_reset_safe(peer
, &nnode
);
480 int bgp_confederation_id_unset(struct bgp
*bgp
)
483 struct listnode
*node
, *nnode
;
486 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
488 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
489 /* We're looking for peers who's AS is not local */
490 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
491 peer
->local_as
= bgp
->as
;
492 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
493 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
494 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
495 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
499 bgp_session_reset_safe(peer
, &nnode
);
505 /* Is an AS part of the confed or not? */
506 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
513 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
514 if (bgp
->confed_peers
[i
] == as
)
520 /* Add an AS to the confederation set. */
521 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
524 struct listnode
*node
, *nnode
;
527 return BGP_ERR_INVALID_BGP
;
530 return BGP_ERR_INVALID_AS
;
532 if (bgp_confederation_peers_check(bgp
, as
))
535 if (bgp
->confed_peers
)
537 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
538 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
541 XMALLOC(MTYPE_BGP_CONFED_LIST
,
542 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
544 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
545 bgp
->confed_peers_cnt
++;
547 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
548 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
549 if (peer
->as
== as
) {
550 peer
->local_as
= bgp
->as
;
551 if (BGP_IS_VALID_STATE_FOR_NOTIF(
554 PEER_DOWN_CONFED_PEER_CHANGE
;
556 peer
, BGP_NOTIFY_CEASE
,
557 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
559 bgp_session_reset_safe(peer
, &nnode
);
566 /* Delete an AS from the confederation set. */
567 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
572 struct listnode
*node
, *nnode
;
577 if (!bgp_confederation_peers_check(bgp
, as
))
580 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
581 if (bgp
->confed_peers
[i
] == as
)
582 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
583 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
585 bgp
->confed_peers_cnt
--;
587 if (bgp
->confed_peers_cnt
== 0) {
588 if (bgp
->confed_peers
)
589 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
590 bgp
->confed_peers
= NULL
;
593 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
594 bgp
->confed_peers_cnt
* sizeof(as_t
));
596 /* Now reset any peer who's remote AS has just been removed from the
598 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
599 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
600 if (peer
->as
== as
) {
601 peer
->local_as
= bgp
->confed_id
;
602 if (BGP_IS_VALID_STATE_FOR_NOTIF(
605 PEER_DOWN_CONFED_PEER_CHANGE
;
607 peer
, BGP_NOTIFY_CEASE
,
608 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
610 bgp_session_reset_safe(peer
, &nnode
);
618 /* Local preference configuration. */
619 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
624 bgp
->default_local_pref
= local_pref
;
629 int bgp_default_local_preference_unset(struct bgp
*bgp
)
634 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
639 /* Local preference configuration. */
640 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
645 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
650 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
654 bgp
->default_subgroup_pkt_queue_max
=
655 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
660 /* Listen limit configuration. */
661 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
666 bgp
->dynamic_neighbors_limit
= listen_limit
;
671 int bgp_listen_limit_unset(struct bgp
*bgp
)
676 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
681 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
682 afi_t
*afi
, safi_t
*safi
)
684 /* Map from IANA values to internal values, return error if
685 * values are unrecognized.
687 *afi
= afi_iana2int(pkt_afi
);
688 *safi
= safi_iana2int(pkt_safi
);
689 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
695 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
696 iana_safi_t
*pkt_safi
)
698 /* Map from internal values to IANA values, return error if
699 * internal values are bad (unexpected).
701 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
703 *pkt_afi
= afi_int2iana(afi
);
704 *pkt_safi
= safi_int2iana(safi
);
708 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
717 afid
= afindex(afi
, safi
);
718 if (afid
>= BGP_AF_MAX
)
722 assert(peer
->peer_af_array
[afid
] == NULL
);
724 /* Allocate new peer af */
725 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
727 peer
->peer_af_array
[afid
] = af
;
732 bgp
->af_peer_count
[afi
][safi
]++;
737 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
744 afid
= afindex(afi
, safi
);
745 if (afid
>= BGP_AF_MAX
)
748 return peer
->peer_af_array
[afid
];
751 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
760 afid
= afindex(afi
, safi
);
761 if (afid
>= BGP_AF_MAX
)
764 af
= peer
->peer_af_array
[afid
];
769 bgp_stop_announce_route_timer(af
);
771 if (PAF_SUBGRP(af
)) {
772 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
773 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
774 af
->subgroup
->update_group
->id
,
775 af
->subgroup
->id
, peer
->host
);
779 update_subgroup_remove_peer(af
->subgroup
, af
);
781 if (bgp
->af_peer_count
[afi
][safi
])
782 bgp
->af_peer_count
[afi
][safi
]--;
784 peer
->peer_af_array
[afid
] = NULL
;
785 XFREE(MTYPE_BGP_PEER_AF
, af
);
789 /* Peer comparison function for sorting. */
790 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
792 if (p1
->group
&& !p2
->group
)
795 if (!p1
->group
&& p2
->group
)
798 if (p1
->group
== p2
->group
) {
799 if (p1
->conf_if
&& !p2
->conf_if
)
802 if (!p1
->conf_if
&& p2
->conf_if
)
805 if (p1
->conf_if
&& p2
->conf_if
)
806 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
808 return strcmp(p1
->group
->name
, p2
->group
->name
);
810 return sockunion_cmp(&p1
->su
, &p2
->su
);
813 static unsigned int peer_hash_key_make(const void *p
)
815 const struct peer
*peer
= p
;
816 return sockunion_hash(&peer
->su
);
819 static bool peer_hash_same(const void *p1
, const void *p2
)
821 const struct peer
*peer1
= p1
;
822 const struct peer
*peer2
= p2
;
823 return (sockunion_same(&peer1
->su
, &peer2
->su
)
824 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
825 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
828 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
832 /* Skip if peer is not a peer-group member. */
833 if (!peer_group_active(peer
))
836 /* Unset override flag to signal inheritance from peer-group. */
837 UNSET_FLAG(peer
->flags_override
, flag
);
840 * Inherit flag state from peer-group. If the flag of the peer-group is
841 * not being inverted, the peer must inherit the inverse of the current
842 * peer-group flag state.
844 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
845 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
846 && CHECK_FLAG(peer
->flags_invert
, flag
))
847 COND_FLAG(peer
->flags
, flag
, !group_val
);
849 COND_FLAG(peer
->flags
, flag
, group_val
);
852 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
854 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
857 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
862 /* Skip if peer is not a peer-group member. */
863 if (!peer_group_active(peer
))
866 /* Unset override flag to signal inheritance from peer-group. */
867 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
870 * Inherit flag state from peer-group. If the flag of the peer-group is
871 * not being inverted, the peer must inherit the inverse of the current
872 * peer-group flag state.
874 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
875 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
876 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
877 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
879 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
882 static bool peergroup_flag_check(struct peer
*peer
, uint32_t flag
)
884 if (!peer_group_active(peer
)) {
885 if (CHECK_FLAG(peer
->flags_invert
, flag
))
886 return !CHECK_FLAG(peer
->flags
, flag
);
888 return !!CHECK_FLAG(peer
->flags
, flag
);
891 return !!CHECK_FLAG(peer
->flags_override
, flag
);
894 static bool peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
897 if (!peer_group_active(peer
)) {
898 if (CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
899 return !peer_af_flag_check(peer
, afi
, safi
, flag
);
901 return !!peer_af_flag_check(peer
, afi
, safi
, flag
);
904 return !!CHECK_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
907 static bool peergroup_filter_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
908 uint8_t type
, int direct
)
910 struct bgp_filter
*filter
;
912 if (peer_group_active(peer
))
913 return !!CHECK_FLAG(peer
->filter_override
[afi
][safi
][direct
],
916 filter
= &peer
->filter
[afi
][safi
];
918 case PEER_FT_DISTRIBUTE_LIST
:
919 return !!(filter
->dlist
[direct
].name
);
920 case PEER_FT_FILTER_LIST
:
921 return !!(filter
->aslist
[direct
].name
);
922 case PEER_FT_PREFIX_LIST
:
923 return !!(filter
->plist
[direct
].name
);
924 case PEER_FT_ROUTE_MAP
:
925 return !!(filter
->map
[direct
].name
);
926 case PEER_FT_UNSUPPRESS_MAP
:
927 return !!(filter
->usmap
.name
);
933 /* Return true if the addpath type is set for peer and different from
936 static int peergroup_af_addpath_check(struct peer
*peer
, afi_t afi
, safi_t safi
)
938 enum bgp_addpath_strat type
, g_type
;
940 type
= peer
->addpath_type
[afi
][safi
];
942 if (type
!= BGP_ADDPATH_NONE
) {
943 if (peer_group_active(peer
)) {
944 g_type
= peer
->group
->conf
->addpath_type
[afi
][safi
];
958 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
959 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
966 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
967 if (peer
->as_type
== AS_INTERNAL
)
968 return BGP_PEER_IBGP
;
970 else if (peer
->as_type
== AS_EXTERNAL
)
971 return BGP_PEER_EBGP
;
973 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
975 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
983 peer1
= listnode_head(peer
->group
->peer
);
988 return BGP_PEER_INTERNAL
;
992 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
993 if (peer
->local_as
== 0)
994 return BGP_PEER_INTERNAL
;
996 if (peer
->local_as
== peer
->as
) {
997 if (bgp
->as
== bgp
->confed_id
) {
998 if (peer
->local_as
== bgp
->as
)
999 return BGP_PEER_IBGP
;
1001 return BGP_PEER_EBGP
;
1003 if (peer
->local_as
== bgp
->confed_id
)
1004 return BGP_PEER_EBGP
;
1006 return BGP_PEER_IBGP
;
1010 if (bgp_confederation_peers_check(bgp
, peer
->as
))
1011 return BGP_PEER_CONFED
;
1013 return BGP_PEER_EBGP
;
1015 if (peer
->as_type
== AS_UNSPECIFIED
) {
1016 /* check if in peer-group with AS information */
1018 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
1019 if (peer
->group
->conf
->as_type
1022 == peer
->group
->conf
->as
)
1023 return BGP_PEER_IBGP
;
1025 return BGP_PEER_EBGP
;
1026 } else if (peer
->group
->conf
->as_type
1028 return BGP_PEER_IBGP
;
1030 return BGP_PEER_EBGP
;
1032 /* no AS information anywhere, let caller know */
1033 return BGP_PEER_UNSPECIFIED
;
1034 } else if (peer
->as_type
!= AS_SPECIFIED
)
1035 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1038 return (peer
->local_as
== 0
1040 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1045 /* Calculate and cache the peer "sort" */
1046 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1048 peer
->sort
= peer_calc_sort(peer
);
1052 static void peer_free(struct peer
*peer
)
1057 assert(peer
->status
== Deleted
);
1061 /* this /ought/ to have been done already through bgp_stop earlier,
1062 * but just to be sure..
1064 bgp_timer_set(peer
);
1065 bgp_reads_off(peer
);
1066 bgp_writes_off(peer
);
1067 assert(!peer
->t_write
);
1068 assert(!peer
->t_read
);
1069 BGP_EVENT_FLUSH(peer
);
1071 pthread_mutex_destroy(&peer
->io_mtx
);
1073 /* Free connected nexthop, if present */
1074 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1075 && !peer_dynamic_neighbor(peer
))
1076 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1079 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1082 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1086 /* Free allocated host character. */
1088 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1092 if (peer
->domainname
) {
1093 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1094 peer
->domainname
= NULL
;
1098 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1099 peer
->ifname
= NULL
;
1102 /* Update source configuration. */
1103 if (peer
->update_source
) {
1104 sockunion_free(peer
->update_source
);
1105 peer
->update_source
= NULL
;
1108 if (peer
->update_if
) {
1109 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1110 peer
->update_if
= NULL
;
1113 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1114 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1116 if (peer
->clear_node_queue
)
1117 work_queue_free_and_null(&peer
->clear_node_queue
);
1119 bgp_sync_delete(peer
);
1121 if (peer
->conf_if
) {
1122 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1123 peer
->conf_if
= NULL
;
1126 bfd_info_free(&(peer
->bfd_info
));
1128 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1129 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1130 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1135 bgp_unlock(peer
->bgp
);
1137 memset(peer
, 0, sizeof(struct peer
));
1139 XFREE(MTYPE_BGP_PEER
, peer
);
1142 /* increase reference count on a struct peer */
1143 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1145 assert(peer
&& (peer
->lock
>= 0));
1148 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1156 /* decrease reference count on a struct peer
1157 * struct peer is freed and NULL returned if last reference
1159 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1161 assert(peer
&& (peer
->lock
> 0));
1164 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1169 if (peer
->lock
== 0) {
1177 /* Allocate new peer object, implicitely locked. */
1178 struct peer
*peer_new(struct bgp
*bgp
)
1185 /* bgp argument is absolutely required */
1190 /* Allocate new peer. */
1191 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1193 /* Set default value. */
1195 peer
->v_start
= BGP_INIT_START_TIMER
;
1196 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1197 peer
->status
= Idle
;
1198 peer
->ostatus
= Idle
;
1199 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1200 peer
->bgp
= bgp_lock(bgp
);
1201 peer
= peer_lock(peer
); /* initial reference */
1202 peer
->password
= NULL
;
1204 /* Set default flags. */
1205 FOREACH_AFI_SAFI (afi
, safi
) {
1206 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
1207 SET_FLAG(peer
->af_flags
[afi
][safi
],
1208 PEER_FLAG_SEND_EXT_COMMUNITY
);
1209 SET_FLAG(peer
->af_flags
[afi
][safi
],
1210 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1212 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1213 PEER_FLAG_SEND_COMMUNITY
);
1214 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1215 PEER_FLAG_SEND_EXT_COMMUNITY
);
1216 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1217 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1218 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1221 /* set nexthop-unchanged for l2vpn evpn by default */
1222 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1223 PEER_FLAG_NEXTHOP_UNCHANGED
);
1225 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1227 /* Create buffers. */
1228 peer
->ibuf
= stream_fifo_new();
1229 peer
->obuf
= stream_fifo_new();
1230 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1232 /* We use a larger buffer for peer->obuf_work in the event that:
1233 * - We RX a BGP_UPDATE where the attributes alone are just
1234 * under BGP_MAX_PACKET_SIZE
1235 * - The user configures an outbound route-map that does many as-path
1236 * prepends or adds many communities. At most they can have
1237 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1238 * large they can make the attributes.
1240 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1241 * bounds checking for every single attribute as we construct an
1245 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1247 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1249 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1251 bgp_sync_init(peer
);
1253 /* Get service port number. */
1254 sp
= getservbyname("bgp", "tcp");
1255 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1257 QOBJ_REG(peer
, peer
);
1262 * This function is invoked when a duplicate peer structure associated with
1263 * a neighbor is being deleted. If this about-to-be-deleted structure is
1264 * the one with all the config, then we have to copy over the info.
1266 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1268 struct peer_af
*paf
;
1276 /* The following function is used by both peer group config copy to
1277 * individual peer and when we transfer config
1279 if (peer_src
->change_local_as
)
1280 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1282 /* peer flags apply */
1283 peer_dst
->flags
= peer_src
->flags
;
1284 peer_dst
->cap
= peer_src
->cap
;
1286 peer_dst
->local_as
= peer_src
->local_as
;
1287 peer_dst
->port
= peer_src
->port
;
1288 (void)peer_sort(peer_dst
);
1289 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1292 peer_dst
->holdtime
= peer_src
->holdtime
;
1293 peer_dst
->keepalive
= peer_src
->keepalive
;
1294 peer_dst
->connect
= peer_src
->connect
;
1295 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1296 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1297 peer_dst
->routeadv
= peer_src
->routeadv
;
1298 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1300 /* password apply */
1301 if (peer_src
->password
&& !peer_dst
->password
)
1302 peer_dst
->password
=
1303 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1305 FOREACH_AFI_SAFI (afi
, safi
) {
1306 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1307 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1308 peer_dst
->allowas_in
[afi
][safi
] =
1309 peer_src
->allowas_in
[afi
][safi
];
1310 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1311 peer_dst
->addpath_type
[afi
][safi
] =
1312 peer_src
->addpath_type
[afi
][safi
];
1315 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1316 paf
= peer_src
->peer_af_array
[afidx
];
1318 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1321 /* update-source apply */
1322 if (peer_src
->update_source
) {
1323 if (peer_dst
->update_source
)
1324 sockunion_free(peer_dst
->update_source
);
1325 if (peer_dst
->update_if
) {
1326 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1327 peer_dst
->update_if
= NULL
;
1329 peer_dst
->update_source
=
1330 sockunion_dup(peer_src
->update_source
);
1331 } else if (peer_src
->update_if
) {
1332 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1333 if (peer_dst
->update_source
) {
1334 sockunion_free(peer_dst
->update_source
);
1335 peer_dst
->update_source
= NULL
;
1337 peer_dst
->update_if
=
1338 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1341 if (peer_src
->ifname
) {
1342 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1345 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1349 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1350 struct interface
*ifp
)
1352 struct connected
*ifc
;
1355 struct listnode
*node
;
1357 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1358 * IPv4 address of the other end.
1360 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1361 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1362 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1363 if (p
.prefixlen
== 30) {
1364 peer
->su
.sa
.sa_family
= AF_INET
;
1365 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1367 peer
->su
.sin
.sin_addr
.s_addr
=
1369 else if (addr
% 4 == 2)
1370 peer
->su
.sin
.sin_addr
.s_addr
=
1372 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1373 peer
->su
.sin
.sin_len
=
1374 sizeof(struct sockaddr_in
);
1375 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1377 } else if (p
.prefixlen
== 31) {
1378 peer
->su
.sa
.sa_family
= AF_INET
;
1379 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1381 peer
->su
.sin
.sin_addr
.s_addr
=
1384 peer
->su
.sin
.sin_addr
.s_addr
=
1386 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1387 peer
->su
.sin
.sin_len
=
1388 sizeof(struct sockaddr_in
);
1389 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1391 } else if (bgp_debug_neighbor_events(peer
))
1393 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1401 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1402 struct interface
*ifp
)
1404 struct nbr_connected
*ifc_nbr
;
1406 /* Have we learnt the peer's IPv6 link-local address? */
1407 if (ifp
->nbr_connected
1408 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1409 peer
->su
.sa
.sa_family
= AF_INET6
;
1410 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1411 sizeof(struct in6_addr
));
1413 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1415 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1423 * Set or reset the peer address socketunion structure based on the
1424 * learnt/derived peer address. If the address has changed, update the
1425 * password on the listen socket, if needed.
1427 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1429 struct interface
*ifp
;
1431 int peer_addr_updated
= 0;
1437 * Our peer structure is stored in the bgp->peerhash
1438 * release it before we modify anything.
1440 hash_release(peer
->bgp
->peerhash
, peer
);
1442 prev_family
= peer
->su
.sa
.sa_family
;
1443 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1445 /* If BGP unnumbered is not "v6only", we first see if we can
1447 * peer's IPv4 address.
1449 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1451 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1453 /* If "v6only" or we can't derive peer's IPv4 address, see if
1455 * learnt the peer's IPv6 link-local address. This is from the
1457 * IPv6 address in router advertisement.
1459 if (!peer_addr_updated
)
1461 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1463 /* If we could derive the peer address, we may need to install the
1465 * configured for the peer, if any, on the listen socket. Otherwise,
1467 * that peer's address is not available and uninstall the password, if
1470 if (peer_addr_updated
) {
1471 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1472 && prev_family
== AF_UNSPEC
)
1475 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1476 && prev_family
!= AF_UNSPEC
)
1477 bgp_md5_unset(peer
);
1478 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1479 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1483 * Since our su changed we need to del/add peer to the peerhash
1485 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1488 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1491 struct bgp_node
*rn
, *nrn
;
1492 struct bgp_table
*table
;
1494 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1495 rn
= bgp_route_next(rn
)) {
1496 table
= bgp_node_get_bgp_table_info(rn
);
1497 if (table
!= NULL
) {
1498 /* Special handling for 2-level routing
1500 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1501 || safi
== SAFI_EVPN
) {
1502 for (nrn
= bgp_table_top(table
);
1503 nrn
; nrn
= bgp_route_next(nrn
))
1504 bgp_process(bgp
, nrn
, afi
, safi
);
1506 bgp_process(bgp
, rn
, afi
, safi
);
1511 /* Force a bestpath recalculation for all prefixes. This is used
1512 * when 'bgp bestpath' commands are entered.
1514 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1519 FOREACH_AFI_SAFI (afi
, safi
) {
1520 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1525 * Create new BGP peer.
1527 * conf_if and su are mutually exclusive if configuring from the cli.
1528 * If we are handing a doppelganger, then we *must* pass in both
1529 * the original peer's su and conf_if, so that we can appropriately
1530 * track the bgp->peerhash( ie we don't want to remove the current
1531 * one from the config ).
1533 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1534 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1535 int as_type
, afi_t afi
, safi_t safi
,
1536 struct peer_group
*group
)
1540 char buf
[SU_ADDRSTRLEN
];
1542 peer
= peer_new(bgp
);
1544 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1548 bgp_peer_conf_if_to_su_update(peer
);
1549 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1550 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1553 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1554 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1555 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1557 peer
->local_as
= local_as
;
1558 peer
->as
= remote_as
;
1559 peer
->as_type
= as_type
;
1560 peer
->local_id
= bgp
->router_id
;
1561 peer
->v_holdtime
= bgp
->default_holdtime
;
1562 peer
->v_keepalive
= bgp
->default_keepalive
;
1563 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1564 ? BGP_DEFAULT_IBGP_ROUTEADV
1565 : BGP_DEFAULT_EBGP_ROUTEADV
;
1567 peer
= peer_lock(peer
); /* bgp peer list reference */
1568 peer
->group
= group
;
1569 listnode_add_sort(bgp
->peer
, peer
);
1570 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1572 /* Adjust update-group coalesce timer heuristics for # peers. */
1573 if (bgp
->heuristic_coalesce
) {
1574 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1576 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1577 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1580 active
= peer_active(peer
);
1582 /* Last read and reset time set */
1583 peer
->readtime
= peer
->resettime
= bgp_clock();
1585 /* Default TTL set. */
1586 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1588 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1591 peer
->afc
[afi
][safi
] = 1;
1592 peer_af_create(peer
, afi
, safi
);
1595 /* auto shutdown if configured */
1596 if (bgp
->autoshutdown
)
1597 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1598 /* Set up peer's events and timers. */
1599 else if (!active
&& peer_active(peer
))
1600 bgp_timer_set(peer
);
1605 /* Make accept BGP peer. This function is only called from the test code */
1606 struct peer
*peer_create_accept(struct bgp
*bgp
)
1610 peer
= peer_new(bgp
);
1612 peer
= peer_lock(peer
); /* bgp peer list reference */
1613 listnode_add_sort(bgp
->peer
, peer
);
1619 * Return true if we have a peer configured to use this afi/safi
1621 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1623 struct listnode
*node
;
1626 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1627 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1630 if (peer
->afc
[afi
][safi
])
1637 /* Change peer's AS number. */
1638 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1640 bgp_peer_sort_t type
;
1643 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1644 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1645 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1646 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1647 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1649 bgp_session_reset(peer
);
1651 type
= peer_sort(peer
);
1653 peer
->as_type
= as_specified
;
1655 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1656 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1657 && peer
->bgp
->as
!= as
)
1658 peer
->local_as
= peer
->bgp
->confed_id
;
1660 peer
->local_as
= peer
->bgp
->as
;
1662 /* Advertisement-interval reset */
1663 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1664 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1665 ? BGP_DEFAULT_IBGP_ROUTEADV
1666 : BGP_DEFAULT_EBGP_ROUTEADV
;
1670 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1672 else if (type
== BGP_PEER_IBGP
)
1675 /* reflector-client reset */
1676 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1677 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1678 PEER_FLAG_REFLECTOR_CLIENT
);
1679 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1680 PEER_FLAG_REFLECTOR_CLIENT
);
1681 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1682 PEER_FLAG_REFLECTOR_CLIENT
);
1683 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1684 PEER_FLAG_REFLECTOR_CLIENT
);
1685 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1686 PEER_FLAG_REFLECTOR_CLIENT
);
1687 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1688 PEER_FLAG_REFLECTOR_CLIENT
);
1689 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1690 PEER_FLAG_REFLECTOR_CLIENT
);
1691 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1692 PEER_FLAG_REFLECTOR_CLIENT
);
1693 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1694 PEER_FLAG_REFLECTOR_CLIENT
);
1695 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1696 PEER_FLAG_REFLECTOR_CLIENT
);
1697 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1698 PEER_FLAG_REFLECTOR_CLIENT
);
1699 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1700 PEER_FLAG_REFLECTOR_CLIENT
);
1701 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1702 PEER_FLAG_REFLECTOR_CLIENT
);
1705 /* local-as reset */
1706 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1707 peer
->change_local_as
= 0;
1708 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1709 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1710 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1714 /* If peer does not exist, create new one. If peer already exists,
1715 set AS number to the peer. */
1716 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1717 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1723 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1725 peer
= peer_lookup(bgp
, su
);
1728 /* Not allowed for a dynamic peer. */
1729 if (peer_dynamic_neighbor(peer
)) {
1731 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1734 /* When this peer is a member of peer-group. */
1736 /* peer-group already has AS number/internal/external */
1737 if (peer
->group
->conf
->as
1738 || peer
->group
->conf
->as_type
) {
1739 /* Return peer group's AS number. */
1740 *as
= peer
->group
->conf
->as
;
1741 return BGP_ERR_PEER_GROUP_MEMBER
;
1744 bgp_peer_sort_t peer_sort_type
=
1745 peer_sort(peer
->group
->conf
);
1747 /* Explicit AS numbers used, compare AS numbers */
1748 if (as_type
== AS_SPECIFIED
) {
1749 if (((peer_sort_type
== BGP_PEER_IBGP
)
1750 && (bgp
->as
!= *as
))
1751 || ((peer_sort_type
== BGP_PEER_EBGP
)
1752 && (bgp
->as
== *as
))) {
1754 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1757 /* internal/external used, compare as-types */
1758 if (((peer_sort_type
== BGP_PEER_IBGP
)
1759 && (as_type
!= AS_INTERNAL
))
1760 || ((peer_sort_type
== BGP_PEER_EBGP
)
1761 && (as_type
!= AS_EXTERNAL
))) {
1763 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1768 /* Existing peer's AS number change. */
1769 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1770 || (peer
->as_type
!= as_type
))
1771 peer_as_change(peer
, *as
, as_type
);
1774 return BGP_ERR_NO_INTERFACE_CONFIG
;
1776 /* If the peer is not part of our confederation, and its not an
1777 iBGP peer then spoof the source AS */
1778 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1779 && !bgp_confederation_peers_check(bgp
, *as
)
1781 local_as
= bgp
->confed_id
;
1785 /* If this is IPv4 unicast configuration and "no bgp default
1786 ipv4-unicast" is specified. */
1788 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1789 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1790 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1793 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1800 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1801 struct peer
*peer
, afi_t afi
,
1805 int out
= FILTER_OUT
;
1807 uint32_t pflags_ovrd
;
1808 uint8_t *pfilter_ovrd
;
1812 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1813 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1815 /* peer af_flags apply */
1816 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1817 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1818 ^ peer
->af_flags_invert
[afi
][safi
];
1819 flags_tmp
&= ~pflags_ovrd
;
1821 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1822 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1823 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1824 conf
->af_flags_invert
[afi
][safi
]);
1826 /* maximum-prefix */
1827 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1828 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1829 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1830 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1834 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1835 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1838 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1839 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1841 /* default-originate route-map */
1842 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1843 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1844 MTYPE_ROUTE_MAP_NAME
);
1845 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1848 /* inbound filter apply */
1849 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1850 PEER_STR_ATTR_INHERIT(peer
, group
,
1851 filter
[afi
][safi
].dlist
[in
].name
,
1852 MTYPE_BGP_FILTER_NAME
);
1853 PEER_ATTR_INHERIT(peer
, group
,
1854 filter
[afi
][safi
].dlist
[in
].alist
);
1857 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1858 PEER_STR_ATTR_INHERIT(peer
, group
,
1859 filter
[afi
][safi
].plist
[in
].name
,
1860 MTYPE_BGP_FILTER_NAME
);
1861 PEER_ATTR_INHERIT(peer
, group
,
1862 filter
[afi
][safi
].plist
[in
].plist
);
1865 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1866 PEER_STR_ATTR_INHERIT(peer
, group
,
1867 filter
[afi
][safi
].aslist
[in
].name
,
1868 MTYPE_BGP_FILTER_NAME
);
1869 PEER_ATTR_INHERIT(peer
, group
,
1870 filter
[afi
][safi
].aslist
[in
].aslist
);
1873 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1874 PEER_STR_ATTR_INHERIT(peer
, group
,
1875 filter
[afi
][safi
].map
[in
].name
,
1876 MTYPE_BGP_FILTER_NAME
);
1877 PEER_ATTR_INHERIT(peer
, group
,
1878 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1881 /* outbound filter apply */
1882 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1883 PEER_STR_ATTR_INHERIT(peer
, group
,
1884 filter
[afi
][safi
].dlist
[out
].name
,
1885 MTYPE_BGP_FILTER_NAME
);
1886 PEER_ATTR_INHERIT(peer
, group
,
1887 filter
[afi
][safi
].dlist
[out
].alist
);
1890 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1891 PEER_STR_ATTR_INHERIT(peer
, group
,
1892 filter
[afi
][safi
].plist
[out
].name
,
1893 MTYPE_BGP_FILTER_NAME
);
1894 PEER_ATTR_INHERIT(peer
, group
,
1895 filter
[afi
][safi
].plist
[out
].plist
);
1898 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1899 PEER_STR_ATTR_INHERIT(peer
, group
,
1900 filter
[afi
][safi
].aslist
[out
].name
,
1901 MTYPE_BGP_FILTER_NAME
);
1902 PEER_ATTR_INHERIT(peer
, group
,
1903 filter
[afi
][safi
].aslist
[out
].aslist
);
1906 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1907 PEER_STR_ATTR_INHERIT(peer
, group
,
1908 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1909 MTYPE_BGP_FILTER_NAME
);
1910 PEER_ATTR_INHERIT(peer
, group
,
1911 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1914 /* nondirectional filter apply */
1915 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1916 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1917 MTYPE_BGP_FILTER_NAME
);
1918 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1921 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1922 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1923 bgp_addpath_type_changed(conf
->bgp
);
1927 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1932 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1933 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1934 __func__
, peer
->host
);
1938 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1940 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1941 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1942 return BGP_ERR_PEER_SAFI_CONFLICT
;
1944 /* Nothing to do if we've already activated this peer */
1945 if (peer
->afc
[afi
][safi
])
1948 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1951 active
= peer_active(peer
);
1952 peer
->afc
[afi
][safi
] = 1;
1955 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1957 if (!active
&& peer_active(peer
)) {
1958 bgp_timer_set(peer
);
1960 if (peer
->status
== Established
) {
1961 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1962 peer
->afc_adv
[afi
][safi
] = 1;
1963 bgp_capability_send(peer
, afi
, safi
,
1965 CAPABILITY_ACTION_SET
);
1966 if (peer
->afc_recv
[afi
][safi
]) {
1967 peer
->afc_nego
[afi
][safi
] = 1;
1968 bgp_announce_route(peer
, afi
, safi
);
1971 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1972 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1973 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1976 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1977 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1978 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1979 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1982 * If we are turning on a AFI/SAFI locally and we've
1983 * started bringing a peer up, we need to tell
1984 * the other peer to restart because we might loose
1985 * configuration here because when the doppelganger
1986 * gets to a established state due to how
1987 * we resolve we could just overwrite the afi/safi
1990 other
= peer
->doppelganger
;
1992 && (other
->status
== OpenSent
1993 || other
->status
== OpenConfirm
)) {
1994 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1995 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1996 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2003 /* Activate the peer or peer group for specified AFI and SAFI. */
2004 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2007 struct peer_group
*group
;
2008 struct listnode
*node
, *nnode
;
2009 struct peer
*tmp_peer
;
2012 /* Nothing to do if we've already activated this peer */
2013 if (peer
->afc
[afi
][safi
])
2018 /* This is a peer-group so activate all of the members of the
2019 * peer-group as well */
2020 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2022 /* Do not activate a peer for both SAFI_UNICAST and
2023 * SAFI_LABELED_UNICAST */
2024 if ((safi
== SAFI_UNICAST
2025 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
2026 || (safi
== SAFI_LABELED_UNICAST
2027 && peer
->afc
[afi
][SAFI_UNICAST
]))
2028 return BGP_ERR_PEER_SAFI_CONFLICT
;
2030 peer
->afc
[afi
][safi
] = 1;
2031 group
= peer
->group
;
2033 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2034 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
2037 ret
|= peer_activate_af(peer
, afi
, safi
);
2040 /* If this is the first peer to be activated for this
2041 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2042 if (safi
== SAFI_LABELED_UNICAST
2043 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
2045 if (BGP_DEBUG(zebra
, ZEBRA
))
2047 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2049 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
2050 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2053 if (safi
== SAFI_FLOWSPEC
) {
2054 /* connect to table manager */
2055 bgp_zebra_init_tm_connect(bgp
);
2060 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
2063 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2064 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2065 __func__
, peer
->host
);
2069 /* Nothing to do if we've already deactivated this peer */
2070 if (!peer
->afc
[afi
][safi
])
2073 /* De-activate the address family configuration. */
2074 peer
->afc
[afi
][safi
] = 0;
2076 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2077 flog_err(EC_BGP_PEER_DELETE
,
2078 "couldn't delete af structure for peer %s",
2083 if (peer
->status
== Established
) {
2084 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2085 peer
->afc_adv
[afi
][safi
] = 0;
2086 peer
->afc_nego
[afi
][safi
] = 0;
2088 if (peer_active_nego(peer
)) {
2089 bgp_capability_send(peer
, afi
, safi
,
2091 CAPABILITY_ACTION_UNSET
);
2092 bgp_clear_route(peer
, afi
, safi
);
2093 peer
->pcount
[afi
][safi
] = 0;
2095 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2096 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2097 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2100 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2101 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2102 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2109 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2112 struct peer_group
*group
;
2113 struct peer
*tmp_peer
;
2114 struct listnode
*node
, *nnode
;
2117 /* Nothing to do if we've already de-activated this peer */
2118 if (!peer
->afc
[afi
][safi
])
2121 /* This is a peer-group so de-activate all of the members of the
2122 * peer-group as well */
2123 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2124 peer
->afc
[afi
][safi
] = 0;
2125 group
= peer
->group
;
2127 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2128 flog_err(EC_BGP_PEER_DELETE
,
2129 "couldn't delete af structure for peer %s",
2133 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2134 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2137 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2142 /* If this is the last peer to be deactivated for this
2143 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2144 if (safi
== SAFI_LABELED_UNICAST
2145 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2146 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2148 if (BGP_DEBUG(zebra
, ZEBRA
))
2150 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2152 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2153 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2158 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2161 return peer_activate(peer
, afi
, safi
);
2163 return peer_deactivate(peer
, afi
, safi
);
2166 static void peer_nsf_stop(struct peer
*peer
)
2171 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2172 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2174 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2175 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2176 peer
->nsf
[afi
][safi
] = 0;
2178 if (peer
->t_gr_restart
) {
2179 BGP_TIMER_OFF(peer
->t_gr_restart
);
2180 if (bgp_debug_neighbor_events(peer
))
2181 zlog_debug("%s graceful restart timer stopped",
2184 if (peer
->t_gr_stale
) {
2185 BGP_TIMER_OFF(peer
->t_gr_stale
);
2186 if (bgp_debug_neighbor_events(peer
))
2188 "%s graceful restart stalepath timer stopped",
2191 bgp_clear_route_all(peer
);
2194 /* Delete peer from confguration.
2196 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2197 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2199 * This function /should/ take care to be idempotent, to guard against
2200 * it being called multiple times through stray events that come in
2201 * that happen to result in this function being called again. That
2202 * said, getting here for a "Deleted" peer is a bug in the neighbour
2205 int peer_delete(struct peer
*peer
)
2211 struct bgp_filter
*filter
;
2212 struct listnode
*pn
;
2215 assert(peer
->status
!= Deleted
);
2218 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2220 bgp_reads_off(peer
);
2221 bgp_writes_off(peer
);
2222 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2223 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2225 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2226 peer_nsf_stop(peer
);
2228 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2230 bgp_bfd_deregister_peer(peer
);
2232 /* If this peer belongs to peer group, clear up the
2235 if (peer_dynamic_neighbor(peer
))
2236 peer_drop_dynamic_neighbor(peer
);
2238 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2240 peer
); /* group->peer list reference */
2241 list_delete_node(peer
->group
->peer
, pn
);
2246 /* Withdraw all information from routing table. We can not use
2247 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2248 * executed after peer structure is deleted.
2250 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2252 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2254 if (peer
->doppelganger
) {
2255 peer
->doppelganger
->doppelganger
= NULL
;
2256 peer
->doppelganger
= NULL
;
2259 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2260 bgp_fsm_change_status(peer
, Deleted
);
2262 /* Remove from NHT */
2263 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2264 bgp_unlink_nexthop_by_peer(peer
);
2266 /* Password configuration */
2267 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2268 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2270 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2271 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2272 bgp_md5_unset(peer
);
2275 bgp_timer_set(peer
); /* stops all timers for Deleted */
2277 /* Delete from all peer list. */
2278 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2279 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2280 peer_unlock(peer
); /* bgp peer list reference */
2281 list_delete_node(bgp
->peer
, pn
);
2282 hash_release(bgp
->peerhash
, peer
);
2287 stream_fifo_free(peer
->ibuf
);
2292 stream_fifo_free(peer
->obuf
);
2296 if (peer
->ibuf_work
) {
2297 ringbuf_del(peer
->ibuf_work
);
2298 peer
->ibuf_work
= NULL
;
2301 if (peer
->obuf_work
) {
2302 stream_free(peer
->obuf_work
);
2303 peer
->obuf_work
= NULL
;
2306 if (peer
->scratch
) {
2307 stream_free(peer
->scratch
);
2308 peer
->scratch
= NULL
;
2311 /* Local and remote addresses. */
2312 if (peer
->su_local
) {
2313 sockunion_free(peer
->su_local
);
2314 peer
->su_local
= NULL
;
2317 if (peer
->su_remote
) {
2318 sockunion_free(peer
->su_remote
);
2319 peer
->su_remote
= NULL
;
2322 /* Free filter related memory. */
2323 FOREACH_AFI_SAFI (afi
, safi
) {
2324 filter
= &peer
->filter
[afi
][safi
];
2326 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2327 if (filter
->dlist
[i
].name
) {
2328 XFREE(MTYPE_BGP_FILTER_NAME
,
2329 filter
->dlist
[i
].name
);
2330 filter
->dlist
[i
].name
= NULL
;
2333 if (filter
->plist
[i
].name
) {
2334 XFREE(MTYPE_BGP_FILTER_NAME
,
2335 filter
->plist
[i
].name
);
2336 filter
->plist
[i
].name
= NULL
;
2339 if (filter
->aslist
[i
].name
) {
2340 XFREE(MTYPE_BGP_FILTER_NAME
,
2341 filter
->aslist
[i
].name
);
2342 filter
->aslist
[i
].name
= NULL
;
2346 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2347 if (filter
->map
[i
].name
) {
2348 XFREE(MTYPE_BGP_FILTER_NAME
,
2349 filter
->map
[i
].name
);
2350 filter
->map
[i
].name
= NULL
;
2354 if (filter
->usmap
.name
) {
2355 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2356 filter
->usmap
.name
= NULL
;
2359 if (peer
->default_rmap
[afi
][safi
].name
) {
2360 XFREE(MTYPE_ROUTE_MAP_NAME
,
2361 peer
->default_rmap
[afi
][safi
].name
);
2362 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2366 FOREACH_AFI_SAFI (afi
, safi
)
2367 peer_af_delete(peer
, afi
, safi
);
2369 if (peer
->hostname
) {
2370 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2371 peer
->hostname
= NULL
;
2374 if (peer
->domainname
) {
2375 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2376 peer
->domainname
= NULL
;
2379 peer_unlock(peer
); /* initial reference */
2384 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2386 return strcmp(g1
->name
, g2
->name
);
2389 /* Peer group cofiguration. */
2390 static struct peer_group
*peer_group_new(void)
2392 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2395 static void peer_group_free(struct peer_group
*group
)
2397 XFREE(MTYPE_PEER_GROUP
, group
);
2400 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2402 struct peer_group
*group
;
2403 struct listnode
*node
, *nnode
;
2405 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2406 if (strcmp(group
->name
, name
) == 0)
2412 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2414 struct peer_group
*group
;
2417 group
= peer_group_lookup(bgp
, name
);
2421 group
= peer_group_new();
2423 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2424 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2425 group
->peer
= list_new();
2426 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2427 group
->listen_range
[afi
] = list_new();
2428 group
->conf
= peer_new(bgp
);
2429 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2430 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2431 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2432 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2433 group
->conf
->group
= group
;
2434 group
->conf
->as
= 0;
2435 group
->conf
->ttl
= 1;
2436 group
->conf
->gtsm_hops
= 0;
2437 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2438 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2439 listnode_add_sort(bgp
->group
, group
);
2444 static void peer_group2peer_config_copy(struct peer_group
*group
,
2454 peer
->as
= conf
->as
;
2457 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2458 peer
->change_local_as
= conf
->change_local_as
;
2461 peer
->ttl
= conf
->ttl
;
2464 peer
->gtsm_hops
= conf
->gtsm_hops
;
2466 /* peer flags apply */
2467 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2468 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2469 flags_tmp
&= ~peer
->flags_override
;
2471 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2472 SET_FLAG(peer
->flags
, flags_tmp
);
2473 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2475 /* peer timers apply */
2476 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2477 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2478 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2481 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2482 PEER_ATTR_INHERIT(peer
, group
, connect
);
2483 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2484 peer
->v_connect
= conf
->connect
;
2486 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2489 /* advertisement-interval apply */
2490 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2491 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2492 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2493 peer
->v_routeadv
= conf
->routeadv
;
2495 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2496 ? BGP_DEFAULT_IBGP_ROUTEADV
2497 : BGP_DEFAULT_EBGP_ROUTEADV
;
2500 /* password apply */
2501 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2502 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2503 MTYPE_PEER_PASSWORD
);
2505 if (!BGP_PEER_SU_UNSPEC(peer
))
2508 /* update-source apply */
2509 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2510 if (conf
->update_source
) {
2511 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2512 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2513 } else if (conf
->update_if
) {
2514 sockunion_free(peer
->update_source
);
2515 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2516 MTYPE_PEER_UPDATE_SOURCE
);
2520 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2523 /* Peer group's remote AS configuration. */
2524 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2527 struct peer_group
*group
;
2529 struct listnode
*node
, *nnode
;
2531 group
= peer_group_lookup(bgp
, group_name
);
2535 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2539 /* When we setup peer-group AS number all peer group member's AS
2540 number must be updated to same number. */
2541 peer_as_change(group
->conf
, *as
, as_type
);
2543 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2544 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2545 || (peer
->as_type
!= as_type
))
2546 peer_as_change(peer
, *as
, as_type
);
2552 int peer_group_delete(struct peer_group
*group
)
2556 struct prefix
*prefix
;
2558 struct listnode
*node
, *nnode
;
2563 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2564 other
= peer
->doppelganger
;
2566 if (other
&& other
->status
!= Deleted
) {
2567 other
->group
= NULL
;
2571 list_delete(&group
->peer
);
2573 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2574 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2576 prefix_free(prefix
);
2578 list_delete(&group
->listen_range
[afi
]);
2581 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2584 bfd_info_free(&(group
->conf
->bfd_info
));
2586 group
->conf
->group
= NULL
;
2587 peer_delete(group
->conf
);
2589 /* Delete from all peer_group list. */
2590 listnode_delete(bgp
->group
, group
);
2592 peer_group_free(group
);
2597 int peer_group_remote_as_delete(struct peer_group
*group
)
2599 struct peer
*peer
, *other
;
2600 struct listnode
*node
, *nnode
;
2602 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2603 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2606 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2607 other
= peer
->doppelganger
;
2611 if (other
&& other
->status
!= Deleted
) {
2612 other
->group
= NULL
;
2616 list_delete_all_node(group
->peer
);
2618 group
->conf
->as
= 0;
2619 group
->conf
->as_type
= AS_UNSPECIFIED
;
2624 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2626 struct prefix
*prefix
;
2627 struct listnode
*node
, *nnode
;
2630 afi
= family2afi(range
->family
);
2632 /* Group needs remote AS configured. */
2633 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2634 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2636 /* Ensure no duplicates. Currently we don't care about overlaps. */
2637 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2638 if (prefix_same(range
, prefix
))
2642 prefix
= prefix_new();
2643 prefix_copy(prefix
, range
);
2644 listnode_add(group
->listen_range
[afi
], prefix
);
2646 /* Update passwords for new ranges */
2647 if (group
->conf
->password
)
2648 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2653 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2655 struct prefix
*prefix
, prefix2
;
2656 struct listnode
*node
, *nnode
;
2659 char buf
[PREFIX2STR_BUFFER
];
2661 afi
= family2afi(range
->family
);
2663 /* Identify the listen range. */
2664 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2665 if (prefix_same(range
, prefix
))
2670 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2672 prefix2str(prefix
, buf
, sizeof(buf
));
2674 /* Dispose off any dynamic neighbors that exist due to this listen range
2676 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2677 if (!peer_dynamic_neighbor(peer
))
2680 sockunion2hostprefix(&peer
->su
, &prefix2
);
2681 if (prefix_match(prefix
, &prefix2
)) {
2682 if (bgp_debug_neighbor_events(peer
))
2684 "Deleting dynamic neighbor %s group %s upon "
2685 "delete of listen range %s",
2686 peer
->host
, group
->name
, buf
);
2691 /* Get rid of the listen range */
2692 listnode_delete(group
->listen_range
[afi
], prefix
);
2694 /* Remove passwords for deleted ranges */
2695 if (group
->conf
->password
)
2696 bgp_md5_unset_prefix(prefix
);
2701 /* Bind specified peer to peer group. */
2702 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2703 struct peer_group
*group
, as_t
*as
)
2705 int first_member
= 0;
2709 /* Lookup the peer. */
2711 peer
= peer_lookup(bgp
, su
);
2713 /* The peer exist, bind it to the peer-group */
2715 /* When the peer already belongs to a peer-group, check the
2717 if (peer_group_active(peer
)) {
2719 /* The peer is already bound to the peer-group,
2722 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2725 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2728 /* The peer has not specified a remote-as, inherit it from the
2730 if (peer
->as_type
== AS_UNSPECIFIED
) {
2731 peer
->as_type
= group
->conf
->as_type
;
2732 peer
->as
= group
->conf
->as
;
2733 peer
->sort
= group
->conf
->sort
;
2736 if (!group
->conf
->as
&& peer_sort(peer
)) {
2737 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2738 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2741 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2744 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2748 peer_group2peer_config_copy(group
, peer
);
2750 FOREACH_AFI_SAFI (afi
, safi
) {
2751 if (group
->conf
->afc
[afi
][safi
]) {
2752 peer
->afc
[afi
][safi
] = 1;
2754 if (peer_af_find(peer
, afi
, safi
)
2755 || peer_af_create(peer
, afi
, safi
)) {
2756 peer_group2peer_config_copy_af(
2757 group
, peer
, afi
, safi
);
2759 } else if (peer
->afc
[afi
][safi
])
2760 peer_deactivate(peer
, afi
, safi
);
2764 assert(group
&& peer
->group
== group
);
2766 listnode_delete(bgp
->peer
, peer
);
2768 peer
->group
= group
;
2769 listnode_add_sort(bgp
->peer
, peer
);
2771 peer
= peer_lock(peer
); /* group->peer list reference */
2772 listnode_add(group
->peer
, peer
);
2776 /* Advertisement-interval reset */
2777 if (!CHECK_FLAG(group
->conf
->flags
,
2778 PEER_FLAG_ROUTEADV
)) {
2779 group
->conf
->v_routeadv
=
2780 (peer_sort(group
->conf
)
2782 ? BGP_DEFAULT_IBGP_ROUTEADV
2783 : BGP_DEFAULT_EBGP_ROUTEADV
;
2786 /* ebgp-multihop reset */
2787 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2788 group
->conf
->ttl
= MAXTTL
;
2790 /* local-as reset */
2791 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2792 group
->conf
->change_local_as
= 0;
2793 peer_flag_unset(group
->conf
,
2794 PEER_FLAG_LOCAL_AS
);
2795 peer_flag_unset(group
->conf
,
2796 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2797 peer_flag_unset(group
->conf
,
2798 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2802 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2804 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2805 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2806 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2807 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2809 bgp_session_reset(peer
);
2813 /* Create a new peer. */
2815 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2816 && (!group
->conf
->as
)) {
2817 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2820 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2821 group
->conf
->as_type
, 0, 0, group
);
2823 peer
= peer_lock(peer
); /* group->peer list reference */
2824 listnode_add(group
->peer
, peer
);
2826 peer_group2peer_config_copy(group
, peer
);
2828 /* If the peer-group is active for this afi/safi then activate
2830 FOREACH_AFI_SAFI (afi
, safi
) {
2831 if (group
->conf
->afc
[afi
][safi
]) {
2832 peer
->afc
[afi
][safi
] = 1;
2833 peer_af_create(peer
, afi
, safi
);
2834 peer_group2peer_config_copy_af(group
, peer
, afi
,
2836 } else if (peer
->afc
[afi
][safi
])
2837 peer_deactivate(peer
, afi
, safi
);
2840 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2842 /* Set up peer's events and timers. */
2843 if (peer_active(peer
))
2844 bgp_timer_set(peer
);
2850 static int bgp_startup_timer_expire(struct thread
*thread
)
2854 bgp
= THREAD_ARG(thread
);
2855 bgp
->t_startup
= NULL
;
2861 * On shutdown we call the cleanup function which
2862 * does a free of the link list nodes, free up
2863 * the data we are pointing at too.
2865 static void bgp_vrf_string_name_delete(void *data
)
2869 XFREE(MTYPE_TMP
, vname
);
2872 /* BGP instance creation by `router bgp' commands. */
2873 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2874 enum bgp_instance_type inst_type
)
2880 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2883 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2884 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2885 zlog_debug("Creating Default VRF, AS %u", *as
);
2887 zlog_debug("Creating %s %s, AS %u",
2888 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2894 /* Default the EVPN VRF to the default one */
2895 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
2901 bgp
->heuristic_coalesce
= true;
2902 bgp
->inst_type
= inst_type
;
2903 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2905 bgp
->peer_self
= peer_new(bgp
);
2906 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2907 bgp
->peer_self
->host
=
2908 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2909 if (bgp
->peer_self
->hostname
!= NULL
) {
2910 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2911 bgp
->peer_self
->hostname
= NULL
;
2913 if (cmd_hostname_get())
2914 bgp
->peer_self
->hostname
=
2915 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2917 if (bgp
->peer_self
->domainname
!= NULL
) {
2918 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2919 bgp
->peer_self
->domainname
= NULL
;
2921 if (cmd_domainname_get())
2922 bgp
->peer_self
->domainname
=
2923 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2924 bgp
->peer
= list_new();
2925 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2926 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2928 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2930 bgp
->group
= list_new();
2931 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2933 FOREACH_AFI_SAFI (afi
, safi
) {
2934 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2935 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2936 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2938 /* Enable maximum-paths */
2939 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2941 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2945 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2946 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2947 bgp
->default_subgroup_pkt_queue_max
=
2948 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2949 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2950 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2951 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2952 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2953 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2954 bgp
->dynamic_neighbors_count
= 0;
2955 bgp
->ebgp_requires_policy
= DEFAULT_EBGP_POLICY_DISABLED
;
2956 #if DFLT_BGP_IMPORT_CHECK
2957 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2959 #if DFLT_BGP_SHOW_HOSTNAME
2960 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2962 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2963 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2965 #if DFLT_BGP_DETERMINISTIC_MED
2966 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2968 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2973 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2974 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2976 assert(bgp
->rfapi_cfg
);
2978 #endif /* ENABLE_BGP_VNC */
2980 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2981 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2982 bgp
->vpn_policy
[afi
].afi
= afi
;
2983 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2984 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2987 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2988 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2989 bgp_vrf_string_name_delete
;
2990 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2991 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2992 bgp_vrf_string_name_delete
;
2995 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2997 /* TODO - The startup timer needs to be run for the whole of BGP
2999 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
3000 bgp
->restart_time
, &bgp
->t_startup
);
3003 /* printable name we can use in debug messages */
3004 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3005 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
3015 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
3017 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
3018 snprintf(bgp
->name_pretty
, len
, "%s %s",
3019 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3025 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
3026 memory_order_relaxed
);
3027 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
3028 memory_order_relaxed
);
3029 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
3033 update_bgp_group_init(bgp
);
3035 /* assign a unique rd id for auto derivation of vrf's RD */
3036 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3038 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
3039 sizeof(struct bgp_evpn_info
));
3046 /* Return the "default VRF" instance of BGP. */
3047 struct bgp
*bgp_get_default(void)
3050 struct listnode
*node
, *nnode
;
3052 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3053 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3058 /* Lookup BGP entry. */
3059 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3062 struct listnode
*node
, *nnode
;
3064 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3066 && ((bgp
->name
== NULL
&& name
== NULL
)
3067 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3072 /* Lookup BGP structure by view name. */
3073 struct bgp
*bgp_lookup_by_name(const char *name
)
3076 struct listnode
*node
, *nnode
;
3078 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3079 if ((bgp
->name
== NULL
&& name
== NULL
)
3080 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3085 /* Lookup BGP instance based on VRF id. */
3086 /* Note: Only to be used for incoming messages from Zebra. */
3087 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3091 /* Lookup VRF (in tree) and follow link. */
3092 vrf
= vrf_lookup_by_id(vrf_id
);
3095 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3098 /* Sets the BGP instance where EVPN is enabled */
3099 void bgp_set_evpn(struct bgp
*bgp
)
3101 if (bm
->bgp_evpn
== bgp
)
3104 /* First, release the reference count we hold on the instance */
3106 bgp_unlock(bm
->bgp_evpn
);
3110 /* Increase the reference count on this new VRF */
3112 bgp_lock(bm
->bgp_evpn
);
3115 /* Returns the BGP instance where EVPN is enabled, if any */
3116 struct bgp
*bgp_get_evpn(void)
3118 return bm
->bgp_evpn
;
3121 /* handle socket creation or deletion, if necessary
3122 * this is called for all new BGP instances
3124 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3129 /* Create BGP server socket, if listen mode not disabled */
3130 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3132 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3134 * suppress vrf socket
3136 if (create
== FALSE
) {
3137 bgp_close_vrf_socket(bgp
);
3141 return BGP_ERR_INVALID_VALUE
;
3143 * if vrf_id did not change
3145 if (vrf
->vrf_id
== old_vrf_id
)
3147 if (old_vrf_id
!= VRF_UNKNOWN
) {
3148 /* look for old socket. close it. */
3149 bgp_close_vrf_socket(bgp
);
3151 /* if backend is not yet identified ( VRF_UNKNOWN) then
3152 * creation will be done later
3154 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3156 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3158 return BGP_ERR_INVALID_VALUE
;
3161 return bgp_check_main_socket(create
, bgp
);
3164 /* Called from VTY commands. */
3165 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3166 enum bgp_instance_type inst_type
)
3169 struct vrf
*vrf
= NULL
;
3171 /* Multiple instance check. */
3173 bgp
= bgp_lookup_by_name(name
);
3175 bgp
= bgp_get_default();
3177 /* Already exists. */
3179 if (bgp
->as
!= *as
) {
3181 return BGP_ERR_INSTANCE_MISMATCH
;
3183 if (bgp
->inst_type
!= inst_type
)
3184 return BGP_ERR_INSTANCE_MISMATCH
;
3189 bgp
= bgp_create(as
, name
, inst_type
);
3190 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3191 bgp
->vrf_id
= vrf_generate_id();
3192 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, TRUE
);
3193 bgp_address_init(bgp
);
3194 bgp_tip_hash_init(bgp
);
3198 bgp
->t_rmap_def_originate_eval
= NULL
;
3200 /* If Default instance or VRF, link to the VRF structure, if present. */
3201 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3202 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3203 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3205 bgp_vrf_link(bgp
, vrf
);
3207 /* BGP server socket already processed if BGP instance
3208 * already part of the list
3210 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3211 listnode_add(bm
->bgp
, bgp
);
3213 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3214 if (BGP_DEBUG(zebra
, ZEBRA
))
3215 zlog_debug("%s: Registering BGP instance %s to zebra",
3216 __PRETTY_FUNCTION__
, name
);
3217 bgp_zebra_instance_register(bgp
);
3224 * Make BGP instance "up". Applies only to VRFs (non-default) and
3225 * implies the VRF has been learnt from Zebra.
3227 void bgp_instance_up(struct bgp
*bgp
)
3230 struct listnode
*node
, *next
;
3232 /* Register with zebra. */
3233 bgp_zebra_instance_register(bgp
);
3235 /* Kick off any peers that may have been configured. */
3236 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3237 if (!BGP_PEER_START_SUPPRESSED(peer
))
3238 BGP_EVENT_ADD(peer
, BGP_Start
);
3241 /* Process any networks that have been configured. */
3242 bgp_static_add(bgp
);
3246 * Make BGP instance "down". Applies only to VRFs (non-default) and
3247 * implies the VRF has been deleted by Zebra.
3249 void bgp_instance_down(struct bgp
*bgp
)
3252 struct listnode
*node
;
3253 struct listnode
*next
;
3256 if (bgp
->t_rmap_def_originate_eval
) {
3257 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3258 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3262 /* Bring down peers, so corresponding routes are purged. */
3263 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3264 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3265 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3266 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3268 bgp_session_reset(peer
);
3271 /* Purge network and redistributed routes. */
3272 bgp_purge_static_redist_routes(bgp
);
3274 /* Cleanup registered nexthops (flags) */
3275 bgp_cleanup_nexthops(bgp
);
3278 /* Delete BGP instance. */
3279 int bgp_delete(struct bgp
*bgp
)
3282 struct peer_group
*group
;
3283 struct listnode
*node
, *next
;
3289 THREAD_OFF(bgp
->t_startup
);
3290 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3291 THREAD_OFF(bgp
->t_update_delay
);
3292 THREAD_OFF(bgp
->t_establish_wait
);
3294 /* Set flag indicating bgp instance delete in progress */
3295 bgp_flag_set(bgp
, BGP_FLAG_DELETE_IN_PROGRESS
);
3297 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3298 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3299 zlog_debug("Deleting Default VRF");
3301 zlog_debug("Deleting %s %s",
3302 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3308 /* unmap from RT list */
3309 bgp_evpn_vrf_delete(bgp
);
3311 /* unmap bgp vrf label */
3312 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3313 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3316 if (bgp
->t_rmap_def_originate_eval
) {
3317 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3318 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3322 /* Inform peers we're going down. */
3323 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3324 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3325 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3326 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3329 /* Delete static routes (networks). */
3330 bgp_static_delete(bgp
);
3332 /* Unset redistribution. */
3333 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3334 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3335 if (i
!= ZEBRA_ROUTE_BGP
)
3336 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3338 /* Free peers and peer-groups. */
3339 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3340 peer_group_delete(group
);
3342 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3345 if (bgp
->peer_self
) {
3346 peer_delete(bgp
->peer_self
);
3347 bgp
->peer_self
= NULL
;
3350 update_bgp_group_free(bgp
);
3352 /* TODO - Other memory may need to be freed - e.g., NHT */
3357 bgp_cleanup_routes(bgp
);
3359 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3360 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3363 &bgp
->vpn_policy
[afi
]
3364 .import_redirect_rtlist
);
3365 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3368 /* Deregister from Zebra, if needed */
3369 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3370 if (BGP_DEBUG(zebra
, ZEBRA
))
3371 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3372 __PRETTY_FUNCTION__
, bgp
->name
);
3373 bgp_zebra_instance_deregister(bgp
);
3376 /* Remove visibility via the master list - there may however still be
3377 * routes to be processed still referencing the struct bgp.
3379 listnode_delete(bm
->bgp
, bgp
);
3381 /* Free interfaces in this instance. */
3384 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3385 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3387 bgp_vrf_unlink(bgp
, vrf
);
3389 /* Update EVPN VRF pointer */
3390 if (bm
->bgp_evpn
== bgp
) {
3391 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3394 bgp_set_evpn(bgp_get_default());
3397 thread_master_free_unused(bm
->master
);
3398 bgp_unlock(bgp
); /* initial reference */
3403 void bgp_free(struct bgp
*bgp
)
3407 struct bgp_table
*table
;
3408 struct bgp_node
*rn
;
3409 struct bgp_rmap
*rmap
;
3413 list_delete(&bgp
->group
);
3414 list_delete(&bgp
->peer
);
3416 if (bgp
->peerhash
) {
3417 hash_free(bgp
->peerhash
);
3418 bgp
->peerhash
= NULL
;
3421 FOREACH_AFI_SAFI (afi
, safi
) {
3422 /* Special handling for 2-level routing tables. */
3423 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3424 || safi
== SAFI_EVPN
) {
3425 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3426 rn
= bgp_route_next(rn
)) {
3427 table
= bgp_node_get_bgp_table_info(rn
);
3428 bgp_table_finish(&table
);
3431 if (bgp
->route
[afi
][safi
])
3432 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3433 if (bgp
->aggregate
[afi
][safi
])
3434 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3435 if (bgp
->rib
[afi
][safi
])
3436 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3437 rmap
= &bgp
->table_map
[afi
][safi
];
3438 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3441 bgp_scan_finish(bgp
);
3442 bgp_address_destroy(bgp
);
3443 bgp_tip_hash_destroy(bgp
);
3445 /* release the auto RD id */
3446 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3448 bgp_evpn_cleanup(bgp
);
3449 bgp_pbr_cleanup(bgp
);
3450 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3452 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3453 vpn_policy_direction_t dir
;
3455 if (bgp
->vpn_policy
[afi
].import_vrf
)
3456 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3457 if (bgp
->vpn_policy
[afi
].export_vrf
)
3458 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3460 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3461 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3462 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3463 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3464 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3465 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3468 XFREE(MTYPE_BGP
, bgp
->name
);
3469 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3471 XFREE(MTYPE_BGP
, bgp
);
3474 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3477 struct listnode
*node
, *nnode
;
3483 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3484 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3485 && !CHECK_FLAG(peer
->sflags
,
3486 PEER_STATUS_ACCEPT_PEER
))
3488 } else if (bm
->bgp
!= NULL
) {
3489 struct listnode
*bgpnode
, *nbgpnode
;
3491 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3492 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3494 && !strcmp(peer
->conf_if
, conf_if
)
3495 && !CHECK_FLAG(peer
->sflags
,
3496 PEER_STATUS_ACCEPT_PEER
))
3502 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3505 struct listnode
*node
, *nnode
;
3511 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3512 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3513 && !CHECK_FLAG(peer
->sflags
,
3514 PEER_STATUS_ACCEPT_PEER
))
3516 } else if (bm
->bgp
!= NULL
) {
3517 struct listnode
*bgpnode
, *nbgpnode
;
3519 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3520 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3522 && !strcmp(peer
->hostname
, hostname
)
3523 && !CHECK_FLAG(peer
->sflags
,
3524 PEER_STATUS_ACCEPT_PEER
))
3530 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3532 struct peer
*peer
= NULL
;
3533 struct peer tmp_peer
;
3535 memset(&tmp_peer
, 0, sizeof(struct peer
));
3538 * We do not want to find the doppelganger peer so search for the peer
3540 * the hash that has PEER_FLAG_CONFIG_NODE
3542 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3547 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3548 } else if (bm
->bgp
!= NULL
) {
3549 struct listnode
*bgpnode
, *nbgpnode
;
3551 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3552 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3561 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3562 union sockunion
*su
,
3563 struct peer_group
*group
)
3569 /* Create peer first; we've already checked group config is valid. */
3570 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3571 group
->conf
->as_type
, 0, 0, group
);
3576 peer
= peer_lock(peer
);
3577 listnode_add(group
->peer
, peer
);
3579 peer_group2peer_config_copy(group
, peer
);
3582 * Bind peer for all AFs configured for the group. We don't call
3583 * peer_group_bind as that is sub-optimal and does some stuff we don't
3586 FOREACH_AFI_SAFI (afi
, safi
) {
3587 if (!group
->conf
->afc
[afi
][safi
])
3589 peer
->afc
[afi
][safi
] = 1;
3591 if (!peer_af_find(peer
, afi
, safi
))
3592 peer_af_create(peer
, afi
, safi
);
3594 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3597 /* Mark as dynamic, but also as a "config node" for other things to
3599 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3600 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3606 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3607 struct prefix
*prefix
)
3609 struct listnode
*node
, *nnode
;
3610 struct prefix
*range
;
3613 afi
= family2afi(prefix
->family
);
3615 if (group
->listen_range
[afi
])
3616 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3618 if (prefix_match(range
, prefix
))
3625 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3626 struct prefix
**listen_range
)
3628 struct prefix
*range
= NULL
;
3629 struct peer_group
*group
= NULL
;
3630 struct listnode
*node
, *nnode
;
3632 *listen_range
= NULL
;
3634 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3635 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3638 } else if (bm
->bgp
!= NULL
) {
3639 struct listnode
*bgpnode
, *nbgpnode
;
3641 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3642 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3643 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3649 *listen_range
= range
;
3650 return (group
&& range
) ? group
: NULL
;
3653 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3655 struct peer_group
*group
;
3658 struct prefix prefix
;
3659 struct prefix
*listen_range
;
3661 char buf
[PREFIX2STR_BUFFER
];
3662 char buf1
[PREFIX2STR_BUFFER
];
3664 sockunion2hostprefix(su
, &prefix
);
3666 /* See if incoming connection matches a configured listen range. */
3667 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3678 prefix2str(&prefix
, buf
, sizeof(buf
));
3679 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3681 if (bgp_debug_neighbor_events(NULL
))
3683 "Dynamic Neighbor %s matches group %s listen range %s",
3684 buf
, group
->name
, buf1
);
3686 /* Are we within the listen limit? */
3687 dncount
= gbgp
->dynamic_neighbors_count
;
3689 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3690 if (bgp_debug_neighbor_events(NULL
))
3691 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3692 inet_sutop(su
, buf
),
3693 gbgp
->dynamic_neighbors_limit
);
3697 /* Ensure group is not disabled. */
3698 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3699 if (bgp_debug_neighbor_events(NULL
))
3701 "Dynamic Neighbor %s rejected - group %s disabled",
3706 /* Check that at least one AF is activated for the group. */
3707 if (!peer_group_af_configured(group
)) {
3708 if (bgp_debug_neighbor_events(NULL
))
3710 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3715 /* Create dynamic peer and bind to associated group. */
3716 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3719 gbgp
->dynamic_neighbors_count
= ++dncount
;
3721 if (bgp_debug_neighbor_events(peer
))
3722 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3723 peer
->host
, group
->name
, dncount
);
3728 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3731 if (peer
->group
->bgp
) {
3732 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3734 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3736 if (bgp_debug_neighbor_events(peer
))
3737 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3738 peer
->group
->name
, dncount
);
3741 /* If peer is configured at least one address family return 1. */
3742 int peer_active(struct peer
*peer
)
3744 if (BGP_PEER_SU_UNSPEC(peer
))
3746 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3747 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3748 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3749 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3750 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3751 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3752 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3753 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3754 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3755 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3756 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3761 /* If peer is negotiated at least one address family return 1. */
3762 int peer_active_nego(struct peer
*peer
)
3764 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3765 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3766 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3767 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3768 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3769 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3770 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3771 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3772 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3773 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3774 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3775 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3776 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3781 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3782 enum peer_change_type type
)
3784 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3787 if (peer
->status
!= Established
)
3790 if (type
== peer_change_reset
) {
3791 /* If we're resetting session, we've to delete both peer struct
3793 if ((peer
->doppelganger
)
3794 && (peer
->doppelganger
->status
!= Deleted
)
3795 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3796 PEER_FLAG_CONFIG_NODE
)))
3797 peer_delete(peer
->doppelganger
);
3799 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3800 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3801 } else if (type
== peer_change_reset_in
) {
3802 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3803 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3804 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3806 if ((peer
->doppelganger
)
3807 && (peer
->doppelganger
->status
!= Deleted
)
3808 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3809 PEER_FLAG_CONFIG_NODE
)))
3810 peer_delete(peer
->doppelganger
);
3812 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3813 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3815 } else if (type
== peer_change_reset_out
) {
3816 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3817 bgp_announce_route(peer
, afi
, safi
);
3821 struct peer_flag_action
{
3825 /* This flag can be set for peer-group member. */
3826 uint8_t not_for_member
;
3828 /* Action when the flag is changed. */
3829 enum peer_change_type type
;
3832 static const struct peer_flag_action peer_flag_action_list
[] = {
3833 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3834 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3835 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3836 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3837 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3838 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3839 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3840 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3841 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3842 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3843 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3844 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3845 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3846 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3847 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3848 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3849 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3850 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3853 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3854 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3855 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3856 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3857 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3858 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3859 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3860 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3861 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3862 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3863 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3864 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3865 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3866 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3867 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3868 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3869 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3870 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3871 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3872 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3873 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3874 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3875 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3876 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3877 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3878 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3881 /* Proper action set. */
3882 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3883 int size
, struct peer_flag_action
*action
,
3890 const struct peer_flag_action
*match
= NULL
;
3892 /* Check peer's frag action. */
3893 for (i
= 0; i
< size
; i
++) {
3894 match
= &action_list
[i
];
3896 if (match
->flag
== 0)
3899 if (match
->flag
& flag
) {
3902 if (match
->type
== peer_change_reset_in
)
3904 if (match
->type
== peer_change_reset_out
)
3906 if (match
->type
== peer_change_reset
) {
3910 if (match
->not_for_member
)
3911 action
->not_for_member
= 1;
3915 /* Set peer clear type. */
3916 if (reset_in
&& reset_out
)
3917 action
->type
= peer_change_reset
;
3919 action
->type
= peer_change_reset_in
;
3921 action
->type
= peer_change_reset_out
;
3923 action
->type
= peer_change_none
;
3928 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3930 if (flag
== PEER_FLAG_SHUTDOWN
) {
3931 if (CHECK_FLAG(peer
->flags
, flag
)) {
3932 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3933 peer_nsf_stop(peer
);
3935 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3936 if (peer
->t_pmax_restart
) {
3937 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3938 if (bgp_debug_neighbor_events(peer
))
3940 "%s Maximum-prefix restart timer canceled",
3944 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3945 peer_nsf_stop(peer
);
3947 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3948 char *msg
= peer
->tx_shutdown_message
;
3951 if (!msg
&& peer_group_active(peer
))
3952 msg
= peer
->group
->conf
3953 ->tx_shutdown_message
;
3954 msglen
= msg
? strlen(msg
) : 0;
3959 uint8_t msgbuf
[129];
3962 memcpy(msgbuf
+ 1, msg
, msglen
);
3964 bgp_notify_send_with_data(
3965 peer
, BGP_NOTIFY_CEASE
,
3966 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3967 msgbuf
, msglen
+ 1);
3970 peer
, BGP_NOTIFY_CEASE
,
3971 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3973 bgp_session_reset(peer
);
3975 peer
->v_start
= BGP_INIT_START_TIMER
;
3976 BGP_EVENT_ADD(peer
, BGP_Stop
);
3978 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3979 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3980 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3981 else if (flag
== PEER_FLAG_PASSIVE
)
3982 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3983 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3984 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3986 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3987 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3989 bgp_session_reset(peer
);
3992 /* Change specified peer flag. */
3993 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3997 bool invert
, member_invert
;
3998 struct peer
*member
;
3999 struct listnode
*node
, *nnode
;
4000 struct peer_flag_action action
;
4002 memset(&action
, 0, sizeof(struct peer_flag_action
));
4003 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
4005 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
4006 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
4009 /* Abort if no flag action exists. */
4011 return BGP_ERR_INVALID_FLAG
;
4013 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4014 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
4015 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
4016 return BGP_ERR_PEER_FLAG_CONFLICT
;
4018 /* Handle flag updates where desired state matches current state. */
4019 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4020 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
4021 COND_FLAG(peer
->flags_override
, flag
, !invert
);
4025 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
4026 COND_FLAG(peer
->flags_override
, flag
, invert
);
4031 /* Inherit from peer-group or set/unset flags accordingly. */
4032 if (peer_group_active(peer
) && set
== invert
)
4033 peer_flag_inherit(peer
, flag
);
4035 COND_FLAG(peer
->flags
, flag
, set
);
4037 /* Check if handling a regular peer. */
4038 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4039 /* Update flag override state accordingly. */
4040 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
4042 /* Execute flag action on peer. */
4043 if (action
.type
== peer_change_reset
)
4044 peer_flag_modify_action(peer
, flag
);
4046 /* Skip peer-group mechanics for regular peers. */
4050 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4051 bgp_nht_register_enhe_capability_interfaces(peer
);
4054 * Update peer-group members, unless they are explicitely overriding
4055 * peer-group configuration.
4057 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4058 /* Skip peers with overridden configuration. */
4059 if (CHECK_FLAG(member
->flags_override
, flag
))
4062 /* Check if only member without group is inverted. */
4064 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4066 /* Skip peers with equivalent configuration. */
4067 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4070 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4073 /* Update flag on peer-group member. */
4074 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4076 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4077 bgp_nht_register_enhe_capability_interfaces(member
);
4079 /* Execute flag action on peer-group member. */
4080 if (action
.type
== peer_change_reset
)
4081 peer_flag_modify_action(member
, flag
);
4087 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4089 return peer_flag_modify(peer
, flag
, 1);
4092 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4094 return peer_flag_modify(peer
, flag
, 0);
4097 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4098 uint32_t flag
, bool set
)
4102 bool invert
, member_invert
;
4103 struct peer
*member
;
4104 struct listnode
*node
, *nnode
;
4105 struct peer_flag_action action
;
4107 memset(&action
, 0, sizeof(struct peer_flag_action
));
4108 size
= sizeof peer_af_flag_action_list
4109 / sizeof(struct peer_flag_action
);
4111 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4112 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4115 /* Abort if flag action exists. */
4117 return BGP_ERR_INVALID_FLAG
;
4119 /* Special check for reflector client. */
4120 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4121 && peer_sort(peer
) != BGP_PEER_IBGP
)
4122 return BGP_ERR_NOT_INTERNAL_PEER
;
4124 /* Special check for remove-private-AS. */
4125 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4126 && peer_sort(peer
) == BGP_PEER_IBGP
)
4127 return BGP_ERR_REMOVE_PRIVATE_AS
;
4129 /* as-override is not allowed for IBGP peers */
4130 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4131 return BGP_ERR_AS_OVERRIDE
;
4133 /* Handle flag updates where desired state matches current state. */
4134 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4135 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4136 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4141 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4142 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4149 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4150 * if we are setting/unsetting flags which conflict with this flag
4151 * handle accordingly
4153 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4157 * if we are setting NEXTHOP_SELF, we need to unset the
4158 * NEXTHOP_UNCHANGED flag
4160 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4161 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4162 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4163 PEER_FLAG_NEXTHOP_UNCHANGED
);
4167 * if we are unsetting NEXTHOP_SELF, we need to set the
4168 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4170 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4171 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4172 SET_FLAG(peer
->af_flags
[afi
][safi
],
4173 PEER_FLAG_NEXTHOP_UNCHANGED
);
4177 /* Inherit from peer-group or set/unset flags accordingly. */
4178 if (peer_group_active(peer
) && set
== invert
)
4179 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4181 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4183 /* Execute action when peer is established. */
4184 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4185 && peer
->status
== Established
) {
4186 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4187 bgp_clear_adj_in(peer
, afi
, safi
);
4189 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4190 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4191 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4192 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4193 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4194 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4195 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4196 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4198 peer_change_action(peer
, afi
, safi
, action
.type
);
4202 /* Check if handling a regular peer. */
4203 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4204 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4208 * Update peer-group members, unless they are explicitely
4209 * overriding peer-group configuration.
4211 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4213 /* Skip peers with overridden configuration. */
4214 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4218 /* Check if only member without group is inverted. */
4220 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4224 /* Skip peers with equivalent configuration. */
4225 if (set
!= member_invert
4226 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4229 if (set
== member_invert
4230 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4233 /* Update flag on peer-group member. */
4234 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4235 set
!= member_invert
);
4237 /* Execute flag action on peer-group member. */
4238 if (member
->status
== Established
) {
4239 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4240 bgp_clear_adj_in(member
, afi
, safi
);
4242 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4243 member
->last_reset
=
4244 PEER_DOWN_RR_CLIENT_CHANGE
;
4246 == PEER_FLAG_RSERVER_CLIENT
)
4247 member
->last_reset
=
4248 PEER_DOWN_RS_CLIENT_CHANGE
;
4250 == PEER_FLAG_ORF_PREFIX_SM
)
4251 member
->last_reset
=
4252 PEER_DOWN_CAPABILITY_CHANGE
;
4254 == PEER_FLAG_ORF_PREFIX_RM
)
4255 member
->last_reset
=
4256 PEER_DOWN_CAPABILITY_CHANGE
;
4258 peer_change_action(member
, afi
, safi
,
4268 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4270 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4273 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4275 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4279 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4281 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4282 peer
->tx_shutdown_message
=
4283 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4287 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4289 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4294 /* EBGP multihop configuration. */
4295 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4297 struct peer_group
*group
;
4298 struct listnode
*node
, *nnode
;
4301 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4304 /* see comment in peer_ttl_security_hops_set() */
4305 if (ttl
!= MAXTTL
) {
4306 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4307 group
= peer
->group
;
4308 if (group
->conf
->gtsm_hops
!= 0)
4309 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4311 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4313 if (peer1
->sort
== BGP_PEER_IBGP
)
4316 if (peer1
->gtsm_hops
!= 0)
4317 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4320 if (peer
->gtsm_hops
!= 0)
4321 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4327 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4328 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4329 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4330 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4331 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4333 bgp_session_reset(peer
);
4336 group
= peer
->group
;
4337 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4338 if (peer
->sort
== BGP_PEER_IBGP
)
4341 peer
->ttl
= group
->conf
->ttl
;
4343 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4344 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4345 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4347 bgp_session_reset(peer
);
4353 int peer_ebgp_multihop_unset(struct peer
*peer
)
4355 struct peer_group
*group
;
4356 struct listnode
*node
, *nnode
;
4358 if (peer
->sort
== BGP_PEER_IBGP
)
4361 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4362 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4364 if (peer_group_active(peer
))
4365 peer
->ttl
= peer
->group
->conf
->ttl
;
4369 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4370 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4371 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4372 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4374 bgp_session_reset(peer
);
4376 group
= peer
->group
;
4377 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4378 if (peer
->sort
== BGP_PEER_IBGP
)
4383 if (peer
->fd
>= 0) {
4384 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4386 peer
, BGP_NOTIFY_CEASE
,
4387 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4389 bgp_session_reset(peer
);
4396 /* Neighbor description. */
4397 int peer_description_set(struct peer
*peer
, const char *desc
)
4399 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4401 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4406 int peer_description_unset(struct peer
*peer
)
4408 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4415 /* Neighbor update-source. */
4416 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4418 struct peer
*member
;
4419 struct listnode
*node
, *nnode
;
4421 /* Set flag and configuration on peer. */
4422 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4423 if (peer
->update_if
) {
4424 if (strcmp(peer
->update_if
, ifname
) == 0)
4426 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4428 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4429 sockunion_free(peer
->update_source
);
4430 peer
->update_source
= NULL
;
4432 /* Check if handling a regular peer. */
4433 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4434 /* Send notification or reset peer depending on state. */
4435 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4436 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4437 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4438 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4440 bgp_session_reset(peer
);
4442 /* Skip peer-group mechanics for regular peers. */
4447 * Set flag and configuration on all peer-group members, unless they are
4448 * explicitely overriding peer-group configuration.
4450 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4451 /* Skip peers with overridden configuration. */
4452 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4455 /* Skip peers with the same configuration. */
4456 if (member
->update_if
) {
4457 if (strcmp(member
->update_if
, ifname
) == 0)
4459 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4462 /* Set flag and configuration on peer-group member. */
4463 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4464 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4465 sockunion_free(member
->update_source
);
4466 member
->update_source
= NULL
;
4468 /* Send notification or reset peer depending on state. */
4469 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4470 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4471 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4472 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4474 bgp_session_reset(member
);
4480 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4482 struct peer
*member
;
4483 struct listnode
*node
, *nnode
;
4485 /* Set flag and configuration on peer. */
4486 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4487 if (peer
->update_source
) {
4488 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4490 sockunion_free(peer
->update_source
);
4492 peer
->update_source
= sockunion_dup(su
);
4493 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4495 /* Check if handling a regular peer. */
4496 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4497 /* Send notification or reset peer depending on state. */
4498 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4499 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4500 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4501 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4503 bgp_session_reset(peer
);
4505 /* Skip peer-group mechanics for regular peers. */
4510 * Set flag and configuration on all peer-group members, unless they are
4511 * explicitely overriding peer-group configuration.
4513 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4514 /* Skip peers with overridden configuration. */
4515 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4518 /* Skip peers with the same configuration. */
4519 if (member
->update_source
) {
4520 if (sockunion_cmp(member
->update_source
, su
) == 0)
4522 sockunion_free(member
->update_source
);
4525 /* Set flag and configuration on peer-group member. */
4526 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4527 member
->update_source
= sockunion_dup(su
);
4528 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4530 /* Send notification or reset peer depending on state. */
4531 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4532 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4533 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4534 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4536 bgp_session_reset(member
);
4542 int peer_update_source_unset(struct peer
*peer
)
4544 struct peer
*member
;
4545 struct listnode
*node
, *nnode
;
4547 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4550 /* Inherit configuration from peer-group if peer is member. */
4551 if (peer_group_active(peer
)) {
4552 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4553 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4554 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4555 MTYPE_PEER_UPDATE_SOURCE
);
4557 /* Otherwise remove flag and configuration from peer. */
4558 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4559 sockunion_free(peer
->update_source
);
4560 peer
->update_source
= NULL
;
4561 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4564 /* Check if handling a regular peer. */
4565 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4566 /* Send notification or reset peer depending on state. */
4567 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4568 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4569 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4570 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4572 bgp_session_reset(peer
);
4574 /* Skip peer-group mechanics for regular peers. */
4579 * Set flag and configuration on all peer-group members, unless they are
4580 * explicitely overriding peer-group configuration.
4582 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4583 /* Skip peers with overridden configuration. */
4584 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4587 /* Skip peers with the same configuration. */
4588 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4589 && !member
->update_source
&& !member
->update_if
)
4592 /* Remove flag and configuration on peer-group member. */
4593 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4594 sockunion_free(member
->update_source
);
4595 member
->update_source
= NULL
;
4596 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4598 /* Send notification or reset peer depending on state. */
4599 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4600 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4601 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4602 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4604 bgp_session_reset(member
);
4610 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4611 const char *rmap
, struct route_map
*route_map
)
4613 struct peer
*member
;
4614 struct listnode
*node
, *nnode
;
4616 /* Set flag and configuration on peer. */
4617 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4619 if (!peer
->default_rmap
[afi
][safi
].name
4620 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4621 if (peer
->default_rmap
[afi
][safi
].name
)
4622 XFREE(MTYPE_ROUTE_MAP_NAME
,
4623 peer
->default_rmap
[afi
][safi
].name
);
4625 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4626 peer
->default_rmap
[afi
][safi
].name
=
4627 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4628 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4629 route_map_counter_increment(route_map
);
4632 if (peer
->default_rmap
[afi
][safi
].name
)
4633 XFREE(MTYPE_ROUTE_MAP_NAME
,
4634 peer
->default_rmap
[afi
][safi
].name
);
4636 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4637 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4638 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4641 /* Check if handling a regular peer. */
4642 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4643 /* Update peer route announcements. */
4644 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4645 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4646 bgp_default_originate(peer
, afi
, safi
, 0);
4647 bgp_announce_route(peer
, afi
, safi
);
4650 /* Skip peer-group mechanics for regular peers. */
4655 * Set flag and configuration on all peer-group members, unless they are
4656 * explicitely overriding peer-group configuration.
4658 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4659 /* Skip peers with overridden configuration. */
4660 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4661 PEER_FLAG_DEFAULT_ORIGINATE
))
4664 /* Set flag and configuration on peer-group member. */
4665 SET_FLAG(member
->af_flags
[afi
][safi
],
4666 PEER_FLAG_DEFAULT_ORIGINATE
);
4668 if (member
->default_rmap
[afi
][safi
].name
)
4669 XFREE(MTYPE_ROUTE_MAP_NAME
,
4670 member
->default_rmap
[afi
][safi
].name
);
4671 route_map_counter_decrement(
4672 member
->default_rmap
[afi
][safi
].map
);
4673 member
->default_rmap
[afi
][safi
].name
=
4674 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4675 member
->default_rmap
[afi
][safi
].map
= route_map
;
4676 route_map_counter_increment(route_map
);
4679 /* Update peer route announcements. */
4680 if (member
->status
== Established
4681 && member
->afc_nego
[afi
][safi
]) {
4682 update_group_adjust_peer(
4683 peer_af_find(member
, afi
, safi
));
4684 bgp_default_originate(member
, afi
, safi
, 0);
4685 bgp_announce_route(member
, afi
, safi
);
4692 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4694 struct peer
*member
;
4695 struct listnode
*node
, *nnode
;
4697 /* Inherit configuration from peer-group if peer is member. */
4698 if (peer_group_active(peer
)) {
4699 peer_af_flag_inherit(peer
, afi
, safi
,
4700 PEER_FLAG_DEFAULT_ORIGINATE
);
4701 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4702 default_rmap
[afi
][safi
].name
,
4703 MTYPE_ROUTE_MAP_NAME
);
4704 PEER_ATTR_INHERIT(peer
, peer
->group
,
4705 default_rmap
[afi
][safi
].map
);
4707 /* Otherwise remove flag and configuration from peer. */
4708 peer_af_flag_unset(peer
, afi
, safi
,
4709 PEER_FLAG_DEFAULT_ORIGINATE
);
4710 if (peer
->default_rmap
[afi
][safi
].name
)
4711 XFREE(MTYPE_ROUTE_MAP_NAME
,
4712 peer
->default_rmap
[afi
][safi
].name
);
4713 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4714 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4715 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4718 /* Check if handling a regular peer. */
4719 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4720 /* Update peer route announcements. */
4721 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4722 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4723 bgp_default_originate(peer
, afi
, safi
, 1);
4724 bgp_announce_route(peer
, afi
, safi
);
4727 /* Skip peer-group mechanics for regular peers. */
4732 * Remove flag and configuration from all peer-group members, unless
4733 * they are explicitely overriding peer-group configuration.
4735 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4736 /* Skip peers with overridden configuration. */
4737 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4738 PEER_FLAG_DEFAULT_ORIGINATE
))
4741 /* Remove flag and configuration on peer-group member. */
4742 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4743 PEER_FLAG_DEFAULT_ORIGINATE
);
4744 if (peer
->default_rmap
[afi
][safi
].name
)
4745 XFREE(MTYPE_ROUTE_MAP_NAME
,
4746 peer
->default_rmap
[afi
][safi
].name
);
4747 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4748 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4749 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4751 /* Update peer route announcements. */
4752 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4753 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4754 bgp_default_originate(peer
, afi
, safi
, 1);
4755 bgp_announce_route(peer
, afi
, safi
);
4762 int peer_port_set(struct peer
*peer
, uint16_t port
)
4768 int peer_port_unset(struct peer
*peer
)
4770 peer
->port
= BGP_PORT_DEFAULT
;
4775 * Helper function that is called after the name of the policy
4776 * being used by a peer has changed (AF specific). Automatically
4777 * initiates inbound or outbound processing as needed.
4779 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4783 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4784 if (peer
->status
== Established
)
4785 bgp_announce_route(peer
, afi
, safi
);
4787 if (peer
->status
!= Established
)
4790 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4791 PEER_FLAG_SOFT_RECONFIG
))
4792 bgp_soft_reconfig_in(peer
, afi
, safi
);
4793 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4794 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4795 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4800 /* neighbor weight. */
4801 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4803 struct peer
*member
;
4804 struct listnode
*node
, *nnode
;
4806 /* Set flag and configuration on peer. */
4807 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4808 if (peer
->weight
[afi
][safi
] != weight
) {
4809 peer
->weight
[afi
][safi
] = weight
;
4810 peer_on_policy_change(peer
, afi
, safi
, 0);
4813 /* Skip peer-group mechanics for regular peers. */
4814 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4818 * Set flag and configuration on all peer-group members, unless they are
4819 * explicitely overriding peer-group configuration.
4821 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4822 /* Skip peers with overridden configuration. */
4823 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4827 /* Set flag and configuration on peer-group member. */
4828 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4829 if (member
->weight
[afi
][safi
] != weight
) {
4830 member
->weight
[afi
][safi
] = weight
;
4831 peer_on_policy_change(member
, afi
, safi
, 0);
4838 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4840 struct peer
*member
;
4841 struct listnode
*node
, *nnode
;
4843 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4846 /* Inherit configuration from peer-group if peer is member. */
4847 if (peer_group_active(peer
)) {
4848 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4849 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4851 peer_on_policy_change(peer
, afi
, safi
, 0);
4855 /* Remove flag and configuration from peer. */
4856 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4857 peer
->weight
[afi
][safi
] = 0;
4858 peer_on_policy_change(peer
, afi
, safi
, 0);
4860 /* Skip peer-group mechanics for regular peers. */
4861 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4865 * Remove flag and configuration from all peer-group members, unless
4866 * they are explicitely overriding peer-group configuration.
4868 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4869 /* Skip peers with overridden configuration. */
4870 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4874 /* Skip peers where flag is already disabled. */
4875 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4878 /* Remove flag and configuration on peer-group member. */
4879 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4880 member
->weight
[afi
][safi
] = 0;
4881 peer_on_policy_change(member
, afi
, safi
, 0);
4887 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4889 struct peer
*member
;
4890 struct listnode
*node
, *nnode
;
4892 if (keepalive
> 65535)
4893 return BGP_ERR_INVALID_VALUE
;
4895 if (holdtime
> 65535)
4896 return BGP_ERR_INVALID_VALUE
;
4898 if (holdtime
< 3 && holdtime
!= 0)
4899 return BGP_ERR_INVALID_VALUE
;
4901 /* Set flag and configuration on peer. */
4902 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4903 peer
->holdtime
= holdtime
;
4904 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4906 /* Skip peer-group mechanics for regular peers. */
4907 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4911 * Set flag and configuration on all peer-group members, unless they are
4912 * explicitely overriding peer-group configuration.
4914 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4915 /* Skip peers with overridden configuration. */
4916 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4919 /* Set flag and configuration on peer-group member. */
4920 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4921 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4922 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4928 int peer_timers_unset(struct peer
*peer
)
4930 struct peer
*member
;
4931 struct listnode
*node
, *nnode
;
4933 /* Inherit configuration from peer-group if peer is member. */
4934 if (peer_group_active(peer
)) {
4935 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4936 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4937 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4939 /* Otherwise remove flag and configuration from peer. */
4940 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4942 peer
->keepalive
= 0;
4945 /* Skip peer-group mechanics for regular peers. */
4946 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4950 * Remove flag and configuration from all peer-group members, unless
4951 * they are explicitely overriding peer-group configuration.
4953 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4954 /* Skip peers with overridden configuration. */
4955 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4958 /* Remove flag and configuration on peer-group member. */
4959 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4960 member
->holdtime
= 0;
4961 member
->keepalive
= 0;
4967 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4969 struct peer
*member
;
4970 struct listnode
*node
, *nnode
;
4972 if (connect
> 65535)
4973 return BGP_ERR_INVALID_VALUE
;
4975 /* Set flag and configuration on peer. */
4976 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4977 peer
->connect
= connect
;
4978 peer
->v_connect
= connect
;
4980 /* Skip peer-group mechanics for regular peers. */
4981 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4985 * Set flag and configuration on all peer-group members, unless they are
4986 * explicitely overriding peer-group configuration.
4988 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4989 /* Skip peers with overridden configuration. */
4990 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4993 /* Set flag and configuration on peer-group member. */
4994 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4995 member
->connect
= connect
;
4996 member
->v_connect
= connect
;
5002 int peer_timers_connect_unset(struct peer
*peer
)
5004 struct peer
*member
;
5005 struct listnode
*node
, *nnode
;
5007 /* Inherit configuration from peer-group if peer is member. */
5008 if (peer_group_active(peer
)) {
5009 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
5010 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
5012 /* Otherwise remove flag and configuration from peer. */
5013 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
5017 /* Set timer with fallback to default value. */
5019 peer
->v_connect
= peer
->connect
;
5021 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5023 /* Skip peer-group mechanics for regular peers. */
5024 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5028 * Remove flag and configuration from all peer-group members, unless
5029 * they are explicitely overriding peer-group configuration.
5031 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5032 /* Skip peers with overridden configuration. */
5033 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
5036 /* Remove flag and configuration on peer-group member. */
5037 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
5038 member
->connect
= 0;
5039 member
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
5045 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5047 struct peer
*member
;
5048 struct listnode
*node
, *nnode
;
5051 return BGP_ERR_INVALID_VALUE
;
5053 /* Set flag and configuration on peer. */
5054 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5055 peer
->routeadv
= routeadv
;
5056 peer
->v_routeadv
= routeadv
;
5058 /* Check if handling a regular peer. */
5059 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5060 /* Update peer route announcements. */
5061 update_group_adjust_peer_afs(peer
);
5062 if (peer
->status
== Established
)
5063 bgp_announce_route_all(peer
);
5065 /* Skip peer-group mechanics for regular peers. */
5070 * Set flag and configuration on all peer-group members, unless they are
5071 * explicitely overriding peer-group configuration.
5073 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5074 /* Skip peers with overridden configuration. */
5075 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5078 /* Set flag and configuration on peer-group member. */
5079 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5080 member
->routeadv
= routeadv
;
5081 member
->v_routeadv
= routeadv
;
5083 /* Update peer route announcements. */
5084 update_group_adjust_peer_afs(member
);
5085 if (member
->status
== Established
)
5086 bgp_announce_route_all(member
);
5092 int peer_advertise_interval_unset(struct peer
*peer
)
5094 struct peer
*member
;
5095 struct listnode
*node
, *nnode
;
5097 /* Inherit configuration from peer-group if peer is member. */
5098 if (peer_group_active(peer
)) {
5099 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5100 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5102 /* Otherwise remove flag and configuration from peer. */
5103 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5107 /* Set timer with fallback to default value. */
5109 peer
->v_routeadv
= peer
->routeadv
;
5111 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5112 ? BGP_DEFAULT_IBGP_ROUTEADV
5113 : BGP_DEFAULT_EBGP_ROUTEADV
;
5115 /* Check if handling a regular peer. */
5116 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5117 /* Update peer route announcements. */
5118 update_group_adjust_peer_afs(peer
);
5119 if (peer
->status
== Established
)
5120 bgp_announce_route_all(peer
);
5122 /* Skip peer-group mechanics for regular peers. */
5127 * Remove flag and configuration from all peer-group members, unless
5128 * they are explicitely overriding peer-group configuration.
5130 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5131 /* Skip peers with overridden configuration. */
5132 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5135 /* Remove flag and configuration on peer-group member. */
5136 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5137 member
->routeadv
= 0;
5138 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5139 ? BGP_DEFAULT_IBGP_ROUTEADV
5140 : BGP_DEFAULT_EBGP_ROUTEADV
;
5142 /* Update peer route announcements. */
5143 update_group_adjust_peer_afs(member
);
5144 if (member
->status
== Established
)
5145 bgp_announce_route_all(member
);
5151 /* neighbor interface */
5152 void peer_interface_set(struct peer
*peer
, const char *str
)
5154 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5155 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5158 void peer_interface_unset(struct peer
*peer
)
5160 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5161 peer
->ifname
= NULL
;
5165 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5166 int allow_num
, int origin
)
5168 struct peer
*member
;
5169 struct listnode
*node
, *nnode
;
5171 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5172 return BGP_ERR_INVALID_VALUE
;
5174 /* Set flag and configuration on peer. */
5175 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5177 if (peer
->allowas_in
[afi
][safi
] != 0
5178 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5179 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5180 peer_af_flag_set(peer
, afi
, safi
,
5181 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5182 peer
->allowas_in
[afi
][safi
] = 0;
5183 peer_on_policy_change(peer
, afi
, safi
, 0);
5186 if (peer
->allowas_in
[afi
][safi
] != allow_num
5187 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5188 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5190 peer_af_flag_unset(peer
, afi
, safi
,
5191 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5192 peer
->allowas_in
[afi
][safi
] = allow_num
;
5193 peer_on_policy_change(peer
, afi
, safi
, 0);
5197 /* Skip peer-group mechanics for regular peers. */
5198 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5202 * Set flag and configuration on all peer-group members, unless
5203 * they are explicitely overriding peer-group configuration.
5205 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5206 /* Skip peers with overridden configuration. */
5207 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5208 PEER_FLAG_ALLOWAS_IN
))
5211 /* Set flag and configuration on peer-group member. */
5212 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5214 if (member
->allowas_in
[afi
][safi
] != 0
5215 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5216 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5217 SET_FLAG(member
->af_flags
[afi
][safi
],
5218 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5219 member
->allowas_in
[afi
][safi
] = 0;
5220 peer_on_policy_change(peer
, afi
, safi
, 0);
5223 if (member
->allowas_in
[afi
][safi
] != allow_num
5224 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5225 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5226 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5227 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5228 member
->allowas_in
[afi
][safi
] = allow_num
;
5229 peer_on_policy_change(peer
, afi
, safi
, 0);
5237 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5239 struct peer
*member
;
5240 struct listnode
*node
, *nnode
;
5242 /* Skip peer if flag is already disabled. */
5243 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5246 /* Inherit configuration from peer-group if peer is member. */
5247 if (peer_group_active(peer
)) {
5248 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5249 peer_af_flag_inherit(peer
, afi
, safi
,
5250 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5251 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5252 peer_on_policy_change(peer
, afi
, safi
, 0);
5257 /* Remove flag and configuration from peer. */
5258 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5259 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5260 peer
->allowas_in
[afi
][safi
] = 0;
5261 peer_on_policy_change(peer
, afi
, safi
, 0);
5263 /* Skip peer-group mechanics if handling a regular peer. */
5264 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5268 * Remove flags and configuration from all peer-group members, unless
5269 * they are explicitely overriding peer-group configuration.
5271 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5272 /* Skip peers with overridden configuration. */
5273 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5274 PEER_FLAG_ALLOWAS_IN
))
5277 /* Skip peers where flag is already disabled. */
5278 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5279 PEER_FLAG_ALLOWAS_IN
))
5282 /* Remove flags and configuration on peer-group member. */
5283 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5284 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5285 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5286 member
->allowas_in
[afi
][safi
] = 0;
5287 peer_on_policy_change(member
, afi
, safi
, 0);
5293 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5296 bool old_no_prepend
, old_replace_as
;
5297 struct bgp
*bgp
= peer
->bgp
;
5298 struct peer
*member
;
5299 struct listnode
*node
, *nnode
;
5301 if (peer_sort(peer
) != BGP_PEER_EBGP
5302 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5303 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5306 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5309 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5311 /* Save previous flag states. */
5313 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5315 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5317 /* Set flag and configuration on peer. */
5318 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5319 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5320 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5322 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5323 && old_replace_as
== replace_as
)
5325 peer
->change_local_as
= as
;
5327 /* Check if handling a regular peer. */
5328 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5329 /* Send notification or reset peer depending on state. */
5330 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5331 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5332 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5333 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5335 bgp_session_reset(peer
);
5337 /* Skip peer-group mechanics for regular peers. */
5342 * Set flag and configuration on all peer-group members, unless they are
5343 * explicitely overriding peer-group configuration.
5345 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5346 /* Skip peers with overridden configuration. */
5347 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5350 /* Skip peers with the same configuration. */
5351 old_no_prepend
= CHECK_FLAG(member
->flags
,
5352 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5353 old_replace_as
= CHECK_FLAG(member
->flags
,
5354 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5355 if (member
->change_local_as
== as
5356 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5357 && old_no_prepend
== no_prepend
5358 && old_replace_as
== replace_as
)
5361 /* Set flag and configuration on peer-group member. */
5362 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5363 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5365 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5367 member
->change_local_as
= as
;
5369 /* Send notification or stop peer depending on state. */
5370 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5371 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5372 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5373 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5375 BGP_EVENT_ADD(member
, BGP_Stop
);
5381 int peer_local_as_unset(struct peer
*peer
)
5383 struct peer
*member
;
5384 struct listnode
*node
, *nnode
;
5386 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5389 /* Inherit configuration from peer-group if peer is member. */
5390 if (peer_group_active(peer
)) {
5391 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5392 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5393 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5394 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5396 /* Otherwise remove flag and configuration from peer. */
5397 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5398 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5399 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5400 peer
->change_local_as
= 0;
5403 /* Check if handling a regular peer. */
5404 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5405 /* Send notification or stop peer depending on state. */
5406 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5407 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5408 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5409 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5411 BGP_EVENT_ADD(peer
, BGP_Stop
);
5413 /* Skip peer-group mechanics for regular peers. */
5418 * Remove flag and configuration from all peer-group members, unless
5419 * they are explicitely overriding peer-group configuration.
5421 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5422 /* Skip peers with overridden configuration. */
5423 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5426 /* Remove flag and configuration on peer-group member. */
5427 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5428 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5429 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5430 member
->change_local_as
= 0;
5432 /* Send notification or stop peer depending on state. */
5433 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5434 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5435 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5436 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5438 bgp_session_reset(member
);
5444 /* Set password for authenticating with the peer. */
5445 int peer_password_set(struct peer
*peer
, const char *password
)
5447 struct peer
*member
;
5448 struct listnode
*node
, *nnode
;
5449 int len
= password
? strlen(password
) : 0;
5450 int ret
= BGP_SUCCESS
;
5452 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5453 return BGP_ERR_INVALID_VALUE
;
5455 /* Set flag and configuration on peer. */
5456 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5457 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5459 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5460 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5462 /* Check if handling a regular peer. */
5463 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5464 /* Send notification or reset peer depending on state. */
5465 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5466 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5467 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5469 bgp_session_reset(peer
);
5472 * Attempt to install password on socket and skip peer-group
5475 if (BGP_PEER_SU_UNSPEC(peer
))
5477 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5478 : BGP_ERR_TCPSIG_FAILED
;
5482 * Set flag and configuration on all peer-group members, unless they are
5483 * explicitely overriding peer-group configuration.
5485 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5486 /* Skip peers with overridden configuration. */
5487 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5490 /* Skip peers with the same password. */
5491 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5494 /* Set flag and configuration on peer-group member. */
5495 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5496 if (member
->password
)
5497 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5498 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5500 /* Send notification or reset peer depending on state. */
5501 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5502 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5503 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5505 bgp_session_reset(member
);
5507 /* Attempt to install password on socket. */
5508 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5509 ret
= BGP_ERR_TCPSIG_FAILED
;
5512 /* Set flag and configuration on all peer-group listen ranges */
5513 struct listnode
*ln
;
5516 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5517 bgp_md5_set_prefix(lr
, password
);
5518 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5519 bgp_md5_set_prefix(lr
, password
);
5524 int peer_password_unset(struct peer
*peer
)
5526 struct peer
*member
;
5527 struct listnode
*node
, *nnode
;
5529 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5532 /* Inherit configuration from peer-group if peer is member. */
5533 if (peer_group_active(peer
)) {
5534 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5535 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5536 MTYPE_PEER_PASSWORD
);
5538 /* Otherwise remove flag and configuration from peer. */
5539 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5540 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5543 /* Check if handling a regular peer. */
5544 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5545 /* Send notification or reset peer depending on state. */
5546 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5547 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5548 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5550 bgp_session_reset(peer
);
5552 /* Attempt to uninstall password on socket. */
5553 if (!BGP_PEER_SU_UNSPEC(peer
))
5554 bgp_md5_unset(peer
);
5556 /* Skip peer-group mechanics for regular peers. */
5561 * Remove flag and configuration from all peer-group members, unless
5562 * they are explicitely overriding peer-group configuration.
5564 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5565 /* Skip peers with overridden configuration. */
5566 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5569 /* Remove flag and configuration on peer-group member. */
5570 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5571 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5573 /* Send notification or reset peer depending on state. */
5574 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5575 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5576 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5578 bgp_session_reset(member
);
5580 /* Attempt to uninstall password on socket. */
5581 if (!BGP_PEER_SU_UNSPEC(member
))
5582 bgp_md5_unset(member
);
5585 /* Set flag and configuration on all peer-group listen ranges */
5586 struct listnode
*ln
;
5589 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5590 bgp_md5_unset_prefix(lr
);
5591 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5592 bgp_md5_unset_prefix(lr
);
5598 /* Set distribute list to the peer. */
5599 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5602 struct peer
*member
;
5603 struct bgp_filter
*filter
;
5604 struct listnode
*node
, *nnode
;
5606 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5607 return BGP_ERR_INVALID_VALUE
;
5609 /* Set configuration on peer. */
5610 filter
= &peer
->filter
[afi
][safi
];
5611 if (filter
->plist
[direct
].name
)
5612 return BGP_ERR_PEER_FILTER_CONFLICT
;
5613 if (filter
->dlist
[direct
].name
)
5614 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5615 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5616 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5618 /* Check if handling a regular peer. */
5619 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5620 /* Set override-flag and process peer route updates. */
5621 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5622 PEER_FT_DISTRIBUTE_LIST
);
5623 peer_on_policy_change(peer
, afi
, safi
,
5624 (direct
== FILTER_OUT
) ? 1 : 0);
5626 /* Skip peer-group mechanics for regular peers. */
5631 * Set configuration on all peer-group members, un less they are
5632 * explicitely overriding peer-group configuration.
5634 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5635 /* Skip peers with overridden configuration. */
5636 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5637 PEER_FT_DISTRIBUTE_LIST
))
5640 /* Set configuration on peer-group member. */
5641 filter
= &member
->filter
[afi
][safi
];
5642 if (filter
->dlist
[direct
].name
)
5643 XFREE(MTYPE_BGP_FILTER_NAME
,
5644 filter
->dlist
[direct
].name
);
5645 filter
->dlist
[direct
].name
=
5646 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5647 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5649 /* Process peer route updates. */
5650 peer_on_policy_change(member
, afi
, safi
,
5651 (direct
== FILTER_OUT
) ? 1 : 0);
5657 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5659 struct peer
*member
;
5660 struct bgp_filter
*filter
;
5661 struct listnode
*node
, *nnode
;
5663 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5664 return BGP_ERR_INVALID_VALUE
;
5666 /* Unset override-flag unconditionally. */
5667 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5668 PEER_FT_DISTRIBUTE_LIST
);
5670 /* Inherit configuration from peer-group if peer is member. */
5671 if (peer_group_active(peer
)) {
5672 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5673 filter
[afi
][safi
].dlist
[direct
].name
,
5674 MTYPE_BGP_FILTER_NAME
);
5675 PEER_ATTR_INHERIT(peer
, peer
->group
,
5676 filter
[afi
][safi
].dlist
[direct
].alist
);
5678 /* Otherwise remove configuration from peer. */
5679 filter
= &peer
->filter
[afi
][safi
];
5680 if (filter
->dlist
[direct
].name
)
5681 XFREE(MTYPE_BGP_FILTER_NAME
,
5682 filter
->dlist
[direct
].name
);
5683 filter
->dlist
[direct
].name
= NULL
;
5684 filter
->dlist
[direct
].alist
= NULL
;
5687 /* Check if handling a regular peer. */
5688 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5689 /* Process peer route updates. */
5690 peer_on_policy_change(peer
, afi
, safi
,
5691 (direct
== FILTER_OUT
) ? 1 : 0);
5693 /* Skip peer-group mechanics for regular peers. */
5698 * Remove configuration on all peer-group members, unless they are
5699 * explicitely overriding peer-group configuration.
5701 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5702 /* Skip peers with overridden configuration. */
5703 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5704 PEER_FT_DISTRIBUTE_LIST
))
5707 /* Remove configuration on peer-group member. */
5708 filter
= &member
->filter
[afi
][safi
];
5709 if (filter
->dlist
[direct
].name
)
5710 XFREE(MTYPE_BGP_FILTER_NAME
,
5711 filter
->dlist
[direct
].name
);
5712 filter
->dlist
[direct
].name
= NULL
;
5713 filter
->dlist
[direct
].alist
= NULL
;
5715 /* Process peer route updates. */
5716 peer_on_policy_change(member
, afi
, safi
,
5717 (direct
== FILTER_OUT
) ? 1 : 0);
5723 /* Update distribute list. */
5724 static void peer_distribute_update(struct access_list
*access
)
5729 struct listnode
*mnode
, *mnnode
;
5730 struct listnode
*node
, *nnode
;
5733 struct peer_group
*group
;
5734 struct bgp_filter
*filter
;
5736 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5738 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5739 access
->name
, 0, 0);
5740 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5741 FOREACH_AFI_SAFI (afi
, safi
) {
5742 filter
= &peer
->filter
[afi
][safi
];
5744 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5746 if (filter
->dlist
[direct
].name
)
5747 filter
->dlist
[direct
]
5748 .alist
= access_list_lookup(
5750 filter
->dlist
[direct
]
5753 filter
->dlist
[direct
].alist
=
5758 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5759 FOREACH_AFI_SAFI (afi
, safi
) {
5760 filter
= &group
->conf
->filter
[afi
][safi
];
5762 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5764 if (filter
->dlist
[direct
].name
)
5765 filter
->dlist
[direct
]
5766 .alist
= access_list_lookup(
5768 filter
->dlist
[direct
]
5771 filter
->dlist
[direct
].alist
=
5777 vnc_prefix_list_update(bgp
);
5782 /* Set prefix list to the peer. */
5783 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5786 struct peer
*member
;
5787 struct bgp_filter
*filter
;
5788 struct listnode
*node
, *nnode
;
5790 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5791 return BGP_ERR_INVALID_VALUE
;
5793 /* Set configuration on peer. */
5794 filter
= &peer
->filter
[afi
][safi
];
5795 if (filter
->dlist
[direct
].name
)
5796 return BGP_ERR_PEER_FILTER_CONFLICT
;
5797 if (filter
->plist
[direct
].name
)
5798 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5799 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5800 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5802 /* Check if handling a regular peer. */
5803 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5804 /* Set override-flag and process peer route updates. */
5805 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5806 PEER_FT_PREFIX_LIST
);
5807 peer_on_policy_change(peer
, afi
, safi
,
5808 (direct
== FILTER_OUT
) ? 1 : 0);
5810 /* Skip peer-group mechanics for regular peers. */
5815 * Set configuration on all peer-group members, unless they are
5816 * explicitely overriding peer-group configuration.
5818 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5819 /* Skip peers with overridden configuration. */
5820 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5821 PEER_FT_PREFIX_LIST
))
5824 /* Set configuration on peer-group member. */
5825 filter
= &member
->filter
[afi
][safi
];
5826 if (filter
->plist
[direct
].name
)
5827 XFREE(MTYPE_BGP_FILTER_NAME
,
5828 filter
->plist
[direct
].name
);
5829 filter
->plist
[direct
].name
=
5830 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5831 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5833 /* Process peer route updates. */
5834 peer_on_policy_change(member
, afi
, safi
,
5835 (direct
== FILTER_OUT
) ? 1 : 0);
5841 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5844 struct peer
*member
;
5845 struct bgp_filter
*filter
;
5846 struct listnode
*node
, *nnode
;
5848 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5849 return BGP_ERR_INVALID_VALUE
;
5851 /* Unset override-flag unconditionally. */
5852 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5853 PEER_FT_PREFIX_LIST
);
5855 /* Inherit configuration from peer-group if peer is member. */
5856 if (peer_group_active(peer
)) {
5857 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5858 filter
[afi
][safi
].plist
[direct
].name
,
5859 MTYPE_BGP_FILTER_NAME
);
5860 PEER_ATTR_INHERIT(peer
, peer
->group
,
5861 filter
[afi
][safi
].plist
[direct
].plist
);
5863 /* Otherwise remove configuration from peer. */
5864 filter
= &peer
->filter
[afi
][safi
];
5865 if (filter
->plist
[direct
].name
)
5866 XFREE(MTYPE_BGP_FILTER_NAME
,
5867 filter
->plist
[direct
].name
);
5868 filter
->plist
[direct
].name
= NULL
;
5869 filter
->plist
[direct
].plist
= NULL
;
5872 /* Check if handling a regular peer. */
5873 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5874 /* Process peer route updates. */
5875 peer_on_policy_change(peer
, afi
, safi
,
5876 (direct
== FILTER_OUT
) ? 1 : 0);
5878 /* Skip peer-group mechanics for regular peers. */
5883 * Remove configuration on all peer-group members, unless they are
5884 * explicitely overriding peer-group configuration.
5886 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5887 /* Skip peers with overridden configuration. */
5888 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5889 PEER_FT_PREFIX_LIST
))
5892 /* Remove configuration on peer-group member. */
5893 filter
= &member
->filter
[afi
][safi
];
5894 if (filter
->plist
[direct
].name
)
5895 XFREE(MTYPE_BGP_FILTER_NAME
,
5896 filter
->plist
[direct
].name
);
5897 filter
->plist
[direct
].name
= NULL
;
5898 filter
->plist
[direct
].plist
= NULL
;
5900 /* Process peer route updates. */
5901 peer_on_policy_change(member
, afi
, safi
,
5902 (direct
== FILTER_OUT
) ? 1 : 0);
5908 /* Update prefix-list list. */
5909 static void peer_prefix_list_update(struct prefix_list
*plist
)
5911 struct listnode
*mnode
, *mnnode
;
5912 struct listnode
*node
, *nnode
;
5915 struct peer_group
*group
;
5916 struct bgp_filter
*filter
;
5921 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5924 * Update the prefix-list on update groups.
5926 update_group_policy_update(
5927 bgp
, BGP_POLICY_PREFIX_LIST
,
5928 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5930 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5931 FOREACH_AFI_SAFI (afi
, safi
) {
5932 filter
= &peer
->filter
[afi
][safi
];
5934 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5936 if (filter
->plist
[direct
].name
)
5937 filter
->plist
[direct
]
5938 .plist
= prefix_list_lookup(
5940 filter
->plist
[direct
]
5943 filter
->plist
[direct
].plist
=
5948 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5949 FOREACH_AFI_SAFI (afi
, safi
) {
5950 filter
= &group
->conf
->filter
[afi
][safi
];
5952 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5954 if (filter
->plist
[direct
].name
)
5955 filter
->plist
[direct
]
5956 .plist
= prefix_list_lookup(
5958 filter
->plist
[direct
]
5961 filter
->plist
[direct
].plist
=
5969 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5972 struct peer
*member
;
5973 struct bgp_filter
*filter
;
5974 struct listnode
*node
, *nnode
;
5976 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5977 return BGP_ERR_INVALID_VALUE
;
5979 /* Set configuration on peer. */
5980 filter
= &peer
->filter
[afi
][safi
];
5981 if (filter
->aslist
[direct
].name
)
5982 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5983 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5984 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5986 /* Check if handling a regular peer. */
5987 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5988 /* Set override-flag and process peer route updates. */
5989 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5990 PEER_FT_FILTER_LIST
);
5991 peer_on_policy_change(peer
, afi
, safi
,
5992 (direct
== FILTER_OUT
) ? 1 : 0);
5994 /* Skip peer-group mechanics for regular peers. */
5999 * Set configuration on all peer-group members, unless they are
6000 * explicitely overriding peer-group configuration.
6002 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6003 /* Skip peers with overridden configuration. */
6004 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6005 PEER_FT_FILTER_LIST
))
6008 /* Set configuration on peer-group member. */
6009 filter
= &member
->filter
[afi
][safi
];
6010 if (filter
->aslist
[direct
].name
)
6011 XFREE(MTYPE_BGP_FILTER_NAME
,
6012 filter
->aslist
[direct
].name
);
6013 filter
->aslist
[direct
].name
=
6014 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6015 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
6017 /* Process peer route updates. */
6018 peer_on_policy_change(member
, afi
, safi
,
6019 (direct
== FILTER_OUT
) ? 1 : 0);
6025 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6027 struct peer
*member
;
6028 struct bgp_filter
*filter
;
6029 struct listnode
*node
, *nnode
;
6031 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
6032 return BGP_ERR_INVALID_VALUE
;
6034 /* Unset override-flag unconditionally. */
6035 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6036 PEER_FT_FILTER_LIST
);
6038 /* Inherit configuration from peer-group if peer is member. */
6039 if (peer_group_active(peer
)) {
6040 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6041 filter
[afi
][safi
].aslist
[direct
].name
,
6042 MTYPE_BGP_FILTER_NAME
);
6043 PEER_ATTR_INHERIT(peer
, peer
->group
,
6044 filter
[afi
][safi
].aslist
[direct
].aslist
);
6046 /* Otherwise remove configuration from peer. */
6047 filter
= &peer
->filter
[afi
][safi
];
6048 if (filter
->aslist
[direct
].name
)
6049 XFREE(MTYPE_BGP_FILTER_NAME
,
6050 filter
->aslist
[direct
].name
);
6051 filter
->aslist
[direct
].name
= NULL
;
6052 filter
->aslist
[direct
].aslist
= NULL
;
6055 /* Check if handling a regular peer. */
6056 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6057 /* Process peer route updates. */
6058 peer_on_policy_change(peer
, afi
, safi
,
6059 (direct
== FILTER_OUT
) ? 1 : 0);
6061 /* Skip peer-group mechanics for regular peers. */
6066 * Remove configuration on all peer-group members, unless they are
6067 * explicitely overriding peer-group configuration.
6069 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6070 /* Skip peers with overridden configuration. */
6071 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6072 PEER_FT_FILTER_LIST
))
6075 /* Remove configuration on peer-group member. */
6076 filter
= &member
->filter
[afi
][safi
];
6077 if (filter
->aslist
[direct
].name
)
6078 XFREE(MTYPE_BGP_FILTER_NAME
,
6079 filter
->aslist
[direct
].name
);
6080 filter
->aslist
[direct
].name
= NULL
;
6081 filter
->aslist
[direct
].aslist
= NULL
;
6083 /* Process peer route updates. */
6084 peer_on_policy_change(member
, afi
, safi
,
6085 (direct
== FILTER_OUT
) ? 1 : 0);
6091 static void peer_aslist_update(const char *aslist_name
)
6096 struct listnode
*mnode
, *mnnode
;
6097 struct listnode
*node
, *nnode
;
6100 struct peer_group
*group
;
6101 struct bgp_filter
*filter
;
6103 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6104 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6107 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6108 FOREACH_AFI_SAFI (afi
, safi
) {
6109 filter
= &peer
->filter
[afi
][safi
];
6111 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6113 if (filter
->aslist
[direct
].name
)
6114 filter
->aslist
[direct
]
6115 .aslist
= as_list_lookup(
6116 filter
->aslist
[direct
]
6119 filter
->aslist
[direct
].aslist
=
6124 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6125 FOREACH_AFI_SAFI (afi
, safi
) {
6126 filter
= &group
->conf
->filter
[afi
][safi
];
6128 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6130 if (filter
->aslist
[direct
].name
)
6131 filter
->aslist
[direct
]
6132 .aslist
= as_list_lookup(
6133 filter
->aslist
[direct
]
6136 filter
->aslist
[direct
].aslist
=
6144 static void peer_aslist_add(char *aslist_name
)
6146 peer_aslist_update(aslist_name
);
6147 route_map_notify_dependencies((char *)aslist_name
,
6148 RMAP_EVENT_ASLIST_ADDED
);
6151 static void peer_aslist_del(const char *aslist_name
)
6153 peer_aslist_update(aslist_name
);
6154 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6158 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6159 const char *name
, struct route_map
*route_map
)
6161 struct peer
*member
;
6162 struct bgp_filter
*filter
;
6163 struct listnode
*node
, *nnode
;
6165 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6166 return BGP_ERR_INVALID_VALUE
;
6168 /* Set configuration on peer. */
6169 filter
= &peer
->filter
[afi
][safi
];
6170 if (filter
->map
[direct
].name
) {
6171 /* If the neighbor is configured with the same route-map
6172 * again then, ignore the duplicate configuration.
6174 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6177 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6179 route_map_counter_decrement(filter
->map
[direct
].map
);
6180 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6181 filter
->map
[direct
].map
= route_map
;
6182 route_map_counter_increment(route_map
);
6184 /* Check if handling a regular peer. */
6185 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6186 /* Set override-flag and process peer route updates. */
6187 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6189 peer_on_policy_change(peer
, afi
, safi
,
6190 (direct
== RMAP_OUT
) ? 1 : 0);
6192 /* Skip peer-group mechanics for regular peers. */
6197 * Set configuration on all peer-group members, unless they are
6198 * explicitely overriding peer-group configuration.
6200 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6201 /* Skip peers with overridden configuration. */
6202 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6206 /* Set configuration on peer-group member. */
6207 filter
= &member
->filter
[afi
][safi
];
6208 if (filter
->map
[direct
].name
)
6209 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6210 route_map_counter_decrement(filter
->map
[direct
].map
);
6211 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6212 filter
->map
[direct
].map
= route_map
;
6213 route_map_counter_increment(route_map
);
6215 /* Process peer route updates. */
6216 peer_on_policy_change(member
, afi
, safi
,
6217 (direct
== RMAP_OUT
) ? 1 : 0);
6222 /* Unset route-map from the peer. */
6223 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6225 struct peer
*member
;
6226 struct bgp_filter
*filter
;
6227 struct listnode
*node
, *nnode
;
6229 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6230 return BGP_ERR_INVALID_VALUE
;
6232 /* Unset override-flag unconditionally. */
6233 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6235 /* Inherit configuration from peer-group if peer is member. */
6236 if (peer_group_active(peer
)) {
6237 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6238 filter
[afi
][safi
].map
[direct
].name
,
6239 MTYPE_BGP_FILTER_NAME
);
6240 PEER_ATTR_INHERIT(peer
, peer
->group
,
6241 filter
[afi
][safi
].map
[direct
].map
);
6243 /* Otherwise remove configuration from peer. */
6244 filter
= &peer
->filter
[afi
][safi
];
6245 if (filter
->map
[direct
].name
)
6246 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6247 route_map_counter_decrement(filter
->map
[direct
].map
);
6248 filter
->map
[direct
].name
= NULL
;
6249 filter
->map
[direct
].map
= NULL
;
6252 /* Check if handling a regular peer. */
6253 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6254 /* Process peer route updates. */
6255 peer_on_policy_change(peer
, afi
, safi
,
6256 (direct
== RMAP_OUT
) ? 1 : 0);
6258 /* Skip peer-group mechanics for regular peers. */
6263 * Remove configuration on all peer-group members, unless they are
6264 * explicitely overriding peer-group configuration.
6266 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6267 /* Skip peers with overridden configuration. */
6268 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6272 /* Remove configuration on peer-group member. */
6273 filter
= &member
->filter
[afi
][safi
];
6274 if (filter
->map
[direct
].name
)
6275 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6276 route_map_counter_decrement(filter
->map
[direct
].map
);
6277 filter
->map
[direct
].name
= NULL
;
6278 filter
->map
[direct
].map
= NULL
;
6280 /* Process peer route updates. */
6281 peer_on_policy_change(member
, afi
, safi
,
6282 (direct
== RMAP_OUT
) ? 1 : 0);
6288 /* Set unsuppress-map to the peer. */
6289 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6290 const char *name
, struct route_map
*route_map
)
6292 struct peer
*member
;
6293 struct bgp_filter
*filter
;
6294 struct listnode
*node
, *nnode
;
6296 /* Set configuration on peer. */
6297 filter
= &peer
->filter
[afi
][safi
];
6298 if (filter
->usmap
.name
)
6299 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6300 route_map_counter_decrement(filter
->usmap
.map
);
6301 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6302 filter
->usmap
.map
= route_map
;
6303 route_map_counter_increment(route_map
);
6305 /* Check if handling a regular peer. */
6306 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6307 /* Set override-flag and process peer route updates. */
6308 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6309 PEER_FT_UNSUPPRESS_MAP
);
6310 peer_on_policy_change(peer
, afi
, safi
, 1);
6312 /* Skip peer-group mechanics for regular peers. */
6317 * Set configuration on all peer-group members, unless they are
6318 * explicitely overriding peer-group configuration.
6320 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6321 /* Skip peers with overridden configuration. */
6322 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6323 PEER_FT_UNSUPPRESS_MAP
))
6326 /* Set configuration on peer-group member. */
6327 filter
= &member
->filter
[afi
][safi
];
6328 if (filter
->usmap
.name
)
6329 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6330 route_map_counter_decrement(filter
->usmap
.map
);
6331 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6332 filter
->usmap
.map
= route_map
;
6333 route_map_counter_increment(route_map
);
6335 /* Process peer route updates. */
6336 peer_on_policy_change(member
, afi
, safi
, 1);
6342 /* Unset route-map from the peer. */
6343 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6345 struct peer
*member
;
6346 struct bgp_filter
*filter
;
6347 struct listnode
*node
, *nnode
;
6349 /* Unset override-flag unconditionally. */
6350 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6352 /* Inherit configuration from peer-group if peer is member. */
6353 if (peer_group_active(peer
)) {
6354 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6355 filter
[afi
][safi
].usmap
.name
,
6356 MTYPE_BGP_FILTER_NAME
);
6357 PEER_ATTR_INHERIT(peer
, peer
->group
,
6358 filter
[afi
][safi
].usmap
.map
);
6360 /* Otherwise remove configuration from peer. */
6361 filter
= &peer
->filter
[afi
][safi
];
6362 if (filter
->usmap
.name
)
6363 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6364 route_map_counter_decrement(filter
->usmap
.map
);
6365 filter
->usmap
.name
= NULL
;
6366 filter
->usmap
.map
= NULL
;
6369 /* Check if handling a regular peer. */
6370 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6371 /* Process peer route updates. */
6372 peer_on_policy_change(peer
, afi
, safi
, 1);
6374 /* Skip peer-group mechanics for regular peers. */
6379 * Remove configuration on all peer-group members, unless they are
6380 * explicitely overriding peer-group configuration.
6382 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6383 /* Skip peers with overridden configuration. */
6384 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6385 PEER_FT_UNSUPPRESS_MAP
))
6388 /* Remove configuration on peer-group member. */
6389 filter
= &member
->filter
[afi
][safi
];
6390 if (filter
->usmap
.name
)
6391 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6392 route_map_counter_decrement(filter
->usmap
.map
);
6393 filter
->usmap
.name
= NULL
;
6394 filter
->usmap
.map
= NULL
;
6396 /* Process peer route updates. */
6397 peer_on_policy_change(member
, afi
, safi
, 1);
6403 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6404 uint32_t max
, uint8_t threshold
, int warning
,
6407 struct peer
*member
;
6408 struct listnode
*node
, *nnode
;
6410 /* Set flags and configuration on peer. */
6411 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6413 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6415 peer_af_flag_unset(peer
, afi
, safi
,
6416 PEER_FLAG_MAX_PREFIX_WARNING
);
6418 peer
->pmax
[afi
][safi
] = max
;
6419 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6420 peer
->pmax_restart
[afi
][safi
] = restart
;
6422 /* Check if handling a regular peer. */
6423 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6424 /* Re-check if peer violates maximum-prefix. */
6425 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6426 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6428 /* Skip peer-group mechanics for regular peers. */
6433 * Set flags and configuration on all peer-group members, unless they
6434 * are explicitely overriding peer-group configuration.
6436 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6437 /* Skip peers with overridden configuration. */
6438 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6439 PEER_FLAG_MAX_PREFIX
))
6442 /* Set flag and configuration on peer-group member. */
6443 member
->pmax
[afi
][safi
] = max
;
6444 member
->pmax_threshold
[afi
][safi
] = threshold
;
6445 member
->pmax_restart
[afi
][safi
] = restart
;
6447 SET_FLAG(member
->af_flags
[afi
][safi
],
6448 PEER_FLAG_MAX_PREFIX_WARNING
);
6450 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6451 PEER_FLAG_MAX_PREFIX_WARNING
);
6453 /* Re-check if peer violates maximum-prefix. */
6454 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6455 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6461 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6463 /* Inherit configuration from peer-group if peer is member. */
6464 if (peer_group_active(peer
)) {
6465 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6466 peer_af_flag_inherit(peer
, afi
, safi
,
6467 PEER_FLAG_MAX_PREFIX_WARNING
);
6468 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6469 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6470 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6475 /* Remove flags and configuration from peer. */
6476 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6477 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6478 peer
->pmax
[afi
][safi
] = 0;
6479 peer
->pmax_threshold
[afi
][safi
] = 0;
6480 peer
->pmax_restart
[afi
][safi
] = 0;
6483 * Remove flags and configuration from all peer-group members, unless
6484 * they are explicitely overriding peer-group configuration.
6486 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6487 struct peer
*member
;
6488 struct listnode
*node
;
6490 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6491 /* Skip peers with overridden configuration. */
6492 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6493 PEER_FLAG_MAX_PREFIX
))
6496 /* Remove flag and configuration on peer-group member.
6498 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6499 PEER_FLAG_MAX_PREFIX
);
6500 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6501 PEER_FLAG_MAX_PREFIX_WARNING
);
6502 member
->pmax
[afi
][safi
] = 0;
6503 member
->pmax_threshold
[afi
][safi
] = 0;
6504 member
->pmax_restart
[afi
][safi
] = 0;
6511 int is_ebgp_multihop_configured(struct peer
*peer
)
6513 struct peer_group
*group
;
6514 struct listnode
*node
, *nnode
;
6517 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6518 group
= peer
->group
;
6519 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6520 && (group
->conf
->ttl
!= 1))
6523 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6524 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6525 && (peer1
->ttl
!= 1))
6529 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6535 /* Set # of hops between us and BGP peer. */
6536 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6538 struct peer_group
*group
;
6539 struct listnode
*node
, *nnode
;
6542 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6543 gtsm_hops
, peer
->host
);
6545 /* We cannot configure ttl-security hops when ebgp-multihop is already
6546 set. For non peer-groups, the check is simple. For peer-groups,
6548 slightly messy, because we need to check both the peer-group
6550 and all peer-group members for any trace of ebgp-multihop
6552 before actually applying the ttl-security rules. Cisco really made a
6553 mess of this configuration parameter, and OpenBGPD got it right.
6556 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6557 if (is_ebgp_multihop_configured(peer
))
6558 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6560 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6561 peer
->gtsm_hops
= gtsm_hops
;
6563 /* Calling ebgp multihop also resets the session.
6564 * On restart, NHT will get setup correctly as will the
6565 * min & max ttls on the socket. The return value is
6568 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6573 group
= peer
->group
;
6574 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6576 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6578 /* Calling ebgp multihop also resets the
6580 * On restart, NHT will get setup correctly as
6582 * min & max ttls on the socket. The return
6586 peer_ebgp_multihop_set(peer
, MAXTTL
);
6590 /* Post the first gtsm setup or if its ibgp, maxttl setting
6592 * necessary, just set the minttl.
6594 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6595 peer
->gtsm_hops
= gtsm_hops
;
6598 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6599 MAXTTL
+ 1 - gtsm_hops
);
6600 if ((peer
->status
< Established
) && peer
->doppelganger
6601 && (peer
->doppelganger
->fd
>= 0))
6602 sockopt_minttl(peer
->su
.sa
.sa_family
,
6603 peer
->doppelganger
->fd
,
6604 MAXTTL
+ 1 - gtsm_hops
);
6606 group
= peer
->group
;
6607 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6609 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6611 /* Change setting of existing peer
6612 * established then change value (may break
6614 * not established yet (teardown session and
6616 * no session then do nothing (will get
6617 * handled by next connection)
6619 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6621 peer
->su
.sa
.sa_family
, peer
->fd
,
6622 MAXTTL
+ 1 - peer
->gtsm_hops
);
6623 if ((peer
->status
< Established
)
6624 && peer
->doppelganger
6625 && (peer
->doppelganger
->fd
>= 0))
6626 sockopt_minttl(peer
->su
.sa
.sa_family
,
6627 peer
->doppelganger
->fd
,
6628 MAXTTL
+ 1 - gtsm_hops
);
6636 int peer_ttl_security_hops_unset(struct peer
*peer
)
6638 struct peer_group
*group
;
6639 struct listnode
*node
, *nnode
;
6642 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6645 /* if a peer-group member, then reset to peer-group default rather than
6647 if (peer_group_active(peer
))
6648 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6650 peer
->gtsm_hops
= 0;
6652 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6653 /* Invoking ebgp_multihop_set will set the TTL back to the
6655 * value as well as restting the NHT and such. The session is
6658 if (peer
->sort
== BGP_PEER_EBGP
)
6659 ret
= peer_ebgp_multihop_unset(peer
);
6662 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6665 if ((peer
->status
< Established
) && peer
->doppelganger
6666 && (peer
->doppelganger
->fd
>= 0))
6667 sockopt_minttl(peer
->su
.sa
.sa_family
,
6668 peer
->doppelganger
->fd
, 0);
6671 group
= peer
->group
;
6672 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6673 peer
->gtsm_hops
= 0;
6674 if (peer
->sort
== BGP_PEER_EBGP
)
6675 ret
= peer_ebgp_multihop_unset(peer
);
6678 sockopt_minttl(peer
->su
.sa
.sa_family
,
6681 if ((peer
->status
< Established
)
6682 && peer
->doppelganger
6683 && (peer
->doppelganger
->fd
>= 0))
6684 sockopt_minttl(peer
->su
.sa
.sa_family
,
6685 peer
->doppelganger
->fd
,
6695 * If peer clear is invoked in a loop for all peers on the BGP instance,
6696 * it may end up freeing the doppelganger, and if this was the next node
6697 * to the current node, we would end up accessing the freed next node.
6698 * Pass along additional parameter which can be updated if next node
6699 * is freed; only required when walking the peer list on BGP instance.
6701 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6703 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6704 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6705 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6706 if (peer
->t_pmax_restart
) {
6707 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6708 if (bgp_debug_neighbor_events(peer
))
6710 "%s Maximum-prefix restart timer canceled",
6713 BGP_EVENT_ADD(peer
, BGP_Start
);
6717 peer
->v_start
= BGP_INIT_START_TIMER
;
6718 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6719 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6720 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6722 bgp_session_reset_safe(peer
, nnode
);
6727 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6728 enum bgp_clear_type stype
)
6730 struct peer_af
*paf
;
6732 if (peer
->status
!= Established
)
6735 if (!peer
->afc
[afi
][safi
])
6736 return BGP_ERR_AF_UNCONFIGURED
;
6738 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6740 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6741 /* Clear the "neighbor x.x.x.x default-originate" flag */
6742 paf
= peer_af_find(peer
, afi
, safi
);
6743 if (paf
&& paf
->subgroup
6744 && CHECK_FLAG(paf
->subgroup
->sflags
,
6745 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6746 UNSET_FLAG(paf
->subgroup
->sflags
,
6747 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6749 bgp_announce_route(peer
, afi
, safi
);
6752 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6753 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6754 PEER_CAP_ORF_PREFIX_SM_ADV
)
6755 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6756 PEER_CAP_ORF_PREFIX_RM_RCV
)
6757 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6758 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6759 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6760 uint8_t prefix_type
;
6762 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6763 PEER_CAP_ORF_PREFIX_RM_RCV
))
6764 prefix_type
= ORF_TYPE_PREFIX
;
6766 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6768 if (filter
->plist
[FILTER_IN
].plist
) {
6769 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6770 PEER_STATUS_ORF_PREFIX_SEND
))
6771 bgp_route_refresh_send(
6772 peer
, afi
, safi
, prefix_type
,
6774 bgp_route_refresh_send(peer
, afi
, safi
,
6776 REFRESH_IMMEDIATE
, 0);
6778 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6779 PEER_STATUS_ORF_PREFIX_SEND
))
6780 bgp_route_refresh_send(
6781 peer
, afi
, safi
, prefix_type
,
6782 REFRESH_IMMEDIATE
, 1);
6784 bgp_route_refresh_send(peer
, afi
, safi
,
6791 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6792 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6793 /* If neighbor has soft reconfiguration inbound flag.
6794 Use Adj-RIB-In database. */
6795 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6796 PEER_FLAG_SOFT_RECONFIG
))
6797 bgp_soft_reconfig_in(peer
, afi
, safi
);
6799 /* If neighbor has route refresh capability, send route
6801 message to the peer. */
6802 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6803 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6804 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6807 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6813 /* Display peer uptime.*/
6814 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6817 time_t uptime1
, epoch_tbuf
;
6820 /* If there is no connection has been done before print `never'. */
6823 json_object_string_add(json
, "peerUptime", "never");
6824 json_object_int_add(json
, "peerUptimeMsec", 0);
6826 snprintf(buf
, len
, "never");
6830 /* Get current time. */
6831 uptime1
= bgp_clock();
6833 tm
= gmtime(&uptime1
);
6835 if (uptime1
< ONE_DAY_SECOND
)
6836 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6838 else if (uptime1
< ONE_WEEK_SECOND
)
6839 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6841 else if (uptime1
< ONE_YEAR_SECOND
)
6842 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6843 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6845 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6847 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6850 epoch_tbuf
= time(NULL
) - uptime1
;
6851 json_object_string_add(json
, "peerUptime", buf
);
6852 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6853 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6860 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6861 afi_t afi
, safi_t safi
)
6863 struct bgp_filter
*filter
;
6867 filter
= &peer
->filter
[afi
][safi
];
6869 /* distribute-list. */
6870 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6872 vty_out(vty
, " neighbor %s distribute-list %s in\n", addr
,
6873 filter
->dlist
[FILTER_IN
].name
);
6875 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_DISTRIBUTE_LIST
,
6877 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6878 filter
->dlist
[FILTER_OUT
].name
);
6881 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6883 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6884 filter
->plist
[FILTER_IN
].name
);
6886 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_PREFIX_LIST
,
6888 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6889 filter
->plist
[FILTER_OUT
].name
);
6892 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
, RMAP_IN
))
6893 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6894 filter
->map
[RMAP_IN
].name
);
6896 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_ROUTE_MAP
,
6898 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6899 filter
->map
[RMAP_OUT
].name
);
6901 /* unsuppress-map */
6902 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_UNSUPPRESS_MAP
, 0))
6903 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6904 filter
->usmap
.name
);
6907 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6909 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6910 filter
->aslist
[FILTER_IN
].name
);
6912 if (peergroup_filter_check(peer
, afi
, safi
, PEER_FT_FILTER_LIST
,
6914 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6915 filter
->aslist
[FILTER_OUT
].name
);
6918 /* BGP peer configuration display function. */
6919 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6922 struct peer
*g_peer
= NULL
;
6923 char buf
[SU_ADDRSTRLEN
];
6925 int if_pg_printed
= FALSE
;
6926 int if_ras_printed
= FALSE
;
6928 /* Skip dynamic neighbors. */
6929 if (peer_dynamic_neighbor(peer
))
6933 addr
= peer
->conf_if
;
6937 /************************************
6938 ****** Global to the neighbor ******
6939 ************************************/
6940 if (peer
->conf_if
) {
6941 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6942 vty_out(vty
, " neighbor %s interface v6only", addr
);
6944 vty_out(vty
, " neighbor %s interface", addr
);
6946 if (peer_group_active(peer
)) {
6947 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6948 if_pg_printed
= TRUE
;
6949 } else if (peer
->as_type
== AS_SPECIFIED
) {
6950 vty_out(vty
, " remote-as %u", peer
->as
);
6951 if_ras_printed
= TRUE
;
6952 } else if (peer
->as_type
== AS_INTERNAL
) {
6953 vty_out(vty
, " remote-as internal");
6954 if_ras_printed
= TRUE
;
6955 } else if (peer
->as_type
== AS_EXTERNAL
) {
6956 vty_out(vty
, " remote-as external");
6957 if_ras_printed
= TRUE
;
6963 /* remote-as and peer-group */
6964 /* peer is a member of a peer-group */
6965 if (peer_group_active(peer
)) {
6966 g_peer
= peer
->group
->conf
;
6968 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6969 if (peer
->as_type
== AS_SPECIFIED
) {
6970 vty_out(vty
, " neighbor %s remote-as %u\n",
6972 } else if (peer
->as_type
== AS_INTERNAL
) {
6974 " neighbor %s remote-as internal\n",
6976 } else if (peer
->as_type
== AS_EXTERNAL
) {
6978 " neighbor %s remote-as external\n",
6983 /* For swpX peers we displayed the peer-group
6984 * via 'neighbor swpX interface peer-group PGNAME' */
6986 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6990 /* peer is NOT a member of a peer-group */
6992 /* peer is a peer-group, declare the peer-group */
6993 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6994 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6997 if (!if_ras_printed
) {
6998 if (peer
->as_type
== AS_SPECIFIED
) {
6999 vty_out(vty
, " neighbor %s remote-as %u\n",
7001 } else if (peer
->as_type
== AS_INTERNAL
) {
7003 " neighbor %s remote-as internal\n",
7005 } else if (peer
->as_type
== AS_EXTERNAL
) {
7007 " neighbor %s remote-as external\n",
7014 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS
)) {
7015 vty_out(vty
, " neighbor %s local-as %u", addr
,
7016 peer
->change_local_as
);
7017 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
7018 vty_out(vty
, " no-prepend");
7019 if (peergroup_flag_check(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
))
7020 vty_out(vty
, " replace-as");
7026 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
7030 if (peergroup_flag_check(peer
, PEER_FLAG_SHUTDOWN
)) {
7031 if (peer
->tx_shutdown_message
)
7032 vty_out(vty
, " neighbor %s shutdown message %s\n", addr
,
7033 peer
->tx_shutdown_message
);
7035 vty_out(vty
, " neighbor %s shutdown\n", addr
);
7039 if (peer
->bfd_info
) {
7040 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
7041 bgp_bfd_peer_config_write(vty
, peer
, addr
);
7046 if (peergroup_flag_check(peer
, PEER_FLAG_PASSWORD
))
7047 vty_out(vty
, " neighbor %s password %s\n", addr
,
7051 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
7052 if (!peer_group_active(peer
)) {
7053 vty_out(vty
, " neighbor %s solo\n", addr
);
7058 if (peer
->port
!= BGP_PORT_DEFAULT
) {
7059 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
7062 /* Local interface name */
7064 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
7068 if (peergroup_flag_check(peer
, PEER_FLAG_PASSIVE
))
7069 vty_out(vty
, " neighbor %s passive\n", addr
);
7072 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
7073 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
7074 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
7075 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
7080 /* ttl-security hops */
7081 if (peer
->gtsm_hops
!= 0) {
7082 if (!peer_group_active(peer
)
7083 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
7084 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
7085 addr
, peer
->gtsm_hops
);
7089 /* disable-connected-check */
7090 if (peergroup_flag_check(peer
, PEER_FLAG_DISABLE_CONNECTED_CHECK
))
7091 vty_out(vty
, " neighbor %s disable-connected-check\n", addr
);
7093 /* enforce-first-as */
7094 if (peergroup_flag_check(peer
, PEER_FLAG_ENFORCE_FIRST_AS
))
7095 vty_out(vty
, " neighbor %s enforce-first-as\n", addr
);
7098 if (peergroup_flag_check(peer
, PEER_FLAG_UPDATE_SOURCE
)) {
7099 if (peer
->update_source
)
7100 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7101 sockunion2str(peer
->update_source
, buf
,
7103 else if (peer
->update_if
)
7104 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
7108 /* advertisement-interval */
7109 if (peergroup_flag_check(peer
, PEER_FLAG_ROUTEADV
))
7110 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
7114 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER
))
7115 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
7116 peer
->keepalive
, peer
->holdtime
);
7118 /* timers connect */
7119 if (peergroup_flag_check(peer
, PEER_FLAG_TIMER_CONNECT
))
7120 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
7123 /* capability dynamic */
7124 if (peergroup_flag_check(peer
, PEER_FLAG_DYNAMIC_CAPABILITY
))
7125 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
7127 /* capability extended-nexthop */
7128 if (peergroup_flag_check(peer
, PEER_FLAG_CAPABILITY_ENHE
)) {
7129 if (!peer
->conf_if
) {
7130 if (CHECK_FLAG(peer
->flags_invert
,
7131 PEER_FLAG_CAPABILITY_ENHE
))
7133 " no neighbor %s capability extended-nexthop\n",
7137 " neighbor %s capability extended-nexthop\n",
7142 /* dont-capability-negotiation */
7143 if (peergroup_flag_check(peer
, PEER_FLAG_DONT_CAPABILITY
))
7144 vty_out(vty
, " neighbor %s dont-capability-negotiate\n", addr
);
7146 /* override-capability */
7147 if (peergroup_flag_check(peer
, PEER_FLAG_OVERRIDE_CAPABILITY
))
7148 vty_out(vty
, " neighbor %s override-capability\n", addr
);
7150 /* strict-capability-match */
7151 if (peergroup_flag_check(peer
, PEER_FLAG_STRICT_CAP_MATCH
))
7152 vty_out(vty
, " neighbor %s strict-capability-match\n", addr
);
7155 /* BGP peer configuration display function. */
7156 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
7157 struct peer
*peer
, afi_t afi
, safi_t safi
)
7159 struct peer
*g_peer
= NULL
;
7161 bool flag_scomm
, flag_secomm
, flag_slcomm
;
7163 /* Skip dynamic neighbors. */
7164 if (peer_dynamic_neighbor(peer
))
7168 addr
= peer
->conf_if
;
7172 /************************************
7173 ****** Per AF to the neighbor ******
7174 ************************************/
7175 if (peer_group_active(peer
)) {
7176 g_peer
= peer
->group
->conf
;
7178 /* If the peer-group is active but peer is not, print a 'no
7180 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
7181 vty_out(vty
, " no neighbor %s activate\n", addr
);
7184 /* If the peer-group is not active but peer is, print an
7186 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
7187 vty_out(vty
, " neighbor %s activate\n", addr
);
7190 if (peer
->afc
[afi
][safi
]) {
7191 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7192 if (bgp_flag_check(bgp
,
7193 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7194 vty_out(vty
, " neighbor %s activate\n",
7198 vty_out(vty
, " neighbor %s activate\n", addr
);
7200 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
7201 if (!bgp_flag_check(bgp
,
7202 BGP_FLAG_NO_DEFAULT_IPV4
)) {
7204 " no neighbor %s activate\n",
7211 /* addpath TX knobs */
7212 if (peergroup_af_addpath_check(peer
, afi
, safi
)) {
7213 switch (peer
->addpath_type
[afi
][safi
]) {
7214 case BGP_ADDPATH_ALL
:
7215 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n",
7218 case BGP_ADDPATH_BEST_PER_AS
:
7220 " neighbor %s addpath-tx-bestpath-per-AS\n",
7223 case BGP_ADDPATH_MAX
:
7224 case BGP_ADDPATH_NONE
:
7229 /* ORF capability. */
7230 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
7231 || peergroup_af_flag_check(peer
, afi
, safi
,
7232 PEER_FLAG_ORF_PREFIX_RM
)) {
7233 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
7235 if (peergroup_af_flag_check(peer
, afi
, safi
,
7236 PEER_FLAG_ORF_PREFIX_SM
)
7237 && peergroup_af_flag_check(peer
, afi
, safi
,
7238 PEER_FLAG_ORF_PREFIX_RM
))
7239 vty_out(vty
, " both");
7240 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7241 PEER_FLAG_ORF_PREFIX_SM
))
7242 vty_out(vty
, " send");
7244 vty_out(vty
, " receive");
7248 /* Route reflector client. */
7249 if (peergroup_af_flag_check(peer
, afi
, safi
,
7250 PEER_FLAG_REFLECTOR_CLIENT
)) {
7251 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
7254 /* next-hop-self force */
7255 if (peergroup_af_flag_check(peer
, afi
, safi
,
7256 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
7257 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
7261 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
7262 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
7265 /* remove-private-AS */
7266 if (peergroup_af_flag_check(peer
, afi
, safi
,
7267 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
7268 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
7272 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7273 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
7274 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
7278 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7279 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
7280 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
7283 else if (peergroup_af_flag_check(peer
, afi
, safi
,
7284 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
7285 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
7289 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
7290 vty_out(vty
, " neighbor %s as-override\n", addr
);
7293 /* send-community print. */
7294 flag_scomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7295 PEER_FLAG_SEND_COMMUNITY
);
7296 flag_secomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7297 PEER_FLAG_SEND_EXT_COMMUNITY
);
7298 flag_slcomm
= peergroup_af_flag_check(peer
, afi
, safi
,
7299 PEER_FLAG_SEND_LARGE_COMMUNITY
);
7301 if (flag_scomm
&& flag_secomm
&& flag_slcomm
) {
7302 vty_out(vty
, " no neighbor %s send-community all\n", addr
);
7305 vty_out(vty
, " no neighbor %s send-community\n", addr
);
7308 " no neighbor %s send-community extended\n",
7312 vty_out(vty
, " no neighbor %s send-community large\n",
7316 /* Default information */
7317 if (peergroup_af_flag_check(peer
, afi
, safi
,
7318 PEER_FLAG_DEFAULT_ORIGINATE
)) {
7319 vty_out(vty
, " neighbor %s default-originate", addr
);
7321 if (peer
->default_rmap
[afi
][safi
].name
)
7322 vty_out(vty
, " route-map %s",
7323 peer
->default_rmap
[afi
][safi
].name
);
7328 /* Soft reconfiguration inbound. */
7329 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7330 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7334 /* maximum-prefix. */
7335 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
)) {
7336 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7337 peer
->pmax
[afi
][safi
]);
7339 if (peer
->pmax_threshold
[afi
][safi
]
7340 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7341 vty_out(vty
, " %u", peer
->pmax_threshold
[afi
][safi
]);
7342 if (peer_af_flag_check(peer
, afi
, safi
,
7343 PEER_FLAG_MAX_PREFIX_WARNING
))
7344 vty_out(vty
, " warning-only");
7345 if (peer
->pmax_restart
[afi
][safi
])
7346 vty_out(vty
, " restart %u",
7347 peer
->pmax_restart
[afi
][safi
]);
7352 /* Route server client. */
7353 if (peergroup_af_flag_check(peer
, afi
, safi
,
7354 PEER_FLAG_RSERVER_CLIENT
)) {
7355 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7358 /* Nexthop-local unchanged. */
7359 if (peergroup_af_flag_check(peer
, afi
, safi
,
7360 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7361 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7364 /* allowas-in <1-10> */
7365 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7366 if (peer_af_flag_check(peer
, afi
, safi
,
7367 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7368 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7369 } else if (peer
->allowas_in
[afi
][safi
] == 3) {
7370 vty_out(vty
, " neighbor %s allowas-in\n", addr
);
7372 vty_out(vty
, " neighbor %s allowas-in %d\n", addr
,
7373 peer
->allowas_in
[afi
][safi
]);
7378 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7379 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7380 peer
->weight
[afi
][safi
]);
7383 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7385 /* atribute-unchanged. */
7386 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7387 || (safi
!= SAFI_EVPN
7388 && peer_af_flag_check(peer
, afi
, safi
,
7389 PEER_FLAG_NEXTHOP_UNCHANGED
))
7390 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7392 if (!peer_group_active(peer
)
7393 || peergroup_af_flag_check(peer
, afi
, safi
,
7394 PEER_FLAG_AS_PATH_UNCHANGED
)
7395 || peergroup_af_flag_check(peer
, afi
, safi
,
7396 PEER_FLAG_NEXTHOP_UNCHANGED
)
7397 || peergroup_af_flag_check(peer
, afi
, safi
,
7398 PEER_FLAG_MED_UNCHANGED
)) {
7401 " neighbor %s attribute-unchanged%s%s%s\n",
7403 peer_af_flag_check(peer
, afi
, safi
,
7404 PEER_FLAG_AS_PATH_UNCHANGED
)
7407 peer_af_flag_check(peer
, afi
, safi
,
7408 PEER_FLAG_NEXTHOP_UNCHANGED
)
7411 peer_af_flag_check(peer
, afi
, safi
,
7412 PEER_FLAG_MED_UNCHANGED
)
7419 /* Address family based peer configuration display. */
7420 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7424 struct peer_group
*group
;
7425 struct listnode
*node
, *nnode
;
7428 vty_frame(vty
, " !\n address-family ");
7429 if (afi
== AFI_IP
) {
7430 if (safi
== SAFI_UNICAST
)
7431 vty_frame(vty
, "ipv4 unicast");
7432 else if (safi
== SAFI_LABELED_UNICAST
)
7433 vty_frame(vty
, "ipv4 labeled-unicast");
7434 else if (safi
== SAFI_MULTICAST
)
7435 vty_frame(vty
, "ipv4 multicast");
7436 else if (safi
== SAFI_MPLS_VPN
)
7437 vty_frame(vty
, "ipv4 vpn");
7438 else if (safi
== SAFI_ENCAP
)
7439 vty_frame(vty
, "ipv4 encap");
7440 else if (safi
== SAFI_FLOWSPEC
)
7441 vty_frame(vty
, "ipv4 flowspec");
7442 } else if (afi
== AFI_IP6
) {
7443 if (safi
== SAFI_UNICAST
)
7444 vty_frame(vty
, "ipv6 unicast");
7445 else if (safi
== SAFI_LABELED_UNICAST
)
7446 vty_frame(vty
, "ipv6 labeled-unicast");
7447 else if (safi
== SAFI_MULTICAST
)
7448 vty_frame(vty
, "ipv6 multicast");
7449 else if (safi
== SAFI_MPLS_VPN
)
7450 vty_frame(vty
, "ipv6 vpn");
7451 else if (safi
== SAFI_ENCAP
)
7452 vty_frame(vty
, "ipv6 encap");
7453 else if (safi
== SAFI_FLOWSPEC
)
7454 vty_frame(vty
, "ipv6 flowspec");
7455 } else if (afi
== AFI_L2VPN
) {
7456 if (safi
== SAFI_EVPN
)
7457 vty_frame(vty
, "l2vpn evpn");
7459 vty_frame(vty
, "\n");
7461 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7463 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7465 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7467 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7468 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7470 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7471 /* Skip dynamic neighbors. */
7472 if (peer_dynamic_neighbor(peer
))
7475 /* Do not display doppelganger peers */
7476 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7477 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7480 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7481 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7483 if (safi
== SAFI_EVPN
)
7484 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7486 if (safi
== SAFI_FLOWSPEC
)
7487 bgp_fs_config_write_pbr(vty
, bgp
, afi
, safi
);
7489 if (safi
== SAFI_UNICAST
) {
7490 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7491 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7492 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7494 vty_out(vty
, " export vpn\n");
7496 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7497 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7499 vty_out(vty
, " import vpn\n");
7501 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7502 BGP_CONFIG_VRF_TO_VRF_IMPORT
)) {
7505 for (ALL_LIST_ELEMENTS_RO(
7506 bgp
->vpn_policy
[afi
].import_vrf
, node
,
7508 vty_out(vty
, " import vrf %s\n", name
);
7512 vty_endframe(vty
, " exit-address-family\n");
7515 int bgp_config_write(struct vty
*vty
)
7519 struct peer_group
*group
;
7521 struct listnode
*node
, *nnode
;
7522 struct listnode
*mnode
, *mnnode
;
7524 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7525 vty_out(vty
, "bgp route-map delay-timer %u\n",
7526 bm
->rmap_update_timer
);
7529 vty_out(vty
, "!\n");
7531 /* BGP configuration. */
7532 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7534 /* skip all auto created vrf as they dont have user config */
7535 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7538 /* Router bgp ASN */
7539 vty_out(vty
, "router bgp %u", bgp
->as
);
7542 vty_out(vty
, " %s %s",
7543 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
)
7544 ? "view" : "vrf", bgp
->name
);
7547 /* BGP fast-external-failover. */
7548 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7549 vty_out(vty
, " no bgp fast-external-failover\n");
7551 /* BGP router ID. */
7552 if (bgp
->router_id_static
.s_addr
!= 0)
7553 vty_out(vty
, " bgp router-id %s\n",
7554 inet_ntoa(bgp
->router_id_static
));
7556 /* BGP log-neighbor-changes. */
7557 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7558 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7559 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7561 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7565 /* BGP configuration. */
7566 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7567 vty_out(vty
, " bgp always-compare-med\n");
7569 /* RFC8212 default eBGP policy. */
7570 if (bgp
->ebgp_requires_policy
7571 == DEFAULT_EBGP_POLICY_ENABLED
)
7572 vty_out(vty
, " bgp ebgp-requires-policy\n");
7574 /* BGP default ipv4-unicast. */
7575 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7576 vty_out(vty
, " no bgp default ipv4-unicast\n");
7578 /* BGP default local-preference. */
7579 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7580 vty_out(vty
, " bgp default local-preference %u\n",
7581 bgp
->default_local_pref
);
7583 /* BGP default show-hostname */
7584 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7585 != DFLT_BGP_SHOW_HOSTNAME
)
7586 vty_out(vty
, " %sbgp default show-hostname\n",
7587 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7591 /* BGP default subgroup-pkt-queue-max. */
7592 if (bgp
->default_subgroup_pkt_queue_max
7593 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7594 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7595 bgp
->default_subgroup_pkt_queue_max
);
7597 /* BGP client-to-client reflection. */
7598 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7599 vty_out(vty
, " no bgp client-to-client reflection\n");
7601 /* BGP cluster ID. */
7602 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7603 vty_out(vty
, " bgp cluster-id %s\n",
7604 inet_ntoa(bgp
->cluster_id
));
7606 /* Disable ebgp connected nexthop check */
7607 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7609 " bgp disable-ebgp-connected-route-check\n");
7611 /* Confederation identifier*/
7612 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7613 vty_out(vty
, " bgp confederation identifier %u\n",
7616 /* Confederation peer */
7617 if (bgp
->confed_peers_cnt
> 0) {
7620 vty_out(vty
, " bgp confederation peers");
7622 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7623 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7628 /* BGP deterministic-med. */
7629 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7630 != DFLT_BGP_DETERMINISTIC_MED
)
7631 vty_out(vty
, " %sbgp deterministic-med\n",
7632 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7636 /* BGP update-delay. */
7637 bgp_config_write_update_delay(vty
, bgp
);
7639 if (bgp
->v_maxmed_onstartup
7640 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7641 vty_out(vty
, " bgp max-med on-startup %u",
7642 bgp
->v_maxmed_onstartup
);
7643 if (bgp
->maxmed_onstartup_value
7644 != BGP_MAXMED_VALUE_DEFAULT
)
7646 bgp
->maxmed_onstartup_value
);
7649 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7650 vty_out(vty
, " bgp max-med administrative");
7651 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7652 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7657 bgp_config_write_wpkt_quanta(vty
, bgp
);
7659 bgp_config_write_rpkt_quanta(vty
, bgp
);
7662 bgp_config_write_coalesce_time(vty
, bgp
);
7664 /* BGP graceful-restart. */
7665 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7667 " bgp graceful-restart stalepath-time %u\n",
7668 bgp
->stalepath_time
);
7669 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7670 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7672 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7673 vty_out(vty
, " bgp graceful-restart\n");
7675 /* BGP graceful-shutdown */
7676 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7677 vty_out(vty
, " bgp graceful-shutdown\n");
7679 /* BGP graceful-restart Preserve State F bit. */
7680 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7682 " bgp graceful-restart preserve-fw-state\n");
7684 /* BGP bestpath method. */
7685 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7686 vty_out(vty
, " bgp bestpath as-path ignore\n");
7687 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7688 vty_out(vty
, " bgp bestpath as-path confed\n");
7690 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7691 if (bgp_flag_check(bgp
,
7692 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7694 " bgp bestpath as-path multipath-relax as-set\n");
7697 " bgp bestpath as-path multipath-relax\n");
7701 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7703 " bgp route-reflector allow-outbound-policy\n");
7705 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7706 vty_out(vty
, " bgp bestpath compare-routerid\n");
7707 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7708 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7709 vty_out(vty
, " bgp bestpath med");
7710 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7711 vty_out(vty
, " confed");
7712 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7713 vty_out(vty
, " missing-as-worst");
7717 /* BGP network import check. */
7718 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7719 != DFLT_BGP_IMPORT_CHECK
)
7720 vty_out(vty
, " %sbgp network import-check\n",
7721 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7725 /* BGP flag dampening. */
7726 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7727 BGP_CONFIG_DAMPENING
))
7728 bgp_config_write_damp(vty
);
7730 /* BGP timers configuration. */
7731 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7732 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7733 vty_out(vty
, " timers bgp %u %u\n",
7734 bgp
->default_keepalive
, bgp
->default_holdtime
);
7737 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7738 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7741 /* Normal neighbor configuration. */
7742 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7743 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7744 bgp_config_write_peer_global(vty
, bgp
, peer
);
7747 /* listen range and limit for dynamic BGP neighbors */
7748 bgp_config_write_listen(vty
, bgp
);
7751 * BGP default autoshutdown neighbors
7753 * This must be placed after any peer and peer-group
7754 * configuration, to avoid setting all peers to shutdown after
7755 * a daemon restart, which is undesired behavior. (see #2286)
7757 if (bgp
->autoshutdown
)
7758 vty_out(vty
, " bgp default shutdown\n");
7760 /* IPv4 unicast configuration. */
7761 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7763 /* IPv4 multicast configuration. */
7764 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7766 /* IPv4 labeled-unicast configuration. */
7767 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7769 /* IPv4 VPN configuration. */
7770 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7772 /* ENCAPv4 configuration. */
7773 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7775 /* FLOWSPEC v4 configuration. */
7776 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7778 /* IPv6 unicast configuration. */
7779 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7781 /* IPv6 multicast configuration. */
7782 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7784 /* IPv6 labeled-unicast configuration. */
7785 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7786 SAFI_LABELED_UNICAST
);
7788 /* IPv6 VPN configuration. */
7789 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7791 /* ENCAPv6 configuration. */
7792 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7794 /* FLOWSPEC v6 configuration. */
7795 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7797 /* EVPN configuration. */
7798 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7801 bgp_rfapi_cfg_write(vty
, bgp
);
7804 vty_out(vty
, "!\n");
7809 void bgp_master_init(struct thread_master
*master
)
7813 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7816 bm
->bgp
= list_new();
7817 bm
->listen_sockets
= list_new();
7818 bm
->port
= BGP_PORT_DEFAULT
;
7819 bm
->master
= master
;
7820 bm
->start_time
= bgp_clock();
7821 bm
->t_rmap_update
= NULL
;
7822 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7823 bm
->terminating
= false;
7825 bgp_process_queue_init();
7828 /* init the rd id space.
7829 assign 0th index in the bitfield,
7830 so that we start with id 1
7832 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7833 bf_assign_zero_index(bm
->rd_idspace
);
7835 /* mpls label dynamic allocation pool */
7836 bgp_lp_init(bm
->master
, &bm
->labelpool
);
7838 QOBJ_REG(bm
, bgp_master
);
7842 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7843 * instance delete (non-default only) or BGP exit.
7845 static void bgp_if_finish(struct bgp
*bgp
)
7848 struct interface
*ifp
;
7850 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
7852 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7855 FOR_ALL_INTERFACES (vrf
, ifp
) {
7856 struct listnode
*c_node
, *c_nnode
;
7857 struct connected
*c
;
7859 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7860 bgp_connected_delete(bgp
, c
);
7864 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7866 struct vrf
*vrf
= NULL
;
7867 struct listnode
*next
;
7870 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
7871 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7873 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7874 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7877 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7881 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7882 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7883 {.completions
= NULL
},
7886 struct frr_pthread
*bgp_pth_io
;
7887 struct frr_pthread
*bgp_pth_ka
;
7889 static void bgp_pthreads_init(void)
7891 assert(!bgp_pth_io
);
7892 assert(!bgp_pth_ka
);
7896 struct frr_pthread_attr io
= {
7897 .start
= frr_pthread_attr_default
.start
,
7898 .stop
= frr_pthread_attr_default
.stop
,
7900 struct frr_pthread_attr ka
= {
7901 .start
= bgp_keepalives_start
,
7902 .stop
= bgp_keepalives_stop
,
7904 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
7905 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
7908 void bgp_pthreads_run(void)
7910 frr_pthread_run(bgp_pth_io
, NULL
);
7911 frr_pthread_run(bgp_pth_ka
, NULL
);
7913 /* Wait until threads are ready. */
7914 frr_pthread_wait_running(bgp_pth_io
);
7915 frr_pthread_wait_running(bgp_pth_ka
);
7918 void bgp_pthreads_finish(void)
7920 frr_pthread_stop_all();
7921 frr_pthread_finish();
7924 void bgp_init(unsigned short instance
)
7927 /* allocates some vital data structures used by peer commands in
7930 /* pre-init pthreads */
7931 bgp_pthreads_init();
7934 bgp_zebra_init(bm
->master
, instance
);
7937 vnc_zebra_init(bm
->master
);
7940 /* BGP VTY commands installation. */
7948 bgp_route_map_init();
7949 bgp_scan_vty_init();
7954 bgp_ethernetvpn_init();
7955 bgp_flowspec_vty_init();
7957 /* Access list initialize. */
7959 access_list_add_hook(peer_distribute_update
);
7960 access_list_delete_hook(peer_distribute_update
);
7962 /* Filter list initialize. */
7964 as_list_add_hook(peer_aslist_add
);
7965 as_list_delete_hook(peer_aslist_del
);
7967 /* Prefix list initialize.*/
7969 prefix_list_add_hook(peer_prefix_list_update
);
7970 prefix_list_delete_hook(peer_prefix_list_update
);
7972 /* Community list initialize. */
7973 bgp_clist
= community_list_init();
7978 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7981 void bgp_terminate(void)
7985 struct listnode
*node
, *nnode
;
7986 struct listnode
*mnode
, *mnnode
;
7990 /* Close the listener sockets first as this prevents peers from
7992 * to reconnect on receiving the peer unconfig message. In the presence
7993 * of a large number of peers this will ensure that no peer is left with
7994 * a dangling connection
7996 /* reverse bgp_master_init */
7999 if (bm
->listen_sockets
)
8000 list_delete(&bm
->listen_sockets
);
8002 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
8003 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
8004 if (peer
->status
== Established
8005 || peer
->status
== OpenSent
8006 || peer
->status
== OpenConfirm
)
8007 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
8008 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
8010 if (bm
->process_main_queue
)
8011 work_queue_free_and_null(&bm
->process_main_queue
);
8013 if (bm
->t_rmap_update
)
8014 BGP_TIMER_OFF(bm
->t_rmap_update
);