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
)
97 DEFINE_HOOK(bgp_inst_delete
, (struct bgp
*bgp
), (bgp
))
99 /* BGP process wide configuration. */
100 static struct bgp_master bgp_master
;
102 /* BGP process wide configuration pointer to export. */
103 struct bgp_master
*bm
;
105 /* BGP community-list. */
106 struct community_list_handler
*bgp_clist
;
108 unsigned int multipath_num
= MULTIPATH_NUM
;
110 static void bgp_if_finish(struct bgp
*bgp
);
111 static void peer_drop_dynamic_neighbor(struct peer
*peer
);
113 extern struct zclient
*zclient
;
115 /* handle main socket creation or deletion */
116 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
118 static int bgp_server_main_created
;
121 if (bgp_server_main_created
)
123 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
124 return BGP_ERR_INVALID_VALUE
;
125 bgp_server_main_created
= 1;
128 if (!bgp_server_main_created
)
131 bgp_server_main_created
= 0;
135 void bgp_session_reset(struct peer
*peer
)
137 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
138 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
139 peer_delete(peer
->doppelganger
);
141 BGP_EVENT_ADD(peer
, BGP_Stop
);
145 * During session reset, we may delete the doppelganger peer, which would
146 * be the next node to the current node. If the session reset was invoked
147 * during walk of peer list, we would end up accessing the freed next
148 * node. This function moves the next node along.
150 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
155 n
= (nnode
) ? *nnode
: NULL
;
156 npeer
= (n
) ? listgetdata(n
) : NULL
;
158 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
159 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
160 PEER_FLAG_CONFIG_NODE
))) {
161 if (peer
->doppelganger
== npeer
)
162 /* nnode and *nnode are confirmed to be non-NULL here */
163 *nnode
= (*nnode
)->next
;
164 peer_delete(peer
->doppelganger
);
167 BGP_EVENT_ADD(peer
, BGP_Stop
);
170 /* BGP global flag manipulation. */
171 int bgp_option_set(int flag
)
175 case BGP_OPT_NO_LISTEN
:
176 case BGP_OPT_NO_ZEBRA
:
177 SET_FLAG(bm
->options
, flag
);
180 return BGP_ERR_INVALID_FLAG
;
185 int bgp_option_unset(int flag
)
189 case BGP_OPT_NO_ZEBRA
:
191 UNSET_FLAG(bm
->options
, flag
);
194 return BGP_ERR_INVALID_FLAG
;
199 int bgp_option_check(int flag
)
201 return CHECK_FLAG(bm
->options
, flag
);
204 /* BGP flag manipulation. */
205 int bgp_flag_set(struct bgp
*bgp
, int flag
)
207 SET_FLAG(bgp
->flags
, flag
);
211 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
213 UNSET_FLAG(bgp
->flags
, flag
);
217 int bgp_flag_check(struct bgp
*bgp
, int flag
)
219 return CHECK_FLAG(bgp
->flags
, flag
);
222 /* Internal function to set BGP structure configureation flag. */
223 static void bgp_config_set(struct bgp
*bgp
, int config
)
225 SET_FLAG(bgp
->config
, config
);
228 static void bgp_config_unset(struct bgp
*bgp
, int config
)
230 UNSET_FLAG(bgp
->config
, config
);
233 static int bgp_config_check(struct bgp
*bgp
, int config
)
235 return CHECK_FLAG(bgp
->config
, config
);
238 /* Set BGP router identifier; distinguish between explicit config and other
241 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
,
245 struct listnode
*node
, *nnode
;
247 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
250 /* EVPN uses router id in RD, withdraw them */
251 if (is_evpn_enabled())
252 bgp_evpn_handle_router_id_update(bgp
, true);
254 vpn_handle_router_id_update(bgp
, true, is_config
);
256 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
258 /* Set all peer's local identifier with this value. */
259 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
260 IPV4_ADDR_COPY(&peer
->local_id
, id
);
262 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
263 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
264 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
265 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
269 /* EVPN uses router id in RD, update them */
270 if (is_evpn_enabled())
271 bgp_evpn_handle_router_id_update(bgp
, false);
273 vpn_handle_router_id_update(bgp
, false, is_config
);
278 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
280 struct listnode
*node
, *nnode
;
282 struct in_addr
*addr
= NULL
;
284 if (router_id
!= NULL
)
285 addr
= (struct in_addr
*)&(router_id
->u
.prefix4
);
287 if (vrf_id
== VRF_DEFAULT
) {
288 /* Router-id change for default VRF has to also update all
290 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
291 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
295 bgp
->router_id_zebra
= *addr
;
297 addr
= &bgp
->router_id_zebra
;
299 if (!bgp
->router_id_static
.s_addr
) {
300 /* Router ID is updated if there are no active
303 if (bgp
->established_peers
== 0) {
304 if (BGP_DEBUG(zebra
, ZEBRA
))
305 zlog_debug("RID change : vrf %u, RTR ID %s",
306 bgp
->vrf_id
, inet_ntoa(*addr
));
307 bgp_router_id_set(bgp
, addr
, false);
312 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
315 bgp
->router_id_zebra
= *addr
;
317 addr
= &bgp
->router_id_zebra
;
319 if (!bgp
->router_id_static
.s_addr
) {
320 /* Router ID is updated if there are no active
323 if (bgp
->established_peers
== 0) {
324 if (BGP_DEBUG(zebra
, ZEBRA
))
325 zlog_debug("RID change : vrf %u, RTR ID %s",
326 bgp
->vrf_id
, inet_ntoa(*addr
));
327 bgp_router_id_set(bgp
, addr
, false);
335 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
337 bgp
->router_id_static
= id
;
338 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
,
339 true /* is config */);
343 /* BGP's cluster-id control. */
344 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
347 struct listnode
*node
, *nnode
;
349 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
350 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
353 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
354 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
356 /* Clear all IBGP peer. */
357 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
358 if (peer
->sort
!= BGP_PEER_IBGP
)
361 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
362 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
363 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
364 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
370 int bgp_cluster_id_unset(struct bgp
*bgp
)
373 struct listnode
*node
, *nnode
;
375 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
378 bgp
->cluster_id
.s_addr
= 0;
379 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
381 /* Clear all IBGP peer. */
382 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
383 if (peer
->sort
!= BGP_PEER_IBGP
)
386 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
387 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
388 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
389 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
395 /* time_t value that is monotonicly increasing
396 * and uneffected by adjustments to system clock
398 time_t bgp_clock(void)
406 /* BGP timer configuration. */
407 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
,
408 uint32_t connect_retry
)
410 bgp
->default_keepalive
=
411 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
412 bgp
->default_holdtime
= holdtime
;
413 bgp
->default_connect_retry
= connect_retry
;
418 /* mostly for completeness - CLI uses its own defaults */
419 int bgp_timers_unset(struct bgp
*bgp
)
421 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
422 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
423 bgp
->default_connect_retry
= BGP_DEFAULT_CONNECT_RETRY
;
428 /* BGP confederation configuration. */
429 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
432 struct listnode
*node
, *nnode
;
436 return BGP_ERR_INVALID_AS
;
438 /* Remember - were we doing confederation before? */
439 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
441 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
443 /* If we were doing confederation already, this is just an external
444 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
445 were not doing confederation before, reset all EBGP sessions. */
446 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
447 /* We're looking for peers who's AS is not local or part of our
449 if (already_confed
) {
450 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
452 if (BGP_IS_VALID_STATE_FOR_NOTIF(
455 PEER_DOWN_CONFED_ID_CHANGE
;
457 peer
, BGP_NOTIFY_CEASE
,
458 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
460 bgp_session_reset_safe(peer
, &nnode
);
463 /* Not doign confederation before, so reset every
466 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
467 /* Reset the local_as to be our EBGP one */
468 if (peer_sort(peer
) == BGP_PEER_EBGP
)
470 if (BGP_IS_VALID_STATE_FOR_NOTIF(
473 PEER_DOWN_CONFED_ID_CHANGE
;
475 peer
, BGP_NOTIFY_CEASE
,
476 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
478 bgp_session_reset_safe(peer
, &nnode
);
485 int bgp_confederation_id_unset(struct bgp
*bgp
)
488 struct listnode
*node
, *nnode
;
491 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
493 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
494 /* We're looking for peers who's AS is not local */
495 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
496 peer
->local_as
= bgp
->as
;
497 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
498 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
499 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
500 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
504 bgp_session_reset_safe(peer
, &nnode
);
510 /* Is an AS part of the confed or not? */
511 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
518 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
519 if (bgp
->confed_peers
[i
] == as
)
525 /* Add an AS to the confederation set. */
526 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
529 struct listnode
*node
, *nnode
;
532 return BGP_ERR_INVALID_BGP
;
535 return BGP_ERR_INVALID_AS
;
537 if (bgp_confederation_peers_check(bgp
, as
))
540 if (bgp
->confed_peers
)
542 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
543 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
546 XMALLOC(MTYPE_BGP_CONFED_LIST
,
547 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
549 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
550 bgp
->confed_peers_cnt
++;
552 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
553 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
554 if (peer
->as
== as
) {
555 peer
->local_as
= bgp
->as
;
556 if (BGP_IS_VALID_STATE_FOR_NOTIF(
559 PEER_DOWN_CONFED_PEER_CHANGE
;
561 peer
, BGP_NOTIFY_CEASE
,
562 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
564 bgp_session_reset_safe(peer
, &nnode
);
571 /* Delete an AS from the confederation set. */
572 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
577 struct listnode
*node
, *nnode
;
582 if (!bgp_confederation_peers_check(bgp
, as
))
585 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
586 if (bgp
->confed_peers
[i
] == as
)
587 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
588 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
590 bgp
->confed_peers_cnt
--;
592 if (bgp
->confed_peers_cnt
== 0) {
593 if (bgp
->confed_peers
)
594 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
595 bgp
->confed_peers
= NULL
;
598 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
599 bgp
->confed_peers_cnt
* sizeof(as_t
));
601 /* Now reset any peer who's remote AS has just been removed from the
603 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
604 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
605 if (peer
->as
== as
) {
606 peer
->local_as
= bgp
->confed_id
;
607 if (BGP_IS_VALID_STATE_FOR_NOTIF(
610 PEER_DOWN_CONFED_PEER_CHANGE
;
612 peer
, BGP_NOTIFY_CEASE
,
613 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
615 bgp_session_reset_safe(peer
, &nnode
);
623 /* Local preference configuration. */
624 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
629 bgp
->default_local_pref
= local_pref
;
634 int bgp_default_local_preference_unset(struct bgp
*bgp
)
639 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
644 /* Local preference configuration. */
645 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
650 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
655 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
659 bgp
->default_subgroup_pkt_queue_max
=
660 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
665 /* Listen limit configuration. */
666 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
671 bgp
->dynamic_neighbors_limit
= listen_limit
;
676 int bgp_listen_limit_unset(struct bgp
*bgp
)
681 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
686 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
687 afi_t
*afi
, safi_t
*safi
)
689 /* Map from IANA values to internal values, return error if
690 * values are unrecognized.
692 *afi
= afi_iana2int(pkt_afi
);
693 *safi
= safi_iana2int(pkt_safi
);
694 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
700 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
701 iana_safi_t
*pkt_safi
)
703 /* Map from internal values to IANA values, return error if
704 * internal values are bad (unexpected).
706 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
708 *pkt_afi
= afi_int2iana(afi
);
709 *pkt_safi
= safi_int2iana(safi
);
713 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
722 afid
= afindex(afi
, safi
);
723 if (afid
>= BGP_AF_MAX
)
727 assert(peer
->peer_af_array
[afid
] == NULL
);
729 /* Allocate new peer af */
730 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
732 peer
->peer_af_array
[afid
] = af
;
737 bgp
->af_peer_count
[afi
][safi
]++;
742 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
749 afid
= afindex(afi
, safi
);
750 if (afid
>= BGP_AF_MAX
)
753 return peer
->peer_af_array
[afid
];
756 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
765 afid
= afindex(afi
, safi
);
766 if (afid
>= BGP_AF_MAX
)
769 af
= peer
->peer_af_array
[afid
];
774 bgp_stop_announce_route_timer(af
);
776 if (PAF_SUBGRP(af
)) {
777 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
778 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
779 af
->subgroup
->update_group
->id
,
780 af
->subgroup
->id
, peer
->host
);
784 update_subgroup_remove_peer(af
->subgroup
, af
);
786 if (bgp
->af_peer_count
[afi
][safi
])
787 bgp
->af_peer_count
[afi
][safi
]--;
789 peer
->peer_af_array
[afid
] = NULL
;
790 XFREE(MTYPE_BGP_PEER_AF
, af
);
794 /* Peer comparison function for sorting. */
795 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
797 if (p1
->group
&& !p2
->group
)
800 if (!p1
->group
&& p2
->group
)
803 if (p1
->group
== p2
->group
) {
804 if (p1
->conf_if
&& !p2
->conf_if
)
807 if (!p1
->conf_if
&& p2
->conf_if
)
810 if (p1
->conf_if
&& p2
->conf_if
)
811 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
813 return strcmp(p1
->group
->name
, p2
->group
->name
);
815 return sockunion_cmp(&p1
->su
, &p2
->su
);
818 static unsigned int peer_hash_key_make(const void *p
)
820 const struct peer
*peer
= p
;
821 return sockunion_hash(&peer
->su
);
824 static bool peer_hash_same(const void *p1
, const void *p2
)
826 const struct peer
*peer1
= p1
;
827 const struct peer
*peer2
= p2
;
828 return (sockunion_same(&peer1
->su
, &peer2
->su
)
829 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
830 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
833 void peer_flag_inherit(struct peer
*peer
, uint32_t flag
)
837 /* Skip if peer is not a peer-group member. */
838 if (!peer_group_active(peer
))
841 /* Unset override flag to signal inheritance from peer-group. */
842 UNSET_FLAG(peer
->flags_override
, flag
);
845 * Inherit flag state from peer-group. If the flag of the peer-group is
846 * not being inverted, the peer must inherit the inverse of the current
847 * peer-group flag state.
849 group_val
= CHECK_FLAG(peer
->group
->conf
->flags
, flag
);
850 if (!CHECK_FLAG(peer
->group
->conf
->flags_invert
, flag
)
851 && CHECK_FLAG(peer
->flags_invert
, flag
))
852 COND_FLAG(peer
->flags
, flag
, !group_val
);
854 COND_FLAG(peer
->flags
, flag
, group_val
);
857 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
859 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
862 void peer_af_flag_inherit(struct peer
*peer
, afi_t afi
, safi_t safi
,
867 /* Skip if peer is not a peer-group member. */
868 if (!peer_group_active(peer
))
871 /* Unset override flag to signal inheritance from peer-group. */
872 UNSET_FLAG(peer
->af_flags_override
[afi
][safi
], flag
);
875 * Inherit flag state from peer-group. If the flag of the peer-group is
876 * not being inverted, the peer must inherit the inverse of the current
877 * peer-group flag state.
879 group_val
= CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
], flag
);
880 if (!CHECK_FLAG(peer
->group
->conf
->af_flags_invert
[afi
][safi
], flag
)
881 && CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
))
882 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, !group_val
);
884 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, group_val
);
887 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
888 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
895 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
896 if (peer
->as_type
== AS_INTERNAL
)
897 return BGP_PEER_IBGP
;
899 else if (peer
->as_type
== AS_EXTERNAL
)
900 return BGP_PEER_EBGP
;
902 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
) {
904 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
912 peer1
= listnode_head(peer
->group
->peer
);
917 return BGP_PEER_INTERNAL
;
921 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
922 if (peer
->local_as
== 0)
923 return BGP_PEER_INTERNAL
;
925 if (peer
->local_as
== peer
->as
) {
926 if (bgp
->as
== bgp
->confed_id
) {
927 if (peer
->local_as
== bgp
->as
)
928 return BGP_PEER_IBGP
;
930 return BGP_PEER_EBGP
;
932 if (peer
->local_as
== bgp
->confed_id
)
933 return BGP_PEER_EBGP
;
935 return BGP_PEER_IBGP
;
939 if (bgp_confederation_peers_check(bgp
, peer
->as
))
940 return BGP_PEER_CONFED
;
942 return BGP_PEER_EBGP
;
944 if (peer
->as_type
== AS_UNSPECIFIED
) {
945 /* check if in peer-group with AS information */
947 && (peer
->group
->conf
->as_type
!= AS_UNSPECIFIED
)) {
948 if (peer
->group
->conf
->as_type
951 == peer
->group
->conf
->as
)
952 return BGP_PEER_IBGP
;
954 return BGP_PEER_EBGP
;
955 } else if (peer
->group
->conf
->as_type
957 return BGP_PEER_IBGP
;
959 return BGP_PEER_EBGP
;
961 /* no AS information anywhere, let caller know */
962 return BGP_PEER_UNSPECIFIED
;
963 } else if (peer
->as_type
!= AS_SPECIFIED
)
964 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
967 return (peer
->local_as
== 0
969 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
974 /* Calculate and cache the peer "sort" */
975 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
977 peer
->sort
= peer_calc_sort(peer
);
981 static void peer_free(struct peer
*peer
)
986 assert(peer
->status
== Deleted
);
990 /* this /ought/ to have been done already through bgp_stop earlier,
991 * but just to be sure..
995 bgp_writes_off(peer
);
996 assert(!peer
->t_write
);
997 assert(!peer
->t_read
);
998 BGP_EVENT_FLUSH(peer
);
1000 pthread_mutex_destroy(&peer
->io_mtx
);
1002 /* Free connected nexthop, if present */
1003 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1004 && !peer_dynamic_neighbor(peer
))
1005 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1008 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1011 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1015 /* Free allocated host character. */
1017 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1021 if (peer
->domainname
) {
1022 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1023 peer
->domainname
= NULL
;
1027 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1028 peer
->ifname
= NULL
;
1031 /* Update source configuration. */
1032 if (peer
->update_source
) {
1033 sockunion_free(peer
->update_source
);
1034 peer
->update_source
= NULL
;
1037 if (peer
->update_if
) {
1038 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1039 peer
->update_if
= NULL
;
1042 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1043 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1045 if (peer
->clear_node_queue
)
1046 work_queue_free_and_null(&peer
->clear_node_queue
);
1048 bgp_sync_delete(peer
);
1050 if (peer
->conf_if
) {
1051 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1052 peer
->conf_if
= NULL
;
1055 bfd_info_free(&(peer
->bfd_info
));
1057 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
1058 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
1059 bgp_addpath_set_peer_type(peer
, afi
, safi
,
1064 bgp_unlock(peer
->bgp
);
1066 memset(peer
, 0, sizeof(struct peer
));
1068 XFREE(MTYPE_BGP_PEER
, peer
);
1071 /* increase reference count on a struct peer */
1072 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1074 assert(peer
&& (peer
->lock
>= 0));
1077 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1085 /* decrease reference count on a struct peer
1086 * struct peer is freed and NULL returned if last reference
1088 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1090 assert(peer
&& (peer
->lock
> 0));
1093 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1098 if (peer
->lock
== 0) {
1106 /* Allocate new peer object, implicitely locked. */
1107 struct peer
*peer_new(struct bgp
*bgp
)
1114 /* bgp argument is absolutely required */
1119 /* Allocate new peer. */
1120 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1122 /* Set default value. */
1124 peer
->v_start
= BGP_INIT_START_TIMER
;
1125 peer
->v_connect
= bgp
->default_connect_retry
;
1126 peer
->status
= Idle
;
1127 peer
->ostatus
= Idle
;
1128 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1129 peer
->bgp
= bgp_lock(bgp
);
1130 peer
= peer_lock(peer
); /* initial reference */
1131 peer
->password
= NULL
;
1133 /* Set default flags. */
1134 FOREACH_AFI_SAFI (afi
, safi
) {
1135 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
1136 SET_FLAG(peer
->af_flags
[afi
][safi
],
1137 PEER_FLAG_SEND_EXT_COMMUNITY
);
1138 SET_FLAG(peer
->af_flags
[afi
][safi
],
1139 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1141 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1142 PEER_FLAG_SEND_COMMUNITY
);
1143 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1144 PEER_FLAG_SEND_EXT_COMMUNITY
);
1145 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1146 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1147 peer
->addpath_type
[afi
][safi
] = BGP_ADDPATH_NONE
;
1150 /* set nexthop-unchanged for l2vpn evpn by default */
1151 SET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1152 PEER_FLAG_NEXTHOP_UNCHANGED
);
1154 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1156 /* Create buffers. */
1157 peer
->ibuf
= stream_fifo_new();
1158 peer
->obuf
= stream_fifo_new();
1159 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1161 /* We use a larger buffer for peer->obuf_work in the event that:
1162 * - We RX a BGP_UPDATE where the attributes alone are just
1163 * under BGP_MAX_PACKET_SIZE
1164 * - The user configures an outbound route-map that does many as-path
1165 * prepends or adds many communities. At most they can have
1166 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1167 * large they can make the attributes.
1169 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1170 * bounds checking for every single attribute as we construct an
1174 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1176 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1178 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1180 bgp_sync_init(peer
);
1182 /* Get service port number. */
1183 sp
= getservbyname("bgp", "tcp");
1184 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1186 QOBJ_REG(peer
, peer
);
1191 * This function is invoked when a duplicate peer structure associated with
1192 * a neighbor is being deleted. If this about-to-be-deleted structure is
1193 * the one with all the config, then we have to copy over the info.
1195 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1197 struct peer_af
*paf
;
1205 /* The following function is used by both peer group config copy to
1206 * individual peer and when we transfer config
1208 if (peer_src
->change_local_as
)
1209 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1211 /* peer flags apply */
1212 peer_dst
->flags
= peer_src
->flags
;
1213 peer_dst
->cap
= peer_src
->cap
;
1215 peer_dst
->local_as
= peer_src
->local_as
;
1216 peer_dst
->port
= peer_src
->port
;
1217 (void)peer_sort(peer_dst
);
1218 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1221 peer_dst
->holdtime
= peer_src
->holdtime
;
1222 peer_dst
->keepalive
= peer_src
->keepalive
;
1223 peer_dst
->connect
= peer_src
->connect
;
1224 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1225 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1226 peer_dst
->routeadv
= peer_src
->routeadv
;
1227 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1229 /* password apply */
1230 if (peer_src
->password
&& !peer_dst
->password
)
1231 peer_dst
->password
=
1232 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1234 FOREACH_AFI_SAFI (afi
, safi
) {
1235 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1236 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1237 peer_dst
->allowas_in
[afi
][safi
] =
1238 peer_src
->allowas_in
[afi
][safi
];
1239 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1240 peer_dst
->addpath_type
[afi
][safi
] =
1241 peer_src
->addpath_type
[afi
][safi
];
1244 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1245 paf
= peer_src
->peer_af_array
[afidx
];
1247 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1250 /* update-source apply */
1251 if (peer_src
->update_source
) {
1252 if (peer_dst
->update_source
)
1253 sockunion_free(peer_dst
->update_source
);
1254 if (peer_dst
->update_if
) {
1255 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1256 peer_dst
->update_if
= NULL
;
1258 peer_dst
->update_source
=
1259 sockunion_dup(peer_src
->update_source
);
1260 } else if (peer_src
->update_if
) {
1261 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1262 if (peer_dst
->update_source
) {
1263 sockunion_free(peer_dst
->update_source
);
1264 peer_dst
->update_source
= NULL
;
1266 peer_dst
->update_if
=
1267 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1270 if (peer_src
->ifname
) {
1271 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1274 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1278 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1279 struct interface
*ifp
)
1281 struct connected
*ifc
;
1284 struct listnode
*node
;
1286 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1287 * IPv4 address of the other end.
1289 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1290 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1291 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1292 if (p
.prefixlen
== 30) {
1293 peer
->su
.sa
.sa_family
= AF_INET
;
1294 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1296 peer
->su
.sin
.sin_addr
.s_addr
=
1298 else if (addr
% 4 == 2)
1299 peer
->su
.sin
.sin_addr
.s_addr
=
1301 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1302 peer
->su
.sin
.sin_len
=
1303 sizeof(struct sockaddr_in
);
1304 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1306 } else if (p
.prefixlen
== 31) {
1307 peer
->su
.sa
.sa_family
= AF_INET
;
1308 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1310 peer
->su
.sin
.sin_addr
.s_addr
=
1313 peer
->su
.sin
.sin_addr
.s_addr
=
1315 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1316 peer
->su
.sin
.sin_len
=
1317 sizeof(struct sockaddr_in
);
1318 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1320 } else if (bgp_debug_neighbor_events(peer
))
1322 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1330 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1331 struct interface
*ifp
)
1333 struct nbr_connected
*ifc_nbr
;
1335 /* Have we learnt the peer's IPv6 link-local address? */
1336 if (ifp
->nbr_connected
1337 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1338 peer
->su
.sa
.sa_family
= AF_INET6
;
1339 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1340 sizeof(struct in6_addr
));
1342 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1344 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1352 * Set or reset the peer address socketunion structure based on the
1353 * learnt/derived peer address. If the address has changed, update the
1354 * password on the listen socket, if needed.
1356 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1358 struct interface
*ifp
;
1360 int peer_addr_updated
= 0;
1366 * Our peer structure is stored in the bgp->peerhash
1367 * release it before we modify anything.
1369 hash_release(peer
->bgp
->peerhash
, peer
);
1371 prev_family
= peer
->su
.sa
.sa_family
;
1372 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1374 /* If BGP unnumbered is not "v6only", we first see if we can
1376 * peer's IPv4 address.
1378 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1380 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1382 /* If "v6only" or we can't derive peer's IPv4 address, see if
1384 * learnt the peer's IPv6 link-local address. This is from the
1386 * IPv6 address in router advertisement.
1388 if (!peer_addr_updated
)
1390 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1392 /* If we could derive the peer address, we may need to install the
1394 * configured for the peer, if any, on the listen socket. Otherwise,
1396 * that peer's address is not available and uninstall the password, if
1399 if (peer_addr_updated
) {
1400 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1401 && prev_family
== AF_UNSPEC
)
1404 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)
1405 && prev_family
!= AF_UNSPEC
)
1406 bgp_md5_unset(peer
);
1407 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1408 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1412 * Since our su changed we need to del/add peer to the peerhash
1414 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1417 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1420 struct bgp_node
*rn
, *nrn
;
1421 struct bgp_table
*table
;
1423 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1424 rn
= bgp_route_next(rn
)) {
1425 table
= bgp_node_get_bgp_table_info(rn
);
1426 if (table
!= NULL
) {
1427 /* Special handling for 2-level routing
1429 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1430 || safi
== SAFI_EVPN
) {
1431 for (nrn
= bgp_table_top(table
);
1432 nrn
; nrn
= bgp_route_next(nrn
))
1433 bgp_process(bgp
, nrn
, afi
, safi
);
1435 bgp_process(bgp
, rn
, afi
, safi
);
1440 /* Force a bestpath recalculation for all prefixes. This is used
1441 * when 'bgp bestpath' commands are entered.
1443 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1448 FOREACH_AFI_SAFI (afi
, safi
) {
1449 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1454 * Create new BGP peer.
1456 * conf_if and su are mutually exclusive if configuring from the cli.
1457 * If we are handing a doppelganger, then we *must* pass in both
1458 * the original peer's su and conf_if, so that we can appropriately
1459 * track the bgp->peerhash( ie we don't want to remove the current
1460 * one from the config ).
1462 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1463 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1464 int as_type
, afi_t afi
, safi_t safi
,
1465 struct peer_group
*group
)
1469 char buf
[SU_ADDRSTRLEN
];
1471 peer
= peer_new(bgp
);
1473 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1477 bgp_peer_conf_if_to_su_update(peer
);
1478 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1479 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1482 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1483 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1484 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1486 peer
->local_as
= local_as
;
1487 peer
->as
= remote_as
;
1488 peer
->as_type
= as_type
;
1489 peer
->local_id
= bgp
->router_id
;
1490 peer
->v_holdtime
= bgp
->default_holdtime
;
1491 peer
->v_keepalive
= bgp
->default_keepalive
;
1492 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1493 ? BGP_DEFAULT_IBGP_ROUTEADV
1494 : BGP_DEFAULT_EBGP_ROUTEADV
;
1496 peer
= peer_lock(peer
); /* bgp peer list reference */
1497 peer
->group
= group
;
1498 listnode_add_sort(bgp
->peer
, peer
);
1499 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1501 /* Adjust update-group coalesce timer heuristics for # peers. */
1502 if (bgp
->heuristic_coalesce
) {
1503 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1505 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1506 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1509 active
= peer_active(peer
);
1511 if (peer
->su
.sa
.sa_family
== AF_UNSPEC
)
1512 peer
->last_reset
= PEER_DOWN_NBR_ADDR
;
1514 peer
->last_reset
= PEER_DOWN_NOAFI_ACTIVATED
;
1517 /* Last read and reset time set */
1518 peer
->readtime
= peer
->resettime
= bgp_clock();
1520 /* Default TTL set. */
1521 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: BGP_DEFAULT_TTL
;
1523 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1526 peer
->afc
[afi
][safi
] = 1;
1527 peer_af_create(peer
, afi
, safi
);
1530 /* auto shutdown if configured */
1531 if (bgp
->autoshutdown
)
1532 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1533 /* Set up peer's events and timers. */
1534 else if (!active
&& peer_active(peer
))
1535 bgp_timer_set(peer
);
1540 /* Make accept BGP peer. This function is only called from the test code */
1541 struct peer
*peer_create_accept(struct bgp
*bgp
)
1545 peer
= peer_new(bgp
);
1547 peer
= peer_lock(peer
); /* bgp peer list reference */
1548 listnode_add_sort(bgp
->peer
, peer
);
1554 * Return true if we have a peer configured to use this afi/safi
1556 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1558 struct listnode
*node
;
1561 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1562 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1565 if (peer
->afc
[afi
][safi
])
1572 /* Change peer's AS number. */
1573 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1575 bgp_peer_sort_t type
;
1578 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1579 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1580 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1581 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1582 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1584 bgp_session_reset(peer
);
1586 type
= peer_sort(peer
);
1588 peer
->as_type
= as_specified
;
1590 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1591 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1592 && peer
->bgp
->as
!= as
)
1593 peer
->local_as
= peer
->bgp
->confed_id
;
1595 peer
->local_as
= peer
->bgp
->as
;
1597 /* Advertisement-interval reset */
1598 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_ROUTEADV
)) {
1599 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
1600 ? BGP_DEFAULT_IBGP_ROUTEADV
1601 : BGP_DEFAULT_EBGP_ROUTEADV
;
1605 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1607 else if (type
== BGP_PEER_IBGP
)
1608 peer
->ttl
= BGP_DEFAULT_TTL
;
1610 /* reflector-client reset */
1611 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1612 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1613 PEER_FLAG_REFLECTOR_CLIENT
);
1614 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1615 PEER_FLAG_REFLECTOR_CLIENT
);
1616 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1617 PEER_FLAG_REFLECTOR_CLIENT
);
1618 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1619 PEER_FLAG_REFLECTOR_CLIENT
);
1620 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1621 PEER_FLAG_REFLECTOR_CLIENT
);
1622 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1623 PEER_FLAG_REFLECTOR_CLIENT
);
1624 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1625 PEER_FLAG_REFLECTOR_CLIENT
);
1626 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1627 PEER_FLAG_REFLECTOR_CLIENT
);
1628 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1629 PEER_FLAG_REFLECTOR_CLIENT
);
1630 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1631 PEER_FLAG_REFLECTOR_CLIENT
);
1632 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1633 PEER_FLAG_REFLECTOR_CLIENT
);
1634 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1635 PEER_FLAG_REFLECTOR_CLIENT
);
1636 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1637 PEER_FLAG_REFLECTOR_CLIENT
);
1640 /* local-as reset */
1641 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1642 peer
->change_local_as
= 0;
1643 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
1644 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1645 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1649 /* If peer does not exist, create new one. If peer already exists,
1650 set AS number to the peer. */
1651 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1652 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1658 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1660 peer
= peer_lookup(bgp
, su
);
1663 /* Not allowed for a dynamic peer. */
1664 if (peer_dynamic_neighbor(peer
)) {
1666 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1669 /* When this peer is a member of peer-group. */
1671 /* peer-group already has AS number/internal/external */
1672 if (peer
->group
->conf
->as
1673 || peer
->group
->conf
->as_type
) {
1674 /* Return peer group's AS number. */
1675 *as
= peer
->group
->conf
->as
;
1676 return BGP_ERR_PEER_GROUP_MEMBER
;
1679 bgp_peer_sort_t peer_sort_type
=
1680 peer_sort(peer
->group
->conf
);
1682 /* Explicit AS numbers used, compare AS numbers */
1683 if (as_type
== AS_SPECIFIED
) {
1684 if (((peer_sort_type
== BGP_PEER_IBGP
)
1685 && (bgp
->as
!= *as
))
1686 || ((peer_sort_type
== BGP_PEER_EBGP
)
1687 && (bgp
->as
== *as
))) {
1689 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1692 /* internal/external used, compare as-types */
1693 if (((peer_sort_type
== BGP_PEER_IBGP
)
1694 && (as_type
!= AS_INTERNAL
))
1695 || ((peer_sort_type
== BGP_PEER_EBGP
)
1696 && (as_type
!= AS_EXTERNAL
))) {
1698 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1703 /* Existing peer's AS number change. */
1704 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1705 || (peer
->as_type
!= as_type
))
1706 peer_as_change(peer
, *as
, as_type
);
1709 return BGP_ERR_NO_INTERFACE_CONFIG
;
1711 /* If the peer is not part of our confederation, and its not an
1712 iBGP peer then spoof the source AS */
1713 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1714 && !bgp_confederation_peers_check(bgp
, *as
)
1716 local_as
= bgp
->confed_id
;
1720 /* If this is IPv4 unicast configuration and "no bgp default
1721 ipv4-unicast" is specified. */
1723 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1724 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1725 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1728 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1735 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1736 struct peer
*peer
, afi_t afi
,
1740 int out
= FILTER_OUT
;
1742 uint32_t pflags_ovrd
;
1743 uint8_t *pfilter_ovrd
;
1747 pflags_ovrd
= peer
->af_flags_override
[afi
][safi
];
1748 pfilter_ovrd
= &peer
->filter_override
[afi
][safi
][in
];
1750 /* peer af_flags apply */
1751 flags_tmp
= conf
->af_flags
[afi
][safi
] & ~pflags_ovrd
;
1752 flags_tmp
^= conf
->af_flags_invert
[afi
][safi
]
1753 ^ peer
->af_flags_invert
[afi
][safi
];
1754 flags_tmp
&= ~pflags_ovrd
;
1756 UNSET_FLAG(peer
->af_flags
[afi
][safi
], ~pflags_ovrd
);
1757 SET_FLAG(peer
->af_flags
[afi
][safi
], flags_tmp
);
1758 SET_FLAG(peer
->af_flags_invert
[afi
][safi
],
1759 conf
->af_flags_invert
[afi
][safi
]);
1761 /* maximum-prefix */
1762 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_MAX_PREFIX
)) {
1763 PEER_ATTR_INHERIT(peer
, group
, pmax
[afi
][safi
]);
1764 PEER_ATTR_INHERIT(peer
, group
, pmax_threshold
[afi
][safi
]);
1765 PEER_ATTR_INHERIT(peer
, group
, pmax_restart
[afi
][safi
]);
1769 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_ALLOWAS_IN
))
1770 PEER_ATTR_INHERIT(peer
, group
, allowas_in
[afi
][safi
]);
1773 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_WEIGHT
))
1774 PEER_ATTR_INHERIT(peer
, group
, weight
[afi
][safi
]);
1776 /* default-originate route-map */
1777 if (!CHECK_FLAG(pflags_ovrd
, PEER_FLAG_DEFAULT_ORIGINATE
)) {
1778 PEER_STR_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].name
,
1779 MTYPE_ROUTE_MAP_NAME
);
1780 PEER_ATTR_INHERIT(peer
, group
, default_rmap
[afi
][safi
].map
);
1783 /* inbound filter apply */
1784 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_DISTRIBUTE_LIST
)) {
1785 PEER_STR_ATTR_INHERIT(peer
, group
,
1786 filter
[afi
][safi
].dlist
[in
].name
,
1787 MTYPE_BGP_FILTER_NAME
);
1788 PEER_ATTR_INHERIT(peer
, group
,
1789 filter
[afi
][safi
].dlist
[in
].alist
);
1792 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_PREFIX_LIST
)) {
1793 PEER_STR_ATTR_INHERIT(peer
, group
,
1794 filter
[afi
][safi
].plist
[in
].name
,
1795 MTYPE_BGP_FILTER_NAME
);
1796 PEER_ATTR_INHERIT(peer
, group
,
1797 filter
[afi
][safi
].plist
[in
].plist
);
1800 if (!CHECK_FLAG(pfilter_ovrd
[in
], PEER_FT_FILTER_LIST
)) {
1801 PEER_STR_ATTR_INHERIT(peer
, group
,
1802 filter
[afi
][safi
].aslist
[in
].name
,
1803 MTYPE_BGP_FILTER_NAME
);
1804 PEER_ATTR_INHERIT(peer
, group
,
1805 filter
[afi
][safi
].aslist
[in
].aslist
);
1808 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_IN
], PEER_FT_ROUTE_MAP
)) {
1809 PEER_STR_ATTR_INHERIT(peer
, group
,
1810 filter
[afi
][safi
].map
[in
].name
,
1811 MTYPE_BGP_FILTER_NAME
);
1812 PEER_ATTR_INHERIT(peer
, group
,
1813 filter
[afi
][safi
].map
[RMAP_IN
].map
);
1816 /* outbound filter apply */
1817 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_DISTRIBUTE_LIST
)) {
1818 PEER_STR_ATTR_INHERIT(peer
, group
,
1819 filter
[afi
][safi
].dlist
[out
].name
,
1820 MTYPE_BGP_FILTER_NAME
);
1821 PEER_ATTR_INHERIT(peer
, group
,
1822 filter
[afi
][safi
].dlist
[out
].alist
);
1825 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_PREFIX_LIST
)) {
1826 PEER_STR_ATTR_INHERIT(peer
, group
,
1827 filter
[afi
][safi
].plist
[out
].name
,
1828 MTYPE_BGP_FILTER_NAME
);
1829 PEER_ATTR_INHERIT(peer
, group
,
1830 filter
[afi
][safi
].plist
[out
].plist
);
1833 if (!CHECK_FLAG(pfilter_ovrd
[out
], PEER_FT_FILTER_LIST
)) {
1834 PEER_STR_ATTR_INHERIT(peer
, group
,
1835 filter
[afi
][safi
].aslist
[out
].name
,
1836 MTYPE_BGP_FILTER_NAME
);
1837 PEER_ATTR_INHERIT(peer
, group
,
1838 filter
[afi
][safi
].aslist
[out
].aslist
);
1841 if (!CHECK_FLAG(pfilter_ovrd
[RMAP_OUT
], PEER_FT_ROUTE_MAP
)) {
1842 PEER_STR_ATTR_INHERIT(peer
, group
,
1843 filter
[afi
][safi
].map
[RMAP_OUT
].name
,
1844 MTYPE_BGP_FILTER_NAME
);
1845 PEER_ATTR_INHERIT(peer
, group
,
1846 filter
[afi
][safi
].map
[RMAP_OUT
].map
);
1849 /* nondirectional filter apply */
1850 if (!CHECK_FLAG(pfilter_ovrd
[0], PEER_FT_UNSUPPRESS_MAP
)) {
1851 PEER_STR_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.name
,
1852 MTYPE_BGP_FILTER_NAME
);
1853 PEER_ATTR_INHERIT(peer
, group
, filter
[afi
][safi
].usmap
.map
);
1856 if (peer
->addpath_type
[afi
][safi
] == BGP_ADDPATH_NONE
) {
1857 peer
->addpath_type
[afi
][safi
] = conf
->addpath_type
[afi
][safi
];
1858 bgp_addpath_type_changed(conf
->bgp
);
1862 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1867 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1868 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
1869 __func__
, peer
->host
);
1873 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1875 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1876 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1877 return BGP_ERR_PEER_SAFI_CONFLICT
;
1879 /* Nothing to do if we've already activated this peer */
1880 if (peer
->afc
[afi
][safi
])
1883 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1886 active
= peer_active(peer
);
1887 peer
->afc
[afi
][safi
] = 1;
1890 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1892 if (!active
&& peer_active(peer
)) {
1893 bgp_timer_set(peer
);
1895 if (peer
->status
== Established
) {
1896 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1897 peer
->afc_adv
[afi
][safi
] = 1;
1898 bgp_capability_send(peer
, afi
, safi
,
1900 CAPABILITY_ACTION_SET
);
1901 if (peer
->afc_recv
[afi
][safi
]) {
1902 peer
->afc_nego
[afi
][safi
] = 1;
1903 bgp_announce_route(peer
, afi
, safi
);
1906 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1907 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1908 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1911 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1912 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1913 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1914 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1917 * If we are turning on a AFI/SAFI locally and we've
1918 * started bringing a peer up, we need to tell
1919 * the other peer to restart because we might loose
1920 * configuration here because when the doppelganger
1921 * gets to a established state due to how
1922 * we resolve we could just overwrite the afi/safi
1925 other
= peer
->doppelganger
;
1927 && (other
->status
== OpenSent
1928 || other
->status
== OpenConfirm
)) {
1929 other
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1930 bgp_notify_send(other
, BGP_NOTIFY_CEASE
,
1931 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1938 /* Activate the peer or peer group for specified AFI and SAFI. */
1939 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1942 struct peer_group
*group
;
1943 struct listnode
*node
, *nnode
;
1944 struct peer
*tmp_peer
;
1947 /* Nothing to do if we've already activated this peer */
1948 if (peer
->afc
[afi
][safi
])
1953 /* This is a peer-group so activate all of the members of the
1954 * peer-group as well */
1955 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1957 /* Do not activate a peer for both SAFI_UNICAST and
1958 * SAFI_LABELED_UNICAST */
1959 if ((safi
== SAFI_UNICAST
1960 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1961 || (safi
== SAFI_LABELED_UNICAST
1962 && peer
->afc
[afi
][SAFI_UNICAST
]))
1963 return BGP_ERR_PEER_SAFI_CONFLICT
;
1965 peer
->afc
[afi
][safi
] = 1;
1966 group
= peer
->group
;
1968 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1969 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1972 ret
|= peer_activate_af(peer
, afi
, safi
);
1975 /* If this is the first peer to be activated for this
1976 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1977 if (safi
== SAFI_LABELED_UNICAST
1978 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1980 if (BGP_DEBUG(zebra
, ZEBRA
))
1982 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1984 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1985 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1988 if (safi
== SAFI_FLOWSPEC
) {
1989 /* connect to table manager */
1990 bgp_zebra_init_tm_connect(bgp
);
1995 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1998 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1999 flog_err(EC_BGP_PEER_GROUP
, "%s was called for peer-group %s",
2000 __func__
, peer
->host
);
2004 /* Nothing to do if we've already deactivated this peer */
2005 if (!peer
->afc
[afi
][safi
])
2008 /* De-activate the address family configuration. */
2009 peer
->afc
[afi
][safi
] = 0;
2011 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2012 flog_err(EC_BGP_PEER_DELETE
,
2013 "couldn't delete af structure for peer %s",
2018 if (peer
->status
== Established
) {
2019 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2020 peer
->afc_adv
[afi
][safi
] = 0;
2021 peer
->afc_nego
[afi
][safi
] = 0;
2023 if (peer_active_nego(peer
)) {
2024 bgp_capability_send(peer
, afi
, safi
,
2026 CAPABILITY_ACTION_UNSET
);
2027 bgp_clear_route(peer
, afi
, safi
);
2028 peer
->pcount
[afi
][safi
] = 0;
2030 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2031 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2032 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2035 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2036 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2037 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2044 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2047 struct peer_group
*group
;
2048 struct peer
*tmp_peer
;
2049 struct listnode
*node
, *nnode
;
2052 /* Nothing to do if we've already de-activated this peer */
2053 if (!peer
->afc
[afi
][safi
])
2056 /* This is a peer-group so de-activate all of the members of the
2057 * peer-group as well */
2058 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2059 peer
->afc
[afi
][safi
] = 0;
2060 group
= peer
->group
;
2062 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2063 flog_err(EC_BGP_PEER_DELETE
,
2064 "couldn't delete af structure for peer %s",
2068 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2069 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2072 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2077 /* If this is the last peer to be deactivated for this
2078 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2079 if (safi
== SAFI_LABELED_UNICAST
2080 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2081 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2083 if (BGP_DEBUG(zebra
, ZEBRA
))
2085 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2087 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2088 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2093 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2096 return peer_activate(peer
, afi
, safi
);
2098 return peer_deactivate(peer
, afi
, safi
);
2101 static void peer_nsf_stop(struct peer
*peer
)
2106 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2107 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2109 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2110 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2111 peer
->nsf
[afi
][safi
] = 0;
2113 if (peer
->t_gr_restart
) {
2114 BGP_TIMER_OFF(peer
->t_gr_restart
);
2115 if (bgp_debug_neighbor_events(peer
))
2116 zlog_debug("%s graceful restart timer stopped",
2119 if (peer
->t_gr_stale
) {
2120 BGP_TIMER_OFF(peer
->t_gr_stale
);
2121 if (bgp_debug_neighbor_events(peer
))
2123 "%s graceful restart stalepath timer stopped",
2126 bgp_clear_route_all(peer
);
2129 /* Delete peer from confguration.
2131 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2132 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2134 * This function /should/ take care to be idempotent, to guard against
2135 * it being called multiple times through stray events that come in
2136 * that happen to result in this function being called again. That
2137 * said, getting here for a "Deleted" peer is a bug in the neighbour
2140 int peer_delete(struct peer
*peer
)
2146 struct bgp_filter
*filter
;
2147 struct listnode
*pn
;
2150 assert(peer
->status
!= Deleted
);
2153 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2155 bgp_keepalives_off(peer
);
2156 bgp_reads_off(peer
);
2157 bgp_writes_off(peer
);
2158 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2159 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2160 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_KEEPALIVES_ON
));
2162 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2163 peer_nsf_stop(peer
);
2165 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2167 bgp_bfd_deregister_peer(peer
);
2169 /* If this peer belongs to peer group, clear up the
2172 if (peer_dynamic_neighbor(peer
))
2173 peer_drop_dynamic_neighbor(peer
);
2175 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2177 peer
); /* group->peer list reference */
2178 list_delete_node(peer
->group
->peer
, pn
);
2183 /* Withdraw all information from routing table. We can not use
2184 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2185 * executed after peer structure is deleted.
2187 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2189 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2191 if (peer
->doppelganger
) {
2192 peer
->doppelganger
->doppelganger
= NULL
;
2193 peer
->doppelganger
= NULL
;
2196 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2197 bgp_fsm_change_status(peer
, Deleted
);
2199 /* Remove from NHT */
2200 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2201 bgp_unlink_nexthop_by_peer(peer
);
2203 /* Password configuration */
2204 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
)) {
2205 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2207 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2208 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2209 bgp_md5_unset(peer
);
2212 bgp_timer_set(peer
); /* stops all timers for Deleted */
2214 /* Delete from all peer list. */
2215 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2216 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2217 peer_unlock(peer
); /* bgp peer list reference */
2218 list_delete_node(bgp
->peer
, pn
);
2219 hash_release(bgp
->peerhash
, peer
);
2224 stream_fifo_free(peer
->ibuf
);
2229 stream_fifo_free(peer
->obuf
);
2233 if (peer
->ibuf_work
) {
2234 ringbuf_del(peer
->ibuf_work
);
2235 peer
->ibuf_work
= NULL
;
2238 if (peer
->obuf_work
) {
2239 stream_free(peer
->obuf_work
);
2240 peer
->obuf_work
= NULL
;
2243 if (peer
->scratch
) {
2244 stream_free(peer
->scratch
);
2245 peer
->scratch
= NULL
;
2248 /* Local and remote addresses. */
2249 if (peer
->su_local
) {
2250 sockunion_free(peer
->su_local
);
2251 peer
->su_local
= NULL
;
2254 if (peer
->su_remote
) {
2255 sockunion_free(peer
->su_remote
);
2256 peer
->su_remote
= NULL
;
2259 /* Free filter related memory. */
2260 FOREACH_AFI_SAFI (afi
, safi
) {
2261 filter
= &peer
->filter
[afi
][safi
];
2263 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2264 if (filter
->dlist
[i
].name
) {
2265 XFREE(MTYPE_BGP_FILTER_NAME
,
2266 filter
->dlist
[i
].name
);
2267 filter
->dlist
[i
].name
= NULL
;
2270 if (filter
->plist
[i
].name
) {
2271 XFREE(MTYPE_BGP_FILTER_NAME
,
2272 filter
->plist
[i
].name
);
2273 filter
->plist
[i
].name
= NULL
;
2276 if (filter
->aslist
[i
].name
) {
2277 XFREE(MTYPE_BGP_FILTER_NAME
,
2278 filter
->aslist
[i
].name
);
2279 filter
->aslist
[i
].name
= NULL
;
2283 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2284 if (filter
->map
[i
].name
) {
2285 XFREE(MTYPE_BGP_FILTER_NAME
,
2286 filter
->map
[i
].name
);
2287 filter
->map
[i
].name
= NULL
;
2291 if (filter
->usmap
.name
) {
2292 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2293 filter
->usmap
.name
= NULL
;
2296 if (peer
->default_rmap
[afi
][safi
].name
) {
2297 XFREE(MTYPE_ROUTE_MAP_NAME
,
2298 peer
->default_rmap
[afi
][safi
].name
);
2299 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2303 FOREACH_AFI_SAFI (afi
, safi
)
2304 peer_af_delete(peer
, afi
, safi
);
2306 if (peer
->hostname
) {
2307 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2308 peer
->hostname
= NULL
;
2311 if (peer
->domainname
) {
2312 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2313 peer
->domainname
= NULL
;
2316 peer_unlock(peer
); /* initial reference */
2321 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2323 return strcmp(g1
->name
, g2
->name
);
2326 /* Peer group cofiguration. */
2327 static struct peer_group
*peer_group_new(void)
2329 return XCALLOC(MTYPE_PEER_GROUP
, sizeof(struct peer_group
));
2332 static void peer_group_free(struct peer_group
*group
)
2334 XFREE(MTYPE_PEER_GROUP
, group
);
2337 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2339 struct peer_group
*group
;
2340 struct listnode
*node
, *nnode
;
2342 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2343 if (strcmp(group
->name
, name
) == 0)
2349 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2351 struct peer_group
*group
;
2354 group
= peer_group_lookup(bgp
, name
);
2358 group
= peer_group_new();
2360 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2361 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2362 group
->peer
= list_new();
2363 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2364 group
->listen_range
[afi
] = list_new();
2365 group
->conf
= peer_new(bgp
);
2366 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2367 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2368 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2369 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2370 group
->conf
->group
= group
;
2371 group
->conf
->as
= 0;
2372 group
->conf
->ttl
= BGP_DEFAULT_TTL
;
2373 group
->conf
->gtsm_hops
= 0;
2374 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2375 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2376 listnode_add_sort(bgp
->group
, group
);
2381 static void peer_group2peer_config_copy(struct peer_group
*group
,
2391 peer
->as
= conf
->as
;
2394 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_LOCAL_AS
))
2395 peer
->change_local_as
= conf
->change_local_as
;
2397 /* If peer-group has configured TTL then override it */
2398 if (conf
->ttl
!= BGP_DEFAULT_TTL
)
2399 peer
->ttl
= conf
->ttl
;
2402 peer
->gtsm_hops
= conf
->gtsm_hops
;
2404 /* peer flags apply */
2405 flags_tmp
= conf
->flags
& ~peer
->flags_override
;
2406 flags_tmp
^= conf
->flags_invert
^ peer
->flags_invert
;
2407 flags_tmp
&= ~peer
->flags_override
;
2409 UNSET_FLAG(peer
->flags
, ~peer
->flags_override
);
2410 SET_FLAG(peer
->flags
, flags_tmp
);
2411 SET_FLAG(peer
->flags_invert
, conf
->flags_invert
);
2413 /* peer timers apply */
2414 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER
)) {
2415 PEER_ATTR_INHERIT(peer
, group
, holdtime
);
2416 PEER_ATTR_INHERIT(peer
, group
, keepalive
);
2419 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_TIMER_CONNECT
)) {
2420 PEER_ATTR_INHERIT(peer
, group
, connect
);
2421 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_TIMER_CONNECT
))
2422 peer
->v_connect
= conf
->connect
;
2424 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
2427 /* advertisement-interval apply */
2428 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_ROUTEADV
)) {
2429 PEER_ATTR_INHERIT(peer
, group
, routeadv
);
2430 if (CHECK_FLAG(conf
->flags
, PEER_FLAG_ROUTEADV
))
2431 peer
->v_routeadv
= conf
->routeadv
;
2433 peer
->v_routeadv
= (peer_sort(peer
) == BGP_PEER_IBGP
)
2434 ? BGP_DEFAULT_IBGP_ROUTEADV
2435 : BGP_DEFAULT_EBGP_ROUTEADV
;
2438 /* password apply */
2439 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_PASSWORD
))
2440 PEER_STR_ATTR_INHERIT(peer
, group
, password
,
2441 MTYPE_PEER_PASSWORD
);
2443 if (!BGP_PEER_SU_UNSPEC(peer
))
2446 /* update-source apply */
2447 if (!CHECK_FLAG(peer
->flags_override
, PEER_FLAG_UPDATE_SOURCE
)) {
2448 if (conf
->update_source
) {
2449 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2450 PEER_SU_ATTR_INHERIT(peer
, group
, update_source
);
2451 } else if (conf
->update_if
) {
2452 sockunion_free(peer
->update_source
);
2453 PEER_STR_ATTR_INHERIT(peer
, group
, update_if
,
2454 MTYPE_PEER_UPDATE_SOURCE
);
2458 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2461 /* Peer group's remote AS configuration. */
2462 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2465 struct peer_group
*group
;
2467 struct listnode
*node
, *nnode
;
2469 group
= peer_group_lookup(bgp
, group_name
);
2473 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2477 /* When we setup peer-group AS number all peer group member's AS
2478 number must be updated to same number. */
2479 peer_as_change(group
->conf
, *as
, as_type
);
2481 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2482 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2483 || (peer
->as_type
!= as_type
))
2484 peer_as_change(peer
, *as
, as_type
);
2490 int peer_notify_unconfig(struct peer
*peer
)
2492 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
2493 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2494 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
2498 int peer_group_notify_unconfig(struct peer_group
*group
)
2500 struct peer
*peer
, *other
;
2501 struct listnode
*node
, *nnode
;
2503 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2504 other
= peer
->doppelganger
;
2505 if (other
&& other
->status
!= Deleted
) {
2506 other
->group
= NULL
;
2507 peer_notify_unconfig(other
);
2509 peer_notify_unconfig(peer
);
2514 int peer_group_delete(struct peer_group
*group
)
2518 struct prefix
*prefix
;
2520 struct listnode
*node
, *nnode
;
2525 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2526 other
= peer
->doppelganger
;
2528 if (other
&& other
->status
!= Deleted
) {
2529 other
->group
= NULL
;
2533 list_delete(&group
->peer
);
2535 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2536 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2538 prefix_free(&prefix
);
2540 list_delete(&group
->listen_range
[afi
]);
2543 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2546 bfd_info_free(&(group
->conf
->bfd_info
));
2548 group
->conf
->group
= NULL
;
2549 peer_delete(group
->conf
);
2551 /* Delete from all peer_group list. */
2552 listnode_delete(bgp
->group
, group
);
2554 peer_group_free(group
);
2559 int peer_group_remote_as_delete(struct peer_group
*group
)
2561 struct peer
*peer
, *other
;
2562 struct listnode
*node
, *nnode
;
2564 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2565 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2568 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2569 other
= peer
->doppelganger
;
2573 if (other
&& other
->status
!= Deleted
) {
2574 other
->group
= NULL
;
2578 list_delete_all_node(group
->peer
);
2580 group
->conf
->as
= 0;
2581 group
->conf
->as_type
= AS_UNSPECIFIED
;
2586 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2588 struct prefix
*prefix
;
2589 struct listnode
*node
, *nnode
;
2592 afi
= family2afi(range
->family
);
2594 /* Group needs remote AS configured. */
2595 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2596 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2598 /* Ensure no duplicates. Currently we don't care about overlaps. */
2599 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2600 if (prefix_same(range
, prefix
))
2604 prefix
= prefix_new();
2605 prefix_copy(prefix
, range
);
2606 listnode_add(group
->listen_range
[afi
], prefix
);
2608 /* Update passwords for new ranges */
2609 if (group
->conf
->password
)
2610 bgp_md5_set_prefix(prefix
, group
->conf
->password
);
2615 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2617 struct prefix
*prefix
, prefix2
;
2618 struct listnode
*node
, *nnode
;
2621 char buf
[PREFIX2STR_BUFFER
];
2623 afi
= family2afi(range
->family
);
2625 /* Identify the listen range. */
2626 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2627 if (prefix_same(range
, prefix
))
2632 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2634 prefix2str(prefix
, buf
, sizeof(buf
));
2636 /* Dispose off any dynamic neighbors that exist due to this listen range
2638 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2639 if (!peer_dynamic_neighbor(peer
))
2642 sockunion2hostprefix(&peer
->su
, &prefix2
);
2643 if (prefix_match(prefix
, &prefix2
)) {
2644 if (bgp_debug_neighbor_events(peer
))
2646 "Deleting dynamic neighbor %s group %s upon "
2647 "delete of listen range %s",
2648 peer
->host
, group
->name
, buf
);
2653 /* Get rid of the listen range */
2654 listnode_delete(group
->listen_range
[afi
], prefix
);
2656 /* Remove passwords for deleted ranges */
2657 if (group
->conf
->password
)
2658 bgp_md5_unset_prefix(prefix
);
2663 /* Bind specified peer to peer group. */
2664 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2665 struct peer_group
*group
, as_t
*as
)
2667 int first_member
= 0;
2671 /* Lookup the peer. */
2673 peer
= peer_lookup(bgp
, su
);
2675 /* The peer exist, bind it to the peer-group */
2677 /* When the peer already belongs to a peer-group, check the
2679 if (peer_group_active(peer
)) {
2681 /* The peer is already bound to the peer-group,
2684 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2687 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2690 /* The peer has not specified a remote-as, inherit it from the
2692 if (peer
->as_type
== AS_UNSPECIFIED
) {
2693 peer
->as_type
= group
->conf
->as_type
;
2694 peer
->as
= group
->conf
->as
;
2695 peer
->sort
= group
->conf
->sort
;
2698 if (!group
->conf
->as
&& peer_sort(peer
)) {
2699 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2700 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2703 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2706 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2710 peer_group2peer_config_copy(group
, peer
);
2712 FOREACH_AFI_SAFI (afi
, safi
) {
2713 if (group
->conf
->afc
[afi
][safi
]) {
2714 peer
->afc
[afi
][safi
] = 1;
2716 if (peer_af_find(peer
, afi
, safi
)
2717 || peer_af_create(peer
, afi
, safi
)) {
2718 peer_group2peer_config_copy_af(
2719 group
, peer
, afi
, safi
);
2721 } else if (peer
->afc
[afi
][safi
])
2722 peer_deactivate(peer
, afi
, safi
);
2726 assert(group
&& peer
->group
== group
);
2728 listnode_delete(bgp
->peer
, peer
);
2730 peer
->group
= group
;
2731 listnode_add_sort(bgp
->peer
, peer
);
2733 peer
= peer_lock(peer
); /* group->peer list reference */
2734 listnode_add(group
->peer
, peer
);
2738 /* Advertisement-interval reset */
2739 if (!CHECK_FLAG(group
->conf
->flags
,
2740 PEER_FLAG_ROUTEADV
)) {
2741 group
->conf
->v_routeadv
=
2742 (peer_sort(group
->conf
)
2744 ? BGP_DEFAULT_IBGP_ROUTEADV
2745 : BGP_DEFAULT_EBGP_ROUTEADV
;
2748 /* ebgp-multihop reset */
2749 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2750 group
->conf
->ttl
= MAXTTL
;
2752 /* local-as reset */
2753 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2754 group
->conf
->change_local_as
= 0;
2755 peer_flag_unset(group
->conf
,
2756 PEER_FLAG_LOCAL_AS
);
2757 peer_flag_unset(group
->conf
,
2758 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2759 peer_flag_unset(group
->conf
,
2760 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2764 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2766 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2767 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2768 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2769 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2771 bgp_session_reset(peer
);
2775 /* Create a new peer. */
2777 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2778 && (!group
->conf
->as
)) {
2779 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2782 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2783 group
->conf
->as_type
, 0, 0, group
);
2785 peer
= peer_lock(peer
); /* group->peer list reference */
2786 listnode_add(group
->peer
, peer
);
2788 peer_group2peer_config_copy(group
, peer
);
2790 /* If the peer-group is active for this afi/safi then activate
2792 FOREACH_AFI_SAFI (afi
, safi
) {
2793 if (group
->conf
->afc
[afi
][safi
]) {
2794 peer
->afc
[afi
][safi
] = 1;
2795 peer_af_create(peer
, afi
, safi
);
2796 peer_group2peer_config_copy_af(group
, peer
, afi
,
2798 } else if (peer
->afc
[afi
][safi
])
2799 peer_deactivate(peer
, afi
, safi
);
2802 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2804 /* Set up peer's events and timers. */
2805 if (peer_active(peer
))
2806 bgp_timer_set(peer
);
2812 static int bgp_startup_timer_expire(struct thread
*thread
)
2816 bgp
= THREAD_ARG(thread
);
2817 bgp
->t_startup
= NULL
;
2823 * On shutdown we call the cleanup function which
2824 * does a free of the link list nodes, free up
2825 * the data we are pointing at too.
2827 static void bgp_vrf_string_name_delete(void *data
)
2831 XFREE(MTYPE_TMP
, vname
);
2834 /* BGP instance creation by `router bgp' commands. */
2835 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2836 enum bgp_instance_type inst_type
)
2842 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2845 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2846 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2847 zlog_debug("Creating Default VRF, AS %u", *as
);
2849 zlog_debug("Creating %s %s, AS %u",
2850 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2856 /* Default the EVPN VRF to the default one */
2857 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
&& !bgp_master
.bgp_evpn
) {
2863 bgp
->heuristic_coalesce
= true;
2864 bgp
->inst_type
= inst_type
;
2865 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2867 bgp
->peer_self
= peer_new(bgp
);
2868 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2869 bgp
->peer_self
->host
=
2870 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2871 if (bgp
->peer_self
->hostname
!= NULL
) {
2872 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2873 bgp
->peer_self
->hostname
= NULL
;
2875 if (cmd_hostname_get())
2876 bgp
->peer_self
->hostname
=
2877 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2879 if (bgp
->peer_self
->domainname
!= NULL
) {
2880 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2881 bgp
->peer_self
->domainname
= NULL
;
2883 if (cmd_domainname_get())
2884 bgp
->peer_self
->domainname
=
2885 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2886 bgp
->peer
= list_new();
2887 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2888 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2890 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2892 bgp
->group
= list_new();
2893 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2895 FOREACH_AFI_SAFI (afi
, safi
) {
2896 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2897 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2898 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2900 /* Enable maximum-paths */
2901 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2903 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2907 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2908 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2909 bgp
->default_subgroup_pkt_queue_max
=
2910 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2911 bgp_timers_unset(bgp
);
2912 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2913 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2914 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2915 bgp
->dynamic_neighbors_count
= 0;
2916 bgp
->ebgp_requires_policy
= DEFAULT_EBGP_POLICY_DISABLED
;
2917 bgp
->reject_as_sets
= BGP_REJECT_AS_SETS_DISABLED
;
2918 bgp_addpath_init_bgp_data(&bgp
->tx_addpath
);
2923 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2924 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2926 assert(bgp
->rfapi_cfg
);
2928 #endif /* ENABLE_BGP_VNC */
2930 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2931 bgp
->vpn_policy
[afi
].bgp
= bgp
;
2932 bgp
->vpn_policy
[afi
].afi
= afi
;
2933 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2934 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2937 bgp
->vpn_policy
[afi
].import_vrf
= list_new();
2938 bgp
->vpn_policy
[afi
].import_vrf
->del
=
2939 bgp_vrf_string_name_delete
;
2940 bgp
->vpn_policy
[afi
].export_vrf
= list_new();
2941 bgp
->vpn_policy
[afi
].export_vrf
->del
=
2942 bgp_vrf_string_name_delete
;
2945 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2947 /* TODO - The startup timer needs to be run for the whole of BGP
2949 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2950 bgp
->restart_time
, &bgp
->t_startup
);
2953 /* printable name we can use in debug messages */
2954 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2955 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2965 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2967 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2968 snprintf(bgp
->name_pretty
, len
, "%s %s",
2969 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2975 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2976 memory_order_relaxed
);
2977 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2978 memory_order_relaxed
);
2979 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2983 update_bgp_group_init(bgp
);
2985 /* assign a unique rd id for auto derivation of vrf's RD */
2986 bf_assign_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
2988 bgp
->evpn_info
= XCALLOC(MTYPE_BGP_EVPN_INFO
,
2989 sizeof(struct bgp_evpn_info
));
2996 /* Return the "default VRF" instance of BGP. */
2997 struct bgp
*bgp_get_default(void)
3000 struct listnode
*node
, *nnode
;
3002 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3003 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3008 /* Lookup BGP entry. */
3009 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3012 struct listnode
*node
, *nnode
;
3014 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3016 && ((bgp
->name
== NULL
&& name
== NULL
)
3017 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3022 /* Lookup BGP structure by view name. */
3023 struct bgp
*bgp_lookup_by_name(const char *name
)
3026 struct listnode
*node
, *nnode
;
3028 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3029 if ((bgp
->name
== NULL
&& name
== NULL
)
3030 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3035 /* Lookup BGP instance based on VRF id. */
3036 /* Note: Only to be used for incoming messages from Zebra. */
3037 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3041 /* Lookup VRF (in tree) and follow link. */
3042 vrf
= vrf_lookup_by_id(vrf_id
);
3045 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3048 /* Sets the BGP instance where EVPN is enabled */
3049 void bgp_set_evpn(struct bgp
*bgp
)
3051 if (bm
->bgp_evpn
== bgp
)
3054 /* First, release the reference count we hold on the instance */
3056 bgp_unlock(bm
->bgp_evpn
);
3060 /* Increase the reference count on this new VRF */
3062 bgp_lock(bm
->bgp_evpn
);
3065 /* Returns the BGP instance where EVPN is enabled, if any */
3066 struct bgp
*bgp_get_evpn(void)
3068 return bm
->bgp_evpn
;
3071 /* handle socket creation or deletion, if necessary
3072 * this is called for all new BGP instances
3074 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3079 /* Create BGP server socket, if listen mode not disabled */
3080 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3082 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3084 * suppress vrf socket
3086 if (create
== false) {
3087 bgp_close_vrf_socket(bgp
);
3091 return BGP_ERR_INVALID_VALUE
;
3093 * if vrf_id did not change
3095 if (vrf
->vrf_id
== old_vrf_id
)
3097 if (old_vrf_id
!= VRF_UNKNOWN
) {
3098 /* look for old socket. close it. */
3099 bgp_close_vrf_socket(bgp
);
3101 /* if backend is not yet identified ( VRF_UNKNOWN) then
3102 * creation will be done later
3104 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3106 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3108 return BGP_ERR_INVALID_VALUE
;
3111 return bgp_check_main_socket(create
, bgp
);
3114 /* Called from VTY commands. */
3115 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3116 enum bgp_instance_type inst_type
)
3119 struct vrf
*vrf
= NULL
;
3121 /* Multiple instance check. */
3123 bgp
= bgp_lookup_by_name(name
);
3125 bgp
= bgp_get_default();
3127 /* Already exists. */
3129 if (bgp
->as
!= *as
) {
3131 return BGP_ERR_INSTANCE_MISMATCH
;
3133 if (bgp
->inst_type
!= inst_type
)
3134 return BGP_ERR_INSTANCE_MISMATCH
;
3139 bgp
= bgp_create(as
, name
, inst_type
);
3140 if (bgp_option_check(BGP_OPT_NO_ZEBRA
) && name
)
3141 bgp
->vrf_id
= vrf_generate_id();
3142 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
, true);
3143 bgp_address_init(bgp
);
3144 bgp_tip_hash_init(bgp
);
3148 bgp
->t_rmap_def_originate_eval
= NULL
;
3150 /* If Default instance or VRF, link to the VRF structure, if present. */
3151 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3152 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3153 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3155 bgp_vrf_link(bgp
, vrf
);
3157 /* BGP server socket already processed if BGP instance
3158 * already part of the list
3160 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3161 listnode_add(bm
->bgp
, bgp
);
3163 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3164 if (BGP_DEBUG(zebra
, ZEBRA
))
3165 zlog_debug("%s: Registering BGP instance %s to zebra",
3166 __PRETTY_FUNCTION__
, name
);
3167 bgp_zebra_instance_register(bgp
);
3174 * Make BGP instance "up". Applies only to VRFs (non-default) and
3175 * implies the VRF has been learnt from Zebra.
3177 void bgp_instance_up(struct bgp
*bgp
)
3180 struct listnode
*node
, *next
;
3182 /* Register with zebra. */
3183 bgp_zebra_instance_register(bgp
);
3185 /* Kick off any peers that may have been configured. */
3186 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3187 if (!BGP_PEER_START_SUPPRESSED(peer
))
3188 BGP_EVENT_ADD(peer
, BGP_Start
);
3191 /* Process any networks that have been configured. */
3192 bgp_static_add(bgp
);
3196 * Make BGP instance "down". Applies only to VRFs (non-default) and
3197 * implies the VRF has been deleted by Zebra.
3199 void bgp_instance_down(struct bgp
*bgp
)
3202 struct listnode
*node
;
3203 struct listnode
*next
;
3206 if (bgp
->t_rmap_def_originate_eval
) {
3207 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3208 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3212 /* Bring down peers, so corresponding routes are purged. */
3213 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3214 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3215 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3216 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3218 bgp_session_reset(peer
);
3221 /* Purge network and redistributed routes. */
3222 bgp_purge_static_redist_routes(bgp
);
3224 /* Cleanup registered nexthops (flags) */
3225 bgp_cleanup_nexthops(bgp
);
3228 /* Delete BGP instance. */
3229 int bgp_delete(struct bgp
*bgp
)
3232 struct peer_group
*group
;
3233 struct listnode
*node
, *next
;
3240 hook_call(bgp_inst_delete
, bgp
);
3242 THREAD_OFF(bgp
->t_startup
);
3243 THREAD_OFF(bgp
->t_maxmed_onstartup
);
3244 THREAD_OFF(bgp
->t_update_delay
);
3245 THREAD_OFF(bgp
->t_establish_wait
);
3247 /* Set flag indicating bgp instance delete in progress */
3248 bgp_flag_set(bgp
, BGP_FLAG_DELETE_IN_PROGRESS
);
3250 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3251 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3252 zlog_debug("Deleting Default VRF");
3254 zlog_debug("Deleting %s %s",
3255 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3261 /* unmap from RT list */
3262 bgp_evpn_vrf_delete(bgp
);
3264 /* unmap bgp vrf label */
3265 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP
);
3266 vpn_leak_zebra_vrf_label_withdraw(bgp
, AFI_IP6
);
3269 if (bgp
->t_rmap_def_originate_eval
) {
3270 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3271 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3275 /* Inform peers we're going down. */
3276 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3277 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3278 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3279 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3282 /* Delete static routes (networks). */
3283 bgp_static_delete(bgp
);
3285 /* Unset redistribution. */
3286 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3287 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3288 if (i
!= ZEBRA_ROUTE_BGP
)
3289 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3291 /* Free peers and peer-groups. */
3292 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3293 peer_group_delete(group
);
3295 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3298 if (bgp
->peer_self
) {
3299 peer_delete(bgp
->peer_self
);
3300 bgp
->peer_self
= NULL
;
3303 update_bgp_group_free(bgp
);
3305 /* TODO - Other memory may need to be freed - e.g., NHT */
3310 bgp_cleanup_routes(bgp
);
3312 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3313 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3316 &bgp
->vpn_policy
[afi
]
3317 .import_redirect_rtlist
);
3318 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3321 /* Deregister from Zebra, if needed */
3322 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
)) {
3323 if (BGP_DEBUG(zebra
, ZEBRA
))
3324 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3325 __PRETTY_FUNCTION__
, bgp
->name
);
3326 bgp_zebra_instance_deregister(bgp
);
3329 /* Remove visibility via the master list - there may however still be
3330 * routes to be processed still referencing the struct bgp.
3332 listnode_delete(bm
->bgp
, bgp
);
3334 /* Free interfaces in this instance. */
3337 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3338 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3340 bgp_vrf_unlink(bgp
, vrf
);
3342 /* Update EVPN VRF pointer */
3343 if (bm
->bgp_evpn
== bgp
) {
3344 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3347 bgp_set_evpn(bgp_get_default());
3350 thread_master_free_unused(bm
->master
);
3351 bgp_unlock(bgp
); /* initial reference */
3356 void bgp_free(struct bgp
*bgp
)
3360 struct bgp_table
*table
;
3361 struct bgp_node
*rn
;
3362 struct bgp_rmap
*rmap
;
3366 list_delete(&bgp
->group
);
3367 list_delete(&bgp
->peer
);
3369 if (bgp
->peerhash
) {
3370 hash_free(bgp
->peerhash
);
3371 bgp
->peerhash
= NULL
;
3374 FOREACH_AFI_SAFI (afi
, safi
) {
3375 /* Special handling for 2-level routing tables. */
3376 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3377 || safi
== SAFI_EVPN
) {
3378 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3379 rn
= bgp_route_next(rn
)) {
3380 table
= bgp_node_get_bgp_table_info(rn
);
3381 bgp_table_finish(&table
);
3384 if (bgp
->route
[afi
][safi
])
3385 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3386 if (bgp
->aggregate
[afi
][safi
])
3387 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3388 if (bgp
->rib
[afi
][safi
])
3389 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3390 rmap
= &bgp
->table_map
[afi
][safi
];
3391 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3394 bgp_scan_finish(bgp
);
3395 bgp_address_destroy(bgp
);
3396 bgp_tip_hash_destroy(bgp
);
3398 /* release the auto RD id */
3399 bf_release_index(bm
->rd_idspace
, bgp
->vrf_rd_id
);
3401 bgp_evpn_cleanup(bgp
);
3402 bgp_pbr_cleanup(bgp
);
3403 XFREE(MTYPE_BGP_EVPN_INFO
, bgp
->evpn_info
);
3405 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
3406 vpn_policy_direction_t dir
;
3408 if (bgp
->vpn_policy
[afi
].import_vrf
)
3409 list_delete(&bgp
->vpn_policy
[afi
].import_vrf
);
3410 if (bgp
->vpn_policy
[afi
].export_vrf
)
3411 list_delete(&bgp
->vpn_policy
[afi
].export_vrf
);
3413 dir
= BGP_VPN_POLICY_DIR_FROMVPN
;
3414 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3415 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3416 dir
= BGP_VPN_POLICY_DIR_TOVPN
;
3417 if (bgp
->vpn_policy
[afi
].rtlist
[dir
])
3418 ecommunity_free(&bgp
->vpn_policy
[afi
].rtlist
[dir
]);
3421 XFREE(MTYPE_BGP
, bgp
->name
);
3422 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3424 XFREE(MTYPE_BGP
, bgp
);
3427 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3430 struct listnode
*node
, *nnode
;
3436 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3437 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3438 && !CHECK_FLAG(peer
->sflags
,
3439 PEER_STATUS_ACCEPT_PEER
))
3441 } else if (bm
->bgp
!= NULL
) {
3442 struct listnode
*bgpnode
, *nbgpnode
;
3444 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3445 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3447 && !strcmp(peer
->conf_if
, conf_if
)
3448 && !CHECK_FLAG(peer
->sflags
,
3449 PEER_STATUS_ACCEPT_PEER
))
3455 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3458 struct listnode
*node
, *nnode
;
3464 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3465 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3466 && !CHECK_FLAG(peer
->sflags
,
3467 PEER_STATUS_ACCEPT_PEER
))
3469 } else if (bm
->bgp
!= NULL
) {
3470 struct listnode
*bgpnode
, *nbgpnode
;
3472 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3473 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3475 && !strcmp(peer
->hostname
, hostname
)
3476 && !CHECK_FLAG(peer
->sflags
,
3477 PEER_STATUS_ACCEPT_PEER
))
3483 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3485 struct peer
*peer
= NULL
;
3486 struct peer tmp_peer
;
3488 memset(&tmp_peer
, 0, sizeof(struct peer
));
3491 * We do not want to find the doppelganger peer so search for the peer
3493 * the hash that has PEER_FLAG_CONFIG_NODE
3495 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3500 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3501 } else if (bm
->bgp
!= NULL
) {
3502 struct listnode
*bgpnode
, *nbgpnode
;
3504 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3505 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3514 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3515 union sockunion
*su
,
3516 struct peer_group
*group
)
3522 /* Create peer first; we've already checked group config is valid. */
3523 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3524 group
->conf
->as_type
, 0, 0, group
);
3529 peer
= peer_lock(peer
);
3530 listnode_add(group
->peer
, peer
);
3532 peer_group2peer_config_copy(group
, peer
);
3535 * Bind peer for all AFs configured for the group. We don't call
3536 * peer_group_bind as that is sub-optimal and does some stuff we don't
3539 FOREACH_AFI_SAFI (afi
, safi
) {
3540 if (!group
->conf
->afc
[afi
][safi
])
3542 peer
->afc
[afi
][safi
] = 1;
3544 if (!peer_af_find(peer
, afi
, safi
))
3545 peer_af_create(peer
, afi
, safi
);
3547 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3550 /* Mark as dynamic, but also as a "config node" for other things to
3552 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3553 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3559 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3560 struct prefix
*prefix
)
3562 struct listnode
*node
, *nnode
;
3563 struct prefix
*range
;
3566 afi
= family2afi(prefix
->family
);
3568 if (group
->listen_range
[afi
])
3569 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3571 if (prefix_match(range
, prefix
))
3578 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3579 struct prefix
**listen_range
)
3581 struct prefix
*range
= NULL
;
3582 struct peer_group
*group
= NULL
;
3583 struct listnode
*node
, *nnode
;
3585 *listen_range
= NULL
;
3587 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3588 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3591 } else if (bm
->bgp
!= NULL
) {
3592 struct listnode
*bgpnode
, *nbgpnode
;
3594 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3595 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3596 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3602 *listen_range
= range
;
3603 return (group
&& range
) ? group
: NULL
;
3606 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3608 struct peer_group
*group
;
3611 struct prefix prefix
;
3612 struct prefix
*listen_range
;
3614 char buf
[PREFIX2STR_BUFFER
];
3615 char buf1
[PREFIX2STR_BUFFER
];
3617 sockunion2hostprefix(su
, &prefix
);
3619 /* See if incoming connection matches a configured listen range. */
3620 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3631 prefix2str(&prefix
, buf
, sizeof(buf
));
3632 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3634 if (bgp_debug_neighbor_events(NULL
))
3636 "Dynamic Neighbor %s matches group %s listen range %s",
3637 buf
, group
->name
, buf1
);
3639 /* Are we within the listen limit? */
3640 dncount
= gbgp
->dynamic_neighbors_count
;
3642 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3643 if (bgp_debug_neighbor_events(NULL
))
3644 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3645 inet_sutop(su
, buf
),
3646 gbgp
->dynamic_neighbors_limit
);
3650 /* Ensure group is not disabled. */
3651 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3652 if (bgp_debug_neighbor_events(NULL
))
3654 "Dynamic Neighbor %s rejected - group %s disabled",
3659 /* Check that at least one AF is activated for the group. */
3660 if (!peer_group_af_configured(group
)) {
3661 if (bgp_debug_neighbor_events(NULL
))
3663 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3668 /* Create dynamic peer and bind to associated group. */
3669 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3672 gbgp
->dynamic_neighbors_count
= ++dncount
;
3674 if (bgp_debug_neighbor_events(peer
))
3675 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3676 peer
->host
, group
->name
, dncount
);
3681 static void peer_drop_dynamic_neighbor(struct peer
*peer
)
3684 if (peer
->group
->bgp
) {
3685 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3687 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3689 if (bgp_debug_neighbor_events(peer
))
3690 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3691 peer
->group
->name
, dncount
);
3694 /* If peer is configured at least one address family return 1. */
3695 int peer_active(struct peer
*peer
)
3697 if (BGP_PEER_SU_UNSPEC(peer
))
3699 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3700 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3701 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3702 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3703 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3704 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3705 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3706 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3707 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3708 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3709 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3714 /* If peer is negotiated at least one address family return 1. */
3715 int peer_active_nego(struct peer
*peer
)
3717 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3718 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3719 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3720 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3721 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3722 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3723 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3724 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3725 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3726 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3727 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3728 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3729 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3734 void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3735 enum peer_change_type type
)
3737 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3740 if (peer
->status
!= Established
)
3743 if (type
== peer_change_reset
) {
3744 /* If we're resetting session, we've to delete both peer struct
3746 if ((peer
->doppelganger
)
3747 && (peer
->doppelganger
->status
!= Deleted
)
3748 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3749 PEER_FLAG_CONFIG_NODE
)))
3750 peer_delete(peer
->doppelganger
);
3752 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3753 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3754 } else if (type
== peer_change_reset_in
) {
3755 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3756 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3757 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3759 if ((peer
->doppelganger
)
3760 && (peer
->doppelganger
->status
!= Deleted
)
3761 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3762 PEER_FLAG_CONFIG_NODE
)))
3763 peer_delete(peer
->doppelganger
);
3765 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3766 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3768 } else if (type
== peer_change_reset_out
) {
3769 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3770 bgp_announce_route(peer
, afi
, safi
);
3774 struct peer_flag_action
{
3778 /* This flag can be set for peer-group member. */
3779 uint8_t not_for_member
;
3781 /* Action when the flag is changed. */
3782 enum peer_change_type type
;
3785 static const struct peer_flag_action peer_flag_action_list
[] = {
3786 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3787 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3788 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3789 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3790 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3791 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3792 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3793 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3794 {PEER_FLAG_ENFORCE_FIRST_AS
, 0, peer_change_reset_in
},
3795 {PEER_FLAG_IFPEER_V6ONLY
, 0, peer_change_reset
},
3796 {PEER_FLAG_ROUTEADV
, 0, peer_change_none
},
3797 {PEER_FLAG_TIMER
, 0, peer_change_none
},
3798 {PEER_FLAG_TIMER_CONNECT
, 0, peer_change_none
},
3799 {PEER_FLAG_PASSWORD
, 0, peer_change_none
},
3800 {PEER_FLAG_LOCAL_AS
, 0, peer_change_none
},
3801 {PEER_FLAG_LOCAL_AS_NO_PREPEND
, 0, peer_change_none
},
3802 {PEER_FLAG_LOCAL_AS_REPLACE_AS
, 0, peer_change_none
},
3803 {PEER_FLAG_UPDATE_SOURCE
, 0, peer_change_none
},
3806 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3807 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3808 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3809 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3810 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3811 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3812 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3813 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3814 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3815 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3816 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3817 {PEER_FLAG_DEFAULT_ORIGINATE
, 0, peer_change_none
},
3818 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3819 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3820 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3821 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3822 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3823 {PEER_FLAG_MAX_PREFIX
, 0, peer_change_none
},
3824 {PEER_FLAG_MAX_PREFIX_WARNING
, 0, peer_change_none
},
3825 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3826 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3827 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3828 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3829 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3830 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3831 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3834 /* Proper action set. */
3835 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3836 int size
, struct peer_flag_action
*action
,
3843 const struct peer_flag_action
*match
= NULL
;
3845 /* Check peer's frag action. */
3846 for (i
= 0; i
< size
; i
++) {
3847 match
= &action_list
[i
];
3849 if (match
->flag
== 0)
3852 if (match
->flag
& flag
) {
3855 if (match
->type
== peer_change_reset_in
)
3857 if (match
->type
== peer_change_reset_out
)
3859 if (match
->type
== peer_change_reset
) {
3863 if (match
->not_for_member
)
3864 action
->not_for_member
= 1;
3868 /* Set peer clear type. */
3869 if (reset_in
&& reset_out
)
3870 action
->type
= peer_change_reset
;
3872 action
->type
= peer_change_reset_in
;
3874 action
->type
= peer_change_reset_out
;
3876 action
->type
= peer_change_none
;
3881 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3883 if (flag
== PEER_FLAG_SHUTDOWN
) {
3884 if (CHECK_FLAG(peer
->flags
, flag
)) {
3885 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3886 peer_nsf_stop(peer
);
3888 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3889 if (peer
->t_pmax_restart
) {
3890 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3891 if (bgp_debug_neighbor_events(peer
))
3893 "%s Maximum-prefix restart timer canceled",
3897 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3898 peer_nsf_stop(peer
);
3900 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3901 char *msg
= peer
->tx_shutdown_message
;
3904 if (!msg
&& peer_group_active(peer
))
3905 msg
= peer
->group
->conf
3906 ->tx_shutdown_message
;
3907 msglen
= msg
? strlen(msg
) : 0;
3912 uint8_t msgbuf
[129];
3915 memcpy(msgbuf
+ 1, msg
, msglen
);
3917 bgp_notify_send_with_data(
3918 peer
, BGP_NOTIFY_CEASE
,
3919 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3920 msgbuf
, msglen
+ 1);
3923 peer
, BGP_NOTIFY_CEASE
,
3924 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3926 bgp_session_reset(peer
);
3928 peer
->v_start
= BGP_INIT_START_TIMER
;
3929 BGP_EVENT_ADD(peer
, BGP_Stop
);
3931 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3932 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3933 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3934 else if (flag
== PEER_FLAG_PASSIVE
)
3935 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3936 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3937 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3939 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3940 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3942 bgp_session_reset(peer
);
3945 /* Change specified peer flag. */
3946 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3950 bool invert
, member_invert
;
3951 struct peer
*member
;
3952 struct listnode
*node
, *nnode
;
3953 struct peer_flag_action action
;
3955 memset(&action
, 0, sizeof(struct peer_flag_action
));
3956 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3958 invert
= CHECK_FLAG(peer
->flags_invert
, flag
);
3959 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3962 /* Abort if no flag action exists. */
3964 return BGP_ERR_INVALID_FLAG
;
3966 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
3967 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3968 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3969 return BGP_ERR_PEER_FLAG_CONFLICT
;
3971 /* Handle flag updates where desired state matches current state. */
3972 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3973 if (set
&& CHECK_FLAG(peer
->flags
, flag
)) {
3974 COND_FLAG(peer
->flags_override
, flag
, !invert
);
3978 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
)) {
3979 COND_FLAG(peer
->flags_override
, flag
, invert
);
3984 /* Inherit from peer-group or set/unset flags accordingly. */
3985 if (peer_group_active(peer
) && set
== invert
)
3986 peer_flag_inherit(peer
, flag
);
3988 COND_FLAG(peer
->flags
, flag
, set
);
3990 /* Check if handling a regular peer. */
3991 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3992 /* Update flag override state accordingly. */
3993 COND_FLAG(peer
->flags_override
, flag
, set
!= invert
);
3995 /* Execute flag action on peer. */
3996 if (action
.type
== peer_change_reset
)
3997 peer_flag_modify_action(peer
, flag
);
3999 /* Skip peer-group mechanics for regular peers. */
4003 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4004 bgp_nht_register_enhe_capability_interfaces(peer
);
4007 * Update peer-group members, unless they are explicitely overriding
4008 * peer-group configuration.
4010 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4011 /* Skip peers with overridden configuration. */
4012 if (CHECK_FLAG(member
->flags_override
, flag
))
4015 /* Check if only member without group is inverted. */
4017 CHECK_FLAG(member
->flags_invert
, flag
) && !invert
;
4019 /* Skip peers with equivalent configuration. */
4020 if (set
!= member_invert
&& CHECK_FLAG(member
->flags
, flag
))
4023 if (set
== member_invert
&& !CHECK_FLAG(member
->flags
, flag
))
4026 /* Update flag on peer-group member. */
4027 COND_FLAG(member
->flags
, flag
, set
!= member_invert
);
4029 if (set
&& flag
== PEER_FLAG_CAPABILITY_ENHE
)
4030 bgp_nht_register_enhe_capability_interfaces(member
);
4032 /* Execute flag action on peer-group member. */
4033 if (action
.type
== peer_change_reset
)
4034 peer_flag_modify_action(member
, flag
);
4040 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
4042 return peer_flag_modify(peer
, flag
, 1);
4045 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4047 return peer_flag_modify(peer
, flag
, 0);
4050 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4051 uint32_t flag
, bool set
)
4055 bool invert
, member_invert
;
4056 struct peer
*member
;
4057 struct listnode
*node
, *nnode
;
4058 struct peer_flag_action action
;
4060 memset(&action
, 0, sizeof(struct peer_flag_action
));
4061 size
= sizeof peer_af_flag_action_list
4062 / sizeof(struct peer_flag_action
);
4064 invert
= CHECK_FLAG(peer
->af_flags_invert
[afi
][safi
], flag
);
4065 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4068 /* Abort if flag action exists. */
4070 return BGP_ERR_INVALID_FLAG
;
4072 /* Special check for reflector client. */
4073 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4074 && peer_sort(peer
) != BGP_PEER_IBGP
)
4075 return BGP_ERR_NOT_INTERNAL_PEER
;
4077 /* Special check for remove-private-AS. */
4078 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4079 && peer_sort(peer
) == BGP_PEER_IBGP
)
4080 return BGP_ERR_REMOVE_PRIVATE_AS
;
4082 /* as-override is not allowed for IBGP peers */
4083 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4084 return BGP_ERR_AS_OVERRIDE
;
4086 /* Handle flag updates where desired state matches current state. */
4087 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4088 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4089 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4094 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
)) {
4095 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4102 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4103 * if we are setting/unsetting flags which conflict with this flag
4104 * handle accordingly
4106 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
4110 * if we are setting NEXTHOP_SELF, we need to unset the
4111 * NEXTHOP_UNCHANGED flag
4113 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4114 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4115 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4116 PEER_FLAG_NEXTHOP_UNCHANGED
);
4120 * if we are unsetting NEXTHOP_SELF, we need to set the
4121 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4123 if (CHECK_FLAG(flag
, PEER_FLAG_NEXTHOP_SELF
) ||
4124 CHECK_FLAG(flag
, PEER_FLAG_FORCE_NEXTHOP_SELF
))
4125 SET_FLAG(peer
->af_flags
[afi
][safi
],
4126 PEER_FLAG_NEXTHOP_UNCHANGED
);
4130 /* Inherit from peer-group or set/unset flags accordingly. */
4131 if (peer_group_active(peer
) && set
== invert
)
4132 peer_af_flag_inherit(peer
, afi
, safi
, flag
);
4134 COND_FLAG(peer
->af_flags
[afi
][safi
], flag
, set
);
4136 /* Execute action when peer is established. */
4137 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4138 && peer
->status
== Established
) {
4139 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4140 bgp_clear_adj_in(peer
, afi
, safi
);
4142 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4143 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4144 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4145 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4146 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4147 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4148 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4149 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4151 peer_change_action(peer
, afi
, safi
, action
.type
);
4155 /* Check if handling a regular peer. */
4156 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4157 COND_FLAG(peer
->af_flags_override
[afi
][safi
], flag
,
4161 * Update peer-group members, unless they are explicitely
4162 * overriding peer-group configuration.
4164 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
,
4166 /* Skip peers with overridden configuration. */
4167 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4171 /* Check if only member without group is inverted. */
4173 CHECK_FLAG(member
->af_flags_invert
[afi
][safi
],
4177 /* Skip peers with equivalent configuration. */
4178 if (set
!= member_invert
4179 && CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4182 if (set
== member_invert
4183 && !CHECK_FLAG(member
->af_flags
[afi
][safi
], flag
))
4186 /* Update flag on peer-group member. */
4187 COND_FLAG(member
->af_flags
[afi
][safi
], flag
,
4188 set
!= member_invert
);
4190 /* Execute flag action on peer-group member. */
4191 if (member
->status
== Established
) {
4192 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4193 bgp_clear_adj_in(member
, afi
, safi
);
4195 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4196 member
->last_reset
=
4197 PEER_DOWN_RR_CLIENT_CHANGE
;
4199 == PEER_FLAG_RSERVER_CLIENT
)
4200 member
->last_reset
=
4201 PEER_DOWN_RS_CLIENT_CHANGE
;
4203 == PEER_FLAG_ORF_PREFIX_SM
)
4204 member
->last_reset
=
4205 PEER_DOWN_CAPABILITY_CHANGE
;
4207 == PEER_FLAG_ORF_PREFIX_RM
)
4208 member
->last_reset
=
4209 PEER_DOWN_CAPABILITY_CHANGE
;
4211 peer_change_action(member
, afi
, safi
,
4221 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4223 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4226 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4228 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4232 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4234 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4235 peer
->tx_shutdown_message
=
4236 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4240 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4242 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4247 /* EBGP multihop configuration. */
4248 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4250 struct peer_group
*group
;
4251 struct listnode
*node
, *nnode
;
4254 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4257 /* see comment in peer_ttl_security_hops_set() */
4258 if (ttl
!= MAXTTL
) {
4259 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4260 group
= peer
->group
;
4261 if (group
->conf
->gtsm_hops
!= 0)
4262 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4264 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4266 if (peer1
->sort
== BGP_PEER_IBGP
)
4269 if (peer1
->gtsm_hops
!= 0)
4270 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4273 if (peer
->gtsm_hops
!= 0)
4274 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4280 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4281 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4282 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4283 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4284 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4286 bgp_session_reset(peer
);
4289 group
= peer
->group
;
4290 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4291 if (peer
->sort
== BGP_PEER_IBGP
)
4294 peer
->ttl
= group
->conf
->ttl
;
4296 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4297 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4298 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4300 bgp_session_reset(peer
);
4306 int peer_ebgp_multihop_unset(struct peer
*peer
)
4308 struct peer_group
*group
;
4309 struct listnode
*node
, *nnode
;
4311 if (peer
->sort
== BGP_PEER_IBGP
)
4314 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4315 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4317 if (peer_group_active(peer
))
4318 peer
->ttl
= peer
->group
->conf
->ttl
;
4320 peer
->ttl
= BGP_DEFAULT_TTL
;
4322 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4323 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4324 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4325 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4327 bgp_session_reset(peer
);
4329 group
= peer
->group
;
4330 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4331 if (peer
->sort
== BGP_PEER_IBGP
)
4334 peer
->ttl
= BGP_DEFAULT_TTL
;
4336 if (peer
->fd
>= 0) {
4337 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4339 peer
, BGP_NOTIFY_CEASE
,
4340 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4342 bgp_session_reset(peer
);
4349 /* Neighbor description. */
4350 int peer_description_set(struct peer
*peer
, const char *desc
)
4352 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4354 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4359 int peer_description_unset(struct peer
*peer
)
4361 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4368 /* Neighbor update-source. */
4369 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4371 struct peer
*member
;
4372 struct listnode
*node
, *nnode
;
4374 /* Set flag and configuration on peer. */
4375 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4376 if (peer
->update_if
) {
4377 if (strcmp(peer
->update_if
, ifname
) == 0)
4379 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4381 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4382 sockunion_free(peer
->update_source
);
4383 peer
->update_source
= NULL
;
4385 /* Check if handling a regular peer. */
4386 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4387 /* Send notification or reset peer depending on state. */
4388 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4389 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4390 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4391 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4393 bgp_session_reset(peer
);
4395 /* Skip peer-group mechanics for regular peers. */
4400 * Set flag and configuration on all peer-group members, unless they are
4401 * explicitely overriding peer-group configuration.
4403 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4404 /* Skip peers with overridden configuration. */
4405 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4408 /* Skip peers with the same configuration. */
4409 if (member
->update_if
) {
4410 if (strcmp(member
->update_if
, ifname
) == 0)
4412 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4415 /* Set flag and configuration on peer-group member. */
4416 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4417 member
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4418 sockunion_free(member
->update_source
);
4419 member
->update_source
= NULL
;
4421 /* Send notification or reset peer depending on state. */
4422 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4423 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4424 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4425 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4427 bgp_session_reset(member
);
4433 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4435 struct peer
*member
;
4436 struct listnode
*node
, *nnode
;
4438 /* Set flag and configuration on peer. */
4439 peer_flag_set(peer
, PEER_FLAG_UPDATE_SOURCE
);
4440 if (peer
->update_source
) {
4441 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4443 sockunion_free(peer
->update_source
);
4445 peer
->update_source
= sockunion_dup(su
);
4446 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4448 /* Check if handling a regular peer. */
4449 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4450 /* Send notification or reset peer depending on state. */
4451 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4452 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4453 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4454 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4456 bgp_session_reset(peer
);
4458 /* Skip peer-group mechanics for regular peers. */
4463 * Set flag and configuration on all peer-group members, unless they are
4464 * explicitely overriding peer-group configuration.
4466 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4467 /* Skip peers with overridden configuration. */
4468 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4471 /* Skip peers with the same configuration. */
4472 if (member
->update_source
) {
4473 if (sockunion_cmp(member
->update_source
, su
) == 0)
4475 sockunion_free(member
->update_source
);
4478 /* Set flag and configuration on peer-group member. */
4479 SET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4480 member
->update_source
= sockunion_dup(su
);
4481 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4483 /* Send notification or reset peer depending on state. */
4484 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4485 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4486 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4487 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4489 bgp_session_reset(member
);
4495 int peer_update_source_unset(struct peer
*peer
)
4497 struct peer
*member
;
4498 struct listnode
*node
, *nnode
;
4500 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_UPDATE_SOURCE
))
4503 /* Inherit configuration from peer-group if peer is member. */
4504 if (peer_group_active(peer
)) {
4505 peer_flag_inherit(peer
, PEER_FLAG_UPDATE_SOURCE
);
4506 PEER_SU_ATTR_INHERIT(peer
, peer
->group
, update_source
);
4507 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, update_if
,
4508 MTYPE_PEER_UPDATE_SOURCE
);
4510 /* Otherwise remove flag and configuration from peer. */
4511 peer_flag_unset(peer
, PEER_FLAG_UPDATE_SOURCE
);
4512 sockunion_free(peer
->update_source
);
4513 peer
->update_source
= NULL
;
4514 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4517 /* Check if handling a regular peer. */
4518 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4519 /* Send notification or reset peer depending on state. */
4520 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4521 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4522 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4523 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4525 bgp_session_reset(peer
);
4527 /* Skip peer-group mechanics for regular peers. */
4532 * Set flag and configuration on all peer-group members, unless they are
4533 * explicitely overriding peer-group configuration.
4535 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4536 /* Skip peers with overridden configuration. */
4537 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_UPDATE_SOURCE
))
4540 /* Skip peers with the same configuration. */
4541 if (!CHECK_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
)
4542 && !member
->update_source
&& !member
->update_if
)
4545 /* Remove flag and configuration on peer-group member. */
4546 UNSET_FLAG(member
->flags
, PEER_FLAG_UPDATE_SOURCE
);
4547 sockunion_free(member
->update_source
);
4548 member
->update_source
= NULL
;
4549 XFREE(MTYPE_PEER_UPDATE_SOURCE
, member
->update_if
);
4551 /* Send notification or reset peer depending on state. */
4552 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
4553 member
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4554 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
4555 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4557 bgp_session_reset(member
);
4563 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4564 const char *rmap
, struct route_map
*route_map
)
4566 struct peer
*member
;
4567 struct listnode
*node
, *nnode
;
4569 /* Set flag and configuration on peer. */
4570 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_DEFAULT_ORIGINATE
);
4572 if (!peer
->default_rmap
[afi
][safi
].name
4573 || strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0) {
4574 if (peer
->default_rmap
[afi
][safi
].name
)
4575 XFREE(MTYPE_ROUTE_MAP_NAME
,
4576 peer
->default_rmap
[afi
][safi
].name
);
4578 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4579 peer
->default_rmap
[afi
][safi
].name
=
4580 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4581 peer
->default_rmap
[afi
][safi
].map
= route_map
;
4582 route_map_counter_increment(route_map
);
4585 if (peer
->default_rmap
[afi
][safi
].name
)
4586 XFREE(MTYPE_ROUTE_MAP_NAME
,
4587 peer
->default_rmap
[afi
][safi
].name
);
4589 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4590 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4591 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4594 /* Check if handling a regular peer. */
4595 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4596 /* Update peer route announcements. */
4597 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4598 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4599 bgp_default_originate(peer
, afi
, safi
, 0);
4600 bgp_announce_route(peer
, afi
, safi
);
4603 /* Skip peer-group mechanics for regular peers. */
4608 * Set flag and configuration on all peer-group members, unless they are
4609 * explicitely overriding peer-group configuration.
4611 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4612 /* Skip peers with overridden configuration. */
4613 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4614 PEER_FLAG_DEFAULT_ORIGINATE
))
4617 /* Set flag and configuration on peer-group member. */
4618 SET_FLAG(member
->af_flags
[afi
][safi
],
4619 PEER_FLAG_DEFAULT_ORIGINATE
);
4621 if (member
->default_rmap
[afi
][safi
].name
)
4622 XFREE(MTYPE_ROUTE_MAP_NAME
,
4623 member
->default_rmap
[afi
][safi
].name
);
4624 route_map_counter_decrement(
4625 member
->default_rmap
[afi
][safi
].map
);
4626 member
->default_rmap
[afi
][safi
].name
=
4627 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4628 member
->default_rmap
[afi
][safi
].map
= route_map
;
4629 route_map_counter_increment(route_map
);
4632 /* Update peer route announcements. */
4633 if (member
->status
== Established
4634 && member
->afc_nego
[afi
][safi
]) {
4635 update_group_adjust_peer(
4636 peer_af_find(member
, afi
, safi
));
4637 bgp_default_originate(member
, afi
, safi
, 0);
4638 bgp_announce_route(member
, afi
, safi
);
4645 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4647 struct peer
*member
;
4648 struct listnode
*node
, *nnode
;
4650 /* Inherit configuration from peer-group if peer is member. */
4651 if (peer_group_active(peer
)) {
4652 peer_af_flag_inherit(peer
, afi
, safi
,
4653 PEER_FLAG_DEFAULT_ORIGINATE
);
4654 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
4655 default_rmap
[afi
][safi
].name
,
4656 MTYPE_ROUTE_MAP_NAME
);
4657 PEER_ATTR_INHERIT(peer
, peer
->group
,
4658 default_rmap
[afi
][safi
].map
);
4660 /* Otherwise remove flag and configuration from peer. */
4661 peer_af_flag_unset(peer
, afi
, safi
,
4662 PEER_FLAG_DEFAULT_ORIGINATE
);
4663 if (peer
->default_rmap
[afi
][safi
].name
)
4664 XFREE(MTYPE_ROUTE_MAP_NAME
,
4665 peer
->default_rmap
[afi
][safi
].name
);
4666 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4667 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4668 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4671 /* Check if handling a regular peer. */
4672 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4673 /* Update peer route announcements. */
4674 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4675 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4676 bgp_default_originate(peer
, afi
, safi
, 1);
4677 bgp_announce_route(peer
, afi
, safi
);
4680 /* Skip peer-group mechanics for regular peers. */
4685 * Remove flag and configuration from all peer-group members, unless
4686 * they are explicitely overriding peer-group configuration.
4688 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4689 /* Skip peers with overridden configuration. */
4690 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4691 PEER_FLAG_DEFAULT_ORIGINATE
))
4694 /* Remove flag and configuration on peer-group member. */
4695 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4696 PEER_FLAG_DEFAULT_ORIGINATE
);
4697 if (peer
->default_rmap
[afi
][safi
].name
)
4698 XFREE(MTYPE_ROUTE_MAP_NAME
,
4699 peer
->default_rmap
[afi
][safi
].name
);
4700 route_map_counter_decrement(peer
->default_rmap
[afi
][safi
].map
);
4701 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4702 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4704 /* Update peer route announcements. */
4705 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4706 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4707 bgp_default_originate(peer
, afi
, safi
, 1);
4708 bgp_announce_route(peer
, afi
, safi
);
4715 int peer_port_set(struct peer
*peer
, uint16_t port
)
4721 int peer_port_unset(struct peer
*peer
)
4723 peer
->port
= BGP_PORT_DEFAULT
;
4728 * Helper function that is called after the name of the policy
4729 * being used by a peer has changed (AF specific). Automatically
4730 * initiates inbound or outbound processing as needed.
4732 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4736 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4737 if (peer
->status
== Established
)
4738 bgp_announce_route(peer
, afi
, safi
);
4740 if (peer
->status
!= Established
)
4743 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4744 PEER_FLAG_SOFT_RECONFIG
))
4745 bgp_soft_reconfig_in(peer
, afi
, safi
);
4746 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4747 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4748 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4753 /* neighbor weight. */
4754 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4756 struct peer
*member
;
4757 struct listnode
*node
, *nnode
;
4759 /* Set flag and configuration on peer. */
4760 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4761 if (peer
->weight
[afi
][safi
] != weight
) {
4762 peer
->weight
[afi
][safi
] = weight
;
4763 peer_on_policy_change(peer
, afi
, safi
, 0);
4766 /* Skip peer-group mechanics for regular peers. */
4767 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4771 * Set flag and configuration on all peer-group members, unless they are
4772 * explicitely overriding peer-group configuration.
4774 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4775 /* Skip peers with overridden configuration. */
4776 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
4780 /* Set flag and configuration on peer-group member. */
4781 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4782 if (member
->weight
[afi
][safi
] != weight
) {
4783 member
->weight
[afi
][safi
] = weight
;
4784 peer_on_policy_change(member
, afi
, safi
, 0);
4791 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4793 struct peer
*member
;
4794 struct listnode
*node
, *nnode
;
4796 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4799 /* Inherit configuration from peer-group if peer is member. */
4800 if (peer_group_active(peer
)) {
4801 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4802 PEER_ATTR_INHERIT(peer
, peer
->group
, weight
[afi
][safi
]);
4804 peer_on_policy_change(peer
, afi
, safi
, 0);
4808 /* Remove flag and configuration from peer. */
4809 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4810 peer
->weight
[afi
][safi
] = 0;
4811 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 * Remove flag and configuration from all peer-group members, unless
4819 * they are 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 /* Skip peers where flag is already disabled. */
4828 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
))
4831 /* Remove flag and configuration on peer-group member. */
4832 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4833 member
->weight
[afi
][safi
] = 0;
4834 peer_on_policy_change(member
, afi
, safi
, 0);
4840 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4842 struct peer
*member
;
4843 struct listnode
*node
, *nnode
;
4845 if (keepalive
> 65535)
4846 return BGP_ERR_INVALID_VALUE
;
4848 if (holdtime
> 65535)
4849 return BGP_ERR_INVALID_VALUE
;
4851 if (holdtime
< 3 && holdtime
!= 0)
4852 return BGP_ERR_INVALID_VALUE
;
4854 /* Set flag and configuration on peer. */
4855 peer_flag_set(peer
, PEER_FLAG_TIMER
);
4856 peer
->holdtime
= holdtime
;
4857 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4859 /* Skip peer-group mechanics for regular peers. */
4860 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4864 * Set flag and configuration on all peer-group members, unless they are
4865 * explicitely overriding peer-group configuration.
4867 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4868 /* Skip peers with overridden configuration. */
4869 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4872 /* Set flag and configuration on peer-group member. */
4873 SET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4874 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4875 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4881 int peer_timers_unset(struct peer
*peer
)
4883 struct peer
*member
;
4884 struct listnode
*node
, *nnode
;
4886 /* Inherit configuration from peer-group if peer is member. */
4887 if (peer_group_active(peer
)) {
4888 peer_flag_inherit(peer
, PEER_FLAG_TIMER
);
4889 PEER_ATTR_INHERIT(peer
, peer
->group
, holdtime
);
4890 PEER_ATTR_INHERIT(peer
, peer
->group
, keepalive
);
4892 /* Otherwise remove flag and configuration from peer. */
4893 peer_flag_unset(peer
, PEER_FLAG_TIMER
);
4895 peer
->keepalive
= 0;
4898 /* Skip peer-group mechanics for regular peers. */
4899 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4903 * Remove flag and configuration from all peer-group members, unless
4904 * they are explicitely overriding peer-group configuration.
4906 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4907 /* Skip peers with overridden configuration. */
4908 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER
))
4911 /* Remove flag and configuration on peer-group member. */
4912 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER
);
4913 member
->holdtime
= 0;
4914 member
->keepalive
= 0;
4920 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4922 struct peer
*member
;
4923 struct listnode
*node
, *nnode
;
4925 if (connect
> 65535)
4926 return BGP_ERR_INVALID_VALUE
;
4928 /* Set flag and configuration on peer. */
4929 peer_flag_set(peer
, PEER_FLAG_TIMER_CONNECT
);
4930 peer
->connect
= connect
;
4931 peer
->v_connect
= connect
;
4933 /* Skip peer-group mechanics for regular peers. */
4934 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4938 * Set flag and configuration on all peer-group members, unless they are
4939 * explicitely overriding peer-group configuration.
4941 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4942 /* Skip peers with overridden configuration. */
4943 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4946 /* Set flag and configuration on peer-group member. */
4947 SET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4948 member
->connect
= connect
;
4949 member
->v_connect
= connect
;
4955 int peer_timers_connect_unset(struct peer
*peer
)
4957 struct peer
*member
;
4958 struct listnode
*node
, *nnode
;
4960 /* Inherit configuration from peer-group if peer is member. */
4961 if (peer_group_active(peer
)) {
4962 peer_flag_inherit(peer
, PEER_FLAG_TIMER_CONNECT
);
4963 PEER_ATTR_INHERIT(peer
, peer
->group
, connect
);
4965 /* Otherwise remove flag and configuration from peer. */
4966 peer_flag_unset(peer
, PEER_FLAG_TIMER_CONNECT
);
4970 /* Set timer with fallback to default value. */
4972 peer
->v_connect
= peer
->connect
;
4974 peer
->v_connect
= peer
->bgp
->default_connect_retry
;
4976 /* Skip peer-group mechanics for regular peers. */
4977 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4981 * Remove flag and configuration from all peer-group members, unless
4982 * they are explicitely overriding peer-group configuration.
4984 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
4985 /* Skip peers with overridden configuration. */
4986 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_TIMER_CONNECT
))
4989 /* Remove flag and configuration on peer-group member. */
4990 UNSET_FLAG(member
->flags
, PEER_FLAG_TIMER_CONNECT
);
4991 member
->connect
= 0;
4992 member
->v_connect
= peer
->bgp
->default_connect_retry
;
4998 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
5000 struct peer
*member
;
5001 struct listnode
*node
, *nnode
;
5004 return BGP_ERR_INVALID_VALUE
;
5006 /* Set flag and configuration on peer. */
5007 peer_flag_set(peer
, PEER_FLAG_ROUTEADV
);
5008 peer
->routeadv
= routeadv
;
5009 peer
->v_routeadv
= routeadv
;
5011 /* Check if handling a regular peer. */
5012 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5013 /* Update peer route announcements. */
5014 update_group_adjust_peer_afs(peer
);
5015 if (peer
->status
== Established
)
5016 bgp_announce_route_all(peer
);
5018 /* Skip peer-group mechanics for regular peers. */
5023 * Set flag and configuration on all peer-group members, unless they are
5024 * explicitely overriding peer-group configuration.
5026 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5027 /* Skip peers with overridden configuration. */
5028 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5031 /* Set flag and configuration on peer-group member. */
5032 SET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5033 member
->routeadv
= routeadv
;
5034 member
->v_routeadv
= routeadv
;
5036 /* Update peer route announcements. */
5037 update_group_adjust_peer_afs(member
);
5038 if (member
->status
== Established
)
5039 bgp_announce_route_all(member
);
5045 int peer_advertise_interval_unset(struct peer
*peer
)
5047 struct peer
*member
;
5048 struct listnode
*node
, *nnode
;
5050 /* Inherit configuration from peer-group if peer is member. */
5051 if (peer_group_active(peer
)) {
5052 peer_flag_inherit(peer
, PEER_FLAG_ROUTEADV
);
5053 PEER_ATTR_INHERIT(peer
, peer
->group
, routeadv
);
5055 /* Otherwise remove flag and configuration from peer. */
5056 peer_flag_unset(peer
, PEER_FLAG_ROUTEADV
);
5060 /* Set timer with fallback to default value. */
5062 peer
->v_routeadv
= peer
->routeadv
;
5064 peer
->v_routeadv
= (peer
->sort
== BGP_PEER_IBGP
)
5065 ? BGP_DEFAULT_IBGP_ROUTEADV
5066 : BGP_DEFAULT_EBGP_ROUTEADV
;
5068 /* Check if handling a regular peer. */
5069 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5070 /* Update peer route announcements. */
5071 update_group_adjust_peer_afs(peer
);
5072 if (peer
->status
== Established
)
5073 bgp_announce_route_all(peer
);
5075 /* Skip peer-group mechanics for regular peers. */
5080 * Remove flag and configuration from all peer-group members, unless
5081 * they are explicitely overriding peer-group configuration.
5083 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5084 /* Skip peers with overridden configuration. */
5085 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_ROUTEADV
))
5088 /* Remove flag and configuration on peer-group member. */
5089 UNSET_FLAG(member
->flags
, PEER_FLAG_ROUTEADV
);
5090 member
->routeadv
= 0;
5091 member
->v_routeadv
= (member
->sort
== BGP_PEER_IBGP
)
5092 ? BGP_DEFAULT_IBGP_ROUTEADV
5093 : BGP_DEFAULT_EBGP_ROUTEADV
;
5095 /* Update peer route announcements. */
5096 update_group_adjust_peer_afs(member
);
5097 if (member
->status
== Established
)
5098 bgp_announce_route_all(member
);
5104 /* neighbor interface */
5105 void peer_interface_set(struct peer
*peer
, const char *str
)
5107 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5108 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
5111 void peer_interface_unset(struct peer
*peer
)
5113 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
5114 peer
->ifname
= NULL
;
5118 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5119 int allow_num
, int origin
)
5121 struct peer
*member
;
5122 struct listnode
*node
, *nnode
;
5124 if (!origin
&& (allow_num
< 1 || allow_num
> 10))
5125 return BGP_ERR_INVALID_VALUE
;
5127 /* Set flag and configuration on peer. */
5128 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5130 if (peer
->allowas_in
[afi
][safi
] != 0
5131 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5132 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5133 peer_af_flag_set(peer
, afi
, safi
,
5134 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5135 peer
->allowas_in
[afi
][safi
] = 0;
5136 peer_on_policy_change(peer
, afi
, safi
, 0);
5139 if (peer
->allowas_in
[afi
][safi
] != allow_num
5140 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5141 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5143 peer_af_flag_unset(peer
, afi
, safi
,
5144 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5145 peer
->allowas_in
[afi
][safi
] = allow_num
;
5146 peer_on_policy_change(peer
, afi
, safi
, 0);
5150 /* Skip peer-group mechanics for regular peers. */
5151 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5155 * Set flag and configuration on all peer-group members, unless
5156 * they are explicitely overriding peer-group configuration.
5158 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5159 /* Skip peers with overridden configuration. */
5160 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5161 PEER_FLAG_ALLOWAS_IN
))
5164 /* Set flag and configuration on peer-group member. */
5165 SET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5167 if (member
->allowas_in
[afi
][safi
] != 0
5168 || !CHECK_FLAG(member
->af_flags
[afi
][safi
],
5169 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5170 SET_FLAG(member
->af_flags
[afi
][safi
],
5171 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5172 member
->allowas_in
[afi
][safi
] = 0;
5173 peer_on_policy_change(peer
, afi
, safi
, 0);
5176 if (member
->allowas_in
[afi
][safi
] != allow_num
5177 || CHECK_FLAG(member
->af_flags
[afi
][safi
],
5178 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5179 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5180 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5181 member
->allowas_in
[afi
][safi
] = allow_num
;
5182 peer_on_policy_change(peer
, afi
, safi
, 0);
5190 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5192 struct peer
*member
;
5193 struct listnode
*node
, *nnode
;
5195 /* Skip peer if flag is already disabled. */
5196 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
))
5199 /* Inherit configuration from peer-group if peer is member. */
5200 if (peer_group_active(peer
)) {
5201 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5202 peer_af_flag_inherit(peer
, afi
, safi
,
5203 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5204 PEER_ATTR_INHERIT(peer
, peer
->group
, allowas_in
[afi
][safi
]);
5205 peer_on_policy_change(peer
, afi
, safi
, 0);
5210 /* Remove flag and configuration from peer. */
5211 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5212 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5213 peer
->allowas_in
[afi
][safi
] = 0;
5214 peer_on_policy_change(peer
, afi
, safi
, 0);
5216 /* Skip peer-group mechanics if handling a regular peer. */
5217 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5221 * Remove flags and configuration from all peer-group members, unless
5222 * they are explicitely overriding peer-group configuration.
5224 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5225 /* Skip peers with overridden configuration. */
5226 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
5227 PEER_FLAG_ALLOWAS_IN
))
5230 /* Skip peers where flag is already disabled. */
5231 if (!CHECK_FLAG(member
->af_flags
[afi
][safi
],
5232 PEER_FLAG_ALLOWAS_IN
))
5235 /* Remove flags and configuration on peer-group member. */
5236 UNSET_FLAG(member
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
);
5237 UNSET_FLAG(member
->af_flags
[afi
][safi
],
5238 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5239 member
->allowas_in
[afi
][safi
] = 0;
5240 peer_on_policy_change(member
, afi
, safi
, 0);
5246 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5249 bool old_no_prepend
, old_replace_as
;
5250 struct bgp
*bgp
= peer
->bgp
;
5251 struct peer
*member
;
5252 struct listnode
*node
, *nnode
;
5254 if (peer_sort(peer
) != BGP_PEER_EBGP
5255 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5256 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5259 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5262 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5264 /* Save previous flag states. */
5266 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5268 !!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5270 /* Set flag and configuration on peer. */
5271 peer_flag_set(peer
, PEER_FLAG_LOCAL_AS
);
5272 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
, no_prepend
);
5273 peer_flag_modify(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
, replace_as
);
5275 if (peer
->change_local_as
== as
&& old_no_prepend
== no_prepend
5276 && old_replace_as
== replace_as
)
5278 peer
->change_local_as
= as
;
5280 /* Check if handling a regular peer. */
5281 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5282 /* Send notification or reset peer depending on state. */
5283 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5284 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5285 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5286 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5288 bgp_session_reset(peer
);
5290 /* Skip peer-group mechanics for regular peers. */
5295 * Set flag and configuration on all peer-group members, unless they are
5296 * explicitely overriding peer-group configuration.
5298 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5299 /* Skip peers with overridden configuration. */
5300 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5303 /* Skip peers with the same configuration. */
5304 old_no_prepend
= CHECK_FLAG(member
->flags
,
5305 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5306 old_replace_as
= CHECK_FLAG(member
->flags
,
5307 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5308 if (member
->change_local_as
== as
5309 && CHECK_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
)
5310 && old_no_prepend
== no_prepend
5311 && old_replace_as
== replace_as
)
5314 /* Set flag and configuration on peer-group member. */
5315 SET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5316 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
,
5318 COND_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
,
5320 member
->change_local_as
= as
;
5322 /* Send notification or stop peer depending on state. */
5323 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5324 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5325 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5326 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5328 BGP_EVENT_ADD(member
, BGP_Stop
);
5334 int peer_local_as_unset(struct peer
*peer
)
5336 struct peer
*member
;
5337 struct listnode
*node
, *nnode
;
5339 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS
))
5342 /* Inherit configuration from peer-group if peer is member. */
5343 if (peer_group_active(peer
)) {
5344 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS
);
5345 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5346 peer_flag_inherit(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5347 PEER_ATTR_INHERIT(peer
, peer
->group
, change_local_as
);
5349 /* Otherwise remove flag and configuration from peer. */
5350 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS
);
5351 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5352 peer_flag_unset(peer
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5353 peer
->change_local_as
= 0;
5356 /* Check if handling a regular peer. */
5357 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5358 /* Send notification or stop peer depending on state. */
5359 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5360 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5361 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5362 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5364 BGP_EVENT_ADD(peer
, BGP_Stop
);
5366 /* Skip peer-group mechanics for regular peers. */
5371 * Remove flag and configuration from all peer-group members, unless
5372 * they are explicitely overriding peer-group configuration.
5374 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5375 /* Skip peers with overridden configuration. */
5376 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_LOCAL_AS
))
5379 /* Remove flag and configuration on peer-group member. */
5380 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS
);
5381 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5382 UNSET_FLAG(member
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5383 member
->change_local_as
= 0;
5385 /* Send notification or stop peer depending on state. */
5386 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
)) {
5387 member
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5388 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5389 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5391 bgp_session_reset(member
);
5397 /* Set password for authenticating with the peer. */
5398 int peer_password_set(struct peer
*peer
, const char *password
)
5400 struct peer
*member
;
5401 struct listnode
*node
, *nnode
;
5402 int len
= password
? strlen(password
) : 0;
5403 int ret
= BGP_SUCCESS
;
5405 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5406 return BGP_ERR_INVALID_VALUE
;
5408 /* Set flag and configuration on peer. */
5409 peer_flag_set(peer
, PEER_FLAG_PASSWORD
);
5410 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5412 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5413 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5415 /* Check if handling a regular peer. */
5416 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5417 /* Send notification or reset peer depending on state. */
5418 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5419 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5420 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5422 bgp_session_reset(peer
);
5425 * Attempt to install password on socket and skip peer-group
5428 if (BGP_PEER_SU_UNSPEC(peer
))
5430 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5431 : BGP_ERR_TCPSIG_FAILED
;
5435 * Set flag and configuration on all peer-group members, unless they are
5436 * explicitely overriding peer-group configuration.
5438 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5439 /* Skip peers with overridden configuration. */
5440 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5443 /* Skip peers with the same password. */
5444 if (member
->password
&& strcmp(member
->password
, password
) == 0)
5447 /* Set flag and configuration on peer-group member. */
5448 SET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5449 if (member
->password
)
5450 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5451 member
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5453 /* Send notification or reset peer depending on state. */
5454 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5455 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5456 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5458 bgp_session_reset(member
);
5460 /* Attempt to install password on socket. */
5461 if (!BGP_PEER_SU_UNSPEC(member
) && bgp_md5_set(member
) < 0)
5462 ret
= BGP_ERR_TCPSIG_FAILED
;
5465 /* Set flag and configuration on all peer-group listen ranges */
5466 struct listnode
*ln
;
5469 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5470 bgp_md5_set_prefix(lr
, password
);
5471 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5472 bgp_md5_set_prefix(lr
, password
);
5477 int peer_password_unset(struct peer
*peer
)
5479 struct peer
*member
;
5480 struct listnode
*node
, *nnode
;
5482 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSWORD
))
5485 /* Inherit configuration from peer-group if peer is member. */
5486 if (peer_group_active(peer
)) {
5487 peer_flag_inherit(peer
, PEER_FLAG_PASSWORD
);
5488 PEER_STR_ATTR_INHERIT(peer
, peer
->group
, password
,
5489 MTYPE_PEER_PASSWORD
);
5491 /* Otherwise remove flag and configuration from peer. */
5492 peer_flag_unset(peer
, PEER_FLAG_PASSWORD
);
5493 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5496 /* Check if handling a regular peer. */
5497 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5498 /* Send notification or reset peer depending on state. */
5499 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5500 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5501 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5503 bgp_session_reset(peer
);
5505 /* Attempt to uninstall password on socket. */
5506 if (!BGP_PEER_SU_UNSPEC(peer
))
5507 bgp_md5_unset(peer
);
5509 /* Skip peer-group mechanics for regular peers. */
5514 * Remove flag and configuration from all peer-group members, unless
5515 * they are explicitely overriding peer-group configuration.
5517 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5518 /* Skip peers with overridden configuration. */
5519 if (CHECK_FLAG(member
->flags_override
, PEER_FLAG_PASSWORD
))
5522 /* Remove flag and configuration on peer-group member. */
5523 UNSET_FLAG(member
->flags
, PEER_FLAG_PASSWORD
);
5524 XFREE(MTYPE_PEER_PASSWORD
, member
->password
);
5526 /* Send notification or reset peer depending on state. */
5527 if (BGP_IS_VALID_STATE_FOR_NOTIF(member
->status
))
5528 bgp_notify_send(member
, BGP_NOTIFY_CEASE
,
5529 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5531 bgp_session_reset(member
);
5533 /* Attempt to uninstall password on socket. */
5534 if (!BGP_PEER_SU_UNSPEC(member
))
5535 bgp_md5_unset(member
);
5538 /* Set flag and configuration on all peer-group listen ranges */
5539 struct listnode
*ln
;
5542 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP
], ln
, lr
))
5543 bgp_md5_unset_prefix(lr
);
5544 for (ALL_LIST_ELEMENTS_RO(peer
->group
->listen_range
[AFI_IP6
], ln
, lr
))
5545 bgp_md5_unset_prefix(lr
);
5551 /* Set distribute list to the peer. */
5552 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5555 struct peer
*member
;
5556 struct bgp_filter
*filter
;
5557 struct listnode
*node
, *nnode
;
5559 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5560 return BGP_ERR_INVALID_VALUE
;
5562 /* Set configuration on peer. */
5563 filter
= &peer
->filter
[afi
][safi
];
5564 if (filter
->plist
[direct
].name
)
5565 return BGP_ERR_PEER_FILTER_CONFLICT
;
5566 if (filter
->dlist
[direct
].name
)
5567 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5568 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5569 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5571 /* Check if handling a regular peer. */
5572 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5573 /* Set override-flag and process peer route updates. */
5574 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5575 PEER_FT_DISTRIBUTE_LIST
);
5576 peer_on_policy_change(peer
, afi
, safi
,
5577 (direct
== FILTER_OUT
) ? 1 : 0);
5579 /* Skip peer-group mechanics for regular peers. */
5584 * Set configuration on all peer-group members, un less they are
5585 * explicitely overriding peer-group configuration.
5587 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5588 /* Skip peers with overridden configuration. */
5589 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5590 PEER_FT_DISTRIBUTE_LIST
))
5593 /* Set configuration on peer-group member. */
5594 filter
= &member
->filter
[afi
][safi
];
5595 if (filter
->dlist
[direct
].name
)
5596 XFREE(MTYPE_BGP_FILTER_NAME
,
5597 filter
->dlist
[direct
].name
);
5598 filter
->dlist
[direct
].name
=
5599 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5600 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5602 /* Process peer route updates. */
5603 peer_on_policy_change(member
, afi
, safi
,
5604 (direct
== FILTER_OUT
) ? 1 : 0);
5610 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5612 struct peer
*member
;
5613 struct bgp_filter
*filter
;
5614 struct listnode
*node
, *nnode
;
5616 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5617 return BGP_ERR_INVALID_VALUE
;
5619 /* Unset override-flag unconditionally. */
5620 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5621 PEER_FT_DISTRIBUTE_LIST
);
5623 /* Inherit configuration from peer-group if peer is member. */
5624 if (peer_group_active(peer
)) {
5625 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5626 filter
[afi
][safi
].dlist
[direct
].name
,
5627 MTYPE_BGP_FILTER_NAME
);
5628 PEER_ATTR_INHERIT(peer
, peer
->group
,
5629 filter
[afi
][safi
].dlist
[direct
].alist
);
5631 /* Otherwise remove configuration from peer. */
5632 filter
= &peer
->filter
[afi
][safi
];
5633 if (filter
->dlist
[direct
].name
)
5634 XFREE(MTYPE_BGP_FILTER_NAME
,
5635 filter
->dlist
[direct
].name
);
5636 filter
->dlist
[direct
].name
= NULL
;
5637 filter
->dlist
[direct
].alist
= NULL
;
5640 /* Check if handling a regular peer. */
5641 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5642 /* Process peer route updates. */
5643 peer_on_policy_change(peer
, afi
, safi
,
5644 (direct
== FILTER_OUT
) ? 1 : 0);
5646 /* Skip peer-group mechanics for regular peers. */
5651 * Remove configuration on all peer-group members, unless they are
5652 * explicitely overriding peer-group configuration.
5654 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5655 /* Skip peers with overridden configuration. */
5656 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5657 PEER_FT_DISTRIBUTE_LIST
))
5660 /* Remove configuration on peer-group member. */
5661 filter
= &member
->filter
[afi
][safi
];
5662 if (filter
->dlist
[direct
].name
)
5663 XFREE(MTYPE_BGP_FILTER_NAME
,
5664 filter
->dlist
[direct
].name
);
5665 filter
->dlist
[direct
].name
= NULL
;
5666 filter
->dlist
[direct
].alist
= NULL
;
5668 /* Process peer route updates. */
5669 peer_on_policy_change(member
, afi
, safi
,
5670 (direct
== FILTER_OUT
) ? 1 : 0);
5676 /* Update distribute list. */
5677 static void peer_distribute_update(struct access_list
*access
)
5682 struct listnode
*mnode
, *mnnode
;
5683 struct listnode
*node
, *nnode
;
5686 struct peer_group
*group
;
5687 struct bgp_filter
*filter
;
5689 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5691 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5692 access
->name
, 0, 0);
5693 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5694 FOREACH_AFI_SAFI (afi
, safi
) {
5695 filter
= &peer
->filter
[afi
][safi
];
5697 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5699 if (filter
->dlist
[direct
].name
)
5700 filter
->dlist
[direct
]
5701 .alist
= access_list_lookup(
5703 filter
->dlist
[direct
]
5706 filter
->dlist
[direct
].alist
=
5711 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5712 FOREACH_AFI_SAFI (afi
, safi
) {
5713 filter
= &group
->conf
->filter
[afi
][safi
];
5715 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5717 if (filter
->dlist
[direct
].name
)
5718 filter
->dlist
[direct
]
5719 .alist
= access_list_lookup(
5721 filter
->dlist
[direct
]
5724 filter
->dlist
[direct
].alist
=
5730 vnc_prefix_list_update(bgp
);
5735 /* Set prefix list to the peer. */
5736 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5739 struct peer
*member
;
5740 struct bgp_filter
*filter
;
5741 struct listnode
*node
, *nnode
;
5743 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5744 return BGP_ERR_INVALID_VALUE
;
5746 /* Set configuration on peer. */
5747 filter
= &peer
->filter
[afi
][safi
];
5748 if (filter
->dlist
[direct
].name
)
5749 return BGP_ERR_PEER_FILTER_CONFLICT
;
5750 if (filter
->plist
[direct
].name
)
5751 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5752 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5753 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5755 /* Check if handling a regular peer. */
5756 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5757 /* Set override-flag and process peer route updates. */
5758 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5759 PEER_FT_PREFIX_LIST
);
5760 peer_on_policy_change(peer
, afi
, safi
,
5761 (direct
== FILTER_OUT
) ? 1 : 0);
5763 /* Skip peer-group mechanics for regular peers. */
5768 * Set configuration on all peer-group members, unless they are
5769 * explicitely overriding peer-group configuration.
5771 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5772 /* Skip peers with overridden configuration. */
5773 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5774 PEER_FT_PREFIX_LIST
))
5777 /* Set configuration on peer-group member. */
5778 filter
= &member
->filter
[afi
][safi
];
5779 if (filter
->plist
[direct
].name
)
5780 XFREE(MTYPE_BGP_FILTER_NAME
,
5781 filter
->plist
[direct
].name
);
5782 filter
->plist
[direct
].name
=
5783 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5784 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5786 /* Process peer route updates. */
5787 peer_on_policy_change(member
, afi
, safi
,
5788 (direct
== FILTER_OUT
) ? 1 : 0);
5794 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5797 struct peer
*member
;
5798 struct bgp_filter
*filter
;
5799 struct listnode
*node
, *nnode
;
5801 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5802 return BGP_ERR_INVALID_VALUE
;
5804 /* Unset override-flag unconditionally. */
5805 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5806 PEER_FT_PREFIX_LIST
);
5808 /* Inherit configuration from peer-group if peer is member. */
5809 if (peer_group_active(peer
)) {
5810 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5811 filter
[afi
][safi
].plist
[direct
].name
,
5812 MTYPE_BGP_FILTER_NAME
);
5813 PEER_ATTR_INHERIT(peer
, peer
->group
,
5814 filter
[afi
][safi
].plist
[direct
].plist
);
5816 /* Otherwise remove configuration from peer. */
5817 filter
= &peer
->filter
[afi
][safi
];
5818 if (filter
->plist
[direct
].name
)
5819 XFREE(MTYPE_BGP_FILTER_NAME
,
5820 filter
->plist
[direct
].name
);
5821 filter
->plist
[direct
].name
= NULL
;
5822 filter
->plist
[direct
].plist
= NULL
;
5825 /* Check if handling a regular peer. */
5826 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5827 /* Process peer route updates. */
5828 peer_on_policy_change(peer
, afi
, safi
,
5829 (direct
== FILTER_OUT
) ? 1 : 0);
5831 /* Skip peer-group mechanics for regular peers. */
5836 * Remove configuration on all peer-group members, unless they are
5837 * explicitely overriding peer-group configuration.
5839 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5840 /* Skip peers with overridden configuration. */
5841 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5842 PEER_FT_PREFIX_LIST
))
5845 /* Remove configuration on peer-group member. */
5846 filter
= &member
->filter
[afi
][safi
];
5847 if (filter
->plist
[direct
].name
)
5848 XFREE(MTYPE_BGP_FILTER_NAME
,
5849 filter
->plist
[direct
].name
);
5850 filter
->plist
[direct
].name
= NULL
;
5851 filter
->plist
[direct
].plist
= NULL
;
5853 /* Process peer route updates. */
5854 peer_on_policy_change(member
, afi
, safi
,
5855 (direct
== FILTER_OUT
) ? 1 : 0);
5861 /* Update prefix-list list. */
5862 static void peer_prefix_list_update(struct prefix_list
*plist
)
5864 struct listnode
*mnode
, *mnnode
;
5865 struct listnode
*node
, *nnode
;
5868 struct peer_group
*group
;
5869 struct bgp_filter
*filter
;
5874 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5877 * Update the prefix-list on update groups.
5879 update_group_policy_update(
5880 bgp
, BGP_POLICY_PREFIX_LIST
,
5881 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5883 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5884 FOREACH_AFI_SAFI (afi
, safi
) {
5885 filter
= &peer
->filter
[afi
][safi
];
5887 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5889 if (filter
->plist
[direct
].name
)
5890 filter
->plist
[direct
]
5891 .plist
= prefix_list_lookup(
5893 filter
->plist
[direct
]
5896 filter
->plist
[direct
].plist
=
5901 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5902 FOREACH_AFI_SAFI (afi
, safi
) {
5903 filter
= &group
->conf
->filter
[afi
][safi
];
5905 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5907 if (filter
->plist
[direct
].name
)
5908 filter
->plist
[direct
]
5909 .plist
= prefix_list_lookup(
5911 filter
->plist
[direct
]
5914 filter
->plist
[direct
].plist
=
5922 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5925 struct peer
*member
;
5926 struct bgp_filter
*filter
;
5927 struct listnode
*node
, *nnode
;
5929 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5930 return BGP_ERR_INVALID_VALUE
;
5932 /* Set configuration on peer. */
5933 filter
= &peer
->filter
[afi
][safi
];
5934 if (filter
->aslist
[direct
].name
)
5935 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5936 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5937 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5939 /* Check if handling a regular peer. */
5940 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5941 /* Set override-flag and process peer route updates. */
5942 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5943 PEER_FT_FILTER_LIST
);
5944 peer_on_policy_change(peer
, afi
, safi
,
5945 (direct
== FILTER_OUT
) ? 1 : 0);
5947 /* Skip peer-group mechanics for regular peers. */
5952 * Set configuration on all peer-group members, unless they are
5953 * explicitely overriding peer-group configuration.
5955 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
5956 /* Skip peers with overridden configuration. */
5957 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
5958 PEER_FT_FILTER_LIST
))
5961 /* Set configuration on peer-group member. */
5962 filter
= &member
->filter
[afi
][safi
];
5963 if (filter
->aslist
[direct
].name
)
5964 XFREE(MTYPE_BGP_FILTER_NAME
,
5965 filter
->aslist
[direct
].name
);
5966 filter
->aslist
[direct
].name
=
5967 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5968 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5970 /* Process peer route updates. */
5971 peer_on_policy_change(member
, afi
, safi
,
5972 (direct
== FILTER_OUT
) ? 1 : 0);
5978 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5980 struct peer
*member
;
5981 struct bgp_filter
*filter
;
5982 struct listnode
*node
, *nnode
;
5984 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5985 return BGP_ERR_INVALID_VALUE
;
5987 /* Unset override-flag unconditionally. */
5988 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
5989 PEER_FT_FILTER_LIST
);
5991 /* Inherit configuration from peer-group if peer is member. */
5992 if (peer_group_active(peer
)) {
5993 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
5994 filter
[afi
][safi
].aslist
[direct
].name
,
5995 MTYPE_BGP_FILTER_NAME
);
5996 PEER_ATTR_INHERIT(peer
, peer
->group
,
5997 filter
[afi
][safi
].aslist
[direct
].aslist
);
5999 /* Otherwise remove configuration from peer. */
6000 filter
= &peer
->filter
[afi
][safi
];
6001 if (filter
->aslist
[direct
].name
)
6002 XFREE(MTYPE_BGP_FILTER_NAME
,
6003 filter
->aslist
[direct
].name
);
6004 filter
->aslist
[direct
].name
= NULL
;
6005 filter
->aslist
[direct
].aslist
= NULL
;
6008 /* Check if handling a regular peer. */
6009 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6010 /* Process peer route updates. */
6011 peer_on_policy_change(peer
, afi
, safi
,
6012 (direct
== FILTER_OUT
) ? 1 : 0);
6014 /* Skip peer-group mechanics for regular peers. */
6019 * Remove configuration on all peer-group members, unless they are
6020 * explicitely overriding peer-group configuration.
6022 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6023 /* Skip peers with overridden configuration. */
6024 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6025 PEER_FT_FILTER_LIST
))
6028 /* Remove configuration on peer-group member. */
6029 filter
= &member
->filter
[afi
][safi
];
6030 if (filter
->aslist
[direct
].name
)
6031 XFREE(MTYPE_BGP_FILTER_NAME
,
6032 filter
->aslist
[direct
].name
);
6033 filter
->aslist
[direct
].name
= NULL
;
6034 filter
->aslist
[direct
].aslist
= NULL
;
6036 /* Process peer route updates. */
6037 peer_on_policy_change(member
, afi
, safi
,
6038 (direct
== FILTER_OUT
) ? 1 : 0);
6044 static void peer_aslist_update(const char *aslist_name
)
6049 struct listnode
*mnode
, *mnnode
;
6050 struct listnode
*node
, *nnode
;
6053 struct peer_group
*group
;
6054 struct bgp_filter
*filter
;
6056 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
6057 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
6060 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
6061 FOREACH_AFI_SAFI (afi
, safi
) {
6062 filter
= &peer
->filter
[afi
][safi
];
6064 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6066 if (filter
->aslist
[direct
].name
)
6067 filter
->aslist
[direct
]
6068 .aslist
= as_list_lookup(
6069 filter
->aslist
[direct
]
6072 filter
->aslist
[direct
].aslist
=
6077 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
6078 FOREACH_AFI_SAFI (afi
, safi
) {
6079 filter
= &group
->conf
->filter
[afi
][safi
];
6081 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
6083 if (filter
->aslist
[direct
].name
)
6084 filter
->aslist
[direct
]
6085 .aslist
= as_list_lookup(
6086 filter
->aslist
[direct
]
6089 filter
->aslist
[direct
].aslist
=
6097 static void peer_aslist_add(char *aslist_name
)
6099 peer_aslist_update(aslist_name
);
6100 route_map_notify_dependencies((char *)aslist_name
,
6101 RMAP_EVENT_ASLIST_ADDED
);
6104 static void peer_aslist_del(const char *aslist_name
)
6106 peer_aslist_update(aslist_name
);
6107 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
6111 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
6112 const char *name
, struct route_map
*route_map
)
6114 struct peer
*member
;
6115 struct bgp_filter
*filter
;
6116 struct listnode
*node
, *nnode
;
6118 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6119 return BGP_ERR_INVALID_VALUE
;
6121 /* Set configuration on peer. */
6122 filter
= &peer
->filter
[afi
][safi
];
6123 if (filter
->map
[direct
].name
) {
6124 /* If the neighbor is configured with the same route-map
6125 * again then, ignore the duplicate configuration.
6127 if (strcmp(filter
->map
[direct
].name
, name
) == 0)
6130 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6132 route_map_counter_decrement(filter
->map
[direct
].map
);
6133 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6134 filter
->map
[direct
].map
= route_map
;
6135 route_map_counter_increment(route_map
);
6137 /* Check if handling a regular peer. */
6138 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6139 /* Set override-flag and process peer route updates. */
6140 SET_FLAG(peer
->filter_override
[afi
][safi
][direct
],
6142 peer_on_policy_change(peer
, afi
, safi
,
6143 (direct
== RMAP_OUT
) ? 1 : 0);
6145 /* Skip peer-group mechanics for regular peers. */
6150 * Set configuration on all peer-group members, unless they are
6151 * explicitely overriding peer-group configuration.
6153 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6154 /* Skip peers with overridden configuration. */
6155 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6159 /* Set configuration on peer-group member. */
6160 filter
= &member
->filter
[afi
][safi
];
6161 if (filter
->map
[direct
].name
)
6162 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6163 route_map_counter_decrement(filter
->map
[direct
].map
);
6164 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6165 filter
->map
[direct
].map
= route_map
;
6166 route_map_counter_increment(route_map
);
6168 /* Process peer route updates. */
6169 peer_on_policy_change(member
, afi
, safi
,
6170 (direct
== RMAP_OUT
) ? 1 : 0);
6175 /* Unset route-map from the peer. */
6176 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
6178 struct peer
*member
;
6179 struct bgp_filter
*filter
;
6180 struct listnode
*node
, *nnode
;
6182 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
6183 return BGP_ERR_INVALID_VALUE
;
6185 /* Unset override-flag unconditionally. */
6186 UNSET_FLAG(peer
->filter_override
[afi
][safi
][direct
], PEER_FT_ROUTE_MAP
);
6188 /* Inherit configuration from peer-group if peer is member. */
6189 if (peer_group_active(peer
)) {
6190 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6191 filter
[afi
][safi
].map
[direct
].name
,
6192 MTYPE_BGP_FILTER_NAME
);
6193 PEER_ATTR_INHERIT(peer
, peer
->group
,
6194 filter
[afi
][safi
].map
[direct
].map
);
6196 /* Otherwise remove configuration from peer. */
6197 filter
= &peer
->filter
[afi
][safi
];
6198 if (filter
->map
[direct
].name
)
6199 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6200 route_map_counter_decrement(filter
->map
[direct
].map
);
6201 filter
->map
[direct
].name
= NULL
;
6202 filter
->map
[direct
].map
= NULL
;
6205 /* Check if handling a regular peer. */
6206 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6207 /* Process peer route updates. */
6208 peer_on_policy_change(peer
, afi
, safi
,
6209 (direct
== RMAP_OUT
) ? 1 : 0);
6211 /* Skip peer-group mechanics for regular peers. */
6216 * Remove configuration on all peer-group members, unless they are
6217 * explicitely overriding peer-group configuration.
6219 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6220 /* Skip peers with overridden configuration. */
6221 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][direct
],
6225 /* Remove configuration on peer-group member. */
6226 filter
= &member
->filter
[afi
][safi
];
6227 if (filter
->map
[direct
].name
)
6228 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
6229 route_map_counter_decrement(filter
->map
[direct
].map
);
6230 filter
->map
[direct
].name
= NULL
;
6231 filter
->map
[direct
].map
= NULL
;
6233 /* Process peer route updates. */
6234 peer_on_policy_change(member
, afi
, safi
,
6235 (direct
== RMAP_OUT
) ? 1 : 0);
6241 /* Set unsuppress-map to the peer. */
6242 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6243 const char *name
, struct route_map
*route_map
)
6245 struct peer
*member
;
6246 struct bgp_filter
*filter
;
6247 struct listnode
*node
, *nnode
;
6249 /* Set configuration on peer. */
6250 filter
= &peer
->filter
[afi
][safi
];
6251 if (filter
->usmap
.name
)
6252 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6253 route_map_counter_decrement(filter
->usmap
.map
);
6254 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6255 filter
->usmap
.map
= route_map
;
6256 route_map_counter_increment(route_map
);
6258 /* Check if handling a regular peer. */
6259 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6260 /* Set override-flag and process peer route updates. */
6261 SET_FLAG(peer
->filter_override
[afi
][safi
][0],
6262 PEER_FT_UNSUPPRESS_MAP
);
6263 peer_on_policy_change(peer
, afi
, safi
, 1);
6265 /* Skip peer-group mechanics for regular peers. */
6270 * Set configuration on all peer-group members, unless they are
6271 * explicitely overriding peer-group configuration.
6273 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6274 /* Skip peers with overridden configuration. */
6275 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6276 PEER_FT_UNSUPPRESS_MAP
))
6279 /* Set configuration on peer-group member. */
6280 filter
= &member
->filter
[afi
][safi
];
6281 if (filter
->usmap
.name
)
6282 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6283 route_map_counter_decrement(filter
->usmap
.map
);
6284 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
6285 filter
->usmap
.map
= route_map
;
6286 route_map_counter_increment(route_map
);
6288 /* Process peer route updates. */
6289 peer_on_policy_change(member
, afi
, safi
, 1);
6295 /* Unset route-map from the peer. */
6296 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6298 struct peer
*member
;
6299 struct bgp_filter
*filter
;
6300 struct listnode
*node
, *nnode
;
6302 /* Unset override-flag unconditionally. */
6303 UNSET_FLAG(peer
->filter_override
[afi
][safi
][0], PEER_FT_UNSUPPRESS_MAP
);
6305 /* Inherit configuration from peer-group if peer is member. */
6306 if (peer_group_active(peer
)) {
6307 PEER_STR_ATTR_INHERIT(peer
, peer
->group
,
6308 filter
[afi
][safi
].usmap
.name
,
6309 MTYPE_BGP_FILTER_NAME
);
6310 PEER_ATTR_INHERIT(peer
, peer
->group
,
6311 filter
[afi
][safi
].usmap
.map
);
6313 /* Otherwise remove configuration from peer. */
6314 filter
= &peer
->filter
[afi
][safi
];
6315 if (filter
->usmap
.name
)
6316 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6317 route_map_counter_decrement(filter
->usmap
.map
);
6318 filter
->usmap
.name
= NULL
;
6319 filter
->usmap
.map
= NULL
;
6322 /* Check if handling a regular peer. */
6323 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6324 /* Process peer route updates. */
6325 peer_on_policy_change(peer
, afi
, safi
, 1);
6327 /* Skip peer-group mechanics for regular peers. */
6332 * Remove configuration on all peer-group members, unless they are
6333 * explicitely overriding peer-group configuration.
6335 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6336 /* Skip peers with overridden configuration. */
6337 if (CHECK_FLAG(member
->filter_override
[afi
][safi
][0],
6338 PEER_FT_UNSUPPRESS_MAP
))
6341 /* Remove configuration on peer-group member. */
6342 filter
= &member
->filter
[afi
][safi
];
6343 if (filter
->usmap
.name
)
6344 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
6345 route_map_counter_decrement(filter
->usmap
.map
);
6346 filter
->usmap
.name
= NULL
;
6347 filter
->usmap
.map
= NULL
;
6349 /* Process peer route updates. */
6350 peer_on_policy_change(member
, afi
, safi
, 1);
6356 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
6357 uint32_t max
, uint8_t threshold
, int warning
,
6360 struct peer
*member
;
6361 struct listnode
*node
, *nnode
;
6363 /* Set flags and configuration on peer. */
6364 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6366 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6368 peer_af_flag_unset(peer
, afi
, safi
,
6369 PEER_FLAG_MAX_PREFIX_WARNING
);
6371 peer
->pmax
[afi
][safi
] = max
;
6372 peer
->pmax_threshold
[afi
][safi
] = threshold
;
6373 peer
->pmax_restart
[afi
][safi
] = restart
;
6375 /* Check if handling a regular peer. */
6376 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6377 /* Re-check if peer violates maximum-prefix. */
6378 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
6379 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
6381 /* Skip peer-group mechanics for regular peers. */
6386 * Set flags and configuration on all peer-group members, unless they
6387 * are explicitely overriding peer-group configuration.
6389 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, node
, nnode
, member
)) {
6390 /* Skip peers with overridden configuration. */
6391 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6392 PEER_FLAG_MAX_PREFIX
))
6395 /* Set flag and configuration on peer-group member. */
6396 member
->pmax
[afi
][safi
] = max
;
6397 member
->pmax_threshold
[afi
][safi
] = threshold
;
6398 member
->pmax_restart
[afi
][safi
] = restart
;
6400 SET_FLAG(member
->af_flags
[afi
][safi
],
6401 PEER_FLAG_MAX_PREFIX_WARNING
);
6403 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6404 PEER_FLAG_MAX_PREFIX_WARNING
);
6406 /* Re-check if peer violates maximum-prefix. */
6407 if ((member
->status
== Established
) && (member
->afc
[afi
][safi
]))
6408 bgp_maximum_prefix_overflow(member
, afi
, safi
, 1);
6414 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
6416 /* Inherit configuration from peer-group if peer is member. */
6417 if (peer_group_active(peer
)) {
6418 peer_af_flag_inherit(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6419 peer_af_flag_inherit(peer
, afi
, safi
,
6420 PEER_FLAG_MAX_PREFIX_WARNING
);
6421 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax
[afi
][safi
]);
6422 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_threshold
[afi
][safi
]);
6423 PEER_ATTR_INHERIT(peer
, peer
->group
, pmax_restart
[afi
][safi
]);
6428 /* Remove flags and configuration from peer. */
6429 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX
);
6430 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_MAX_PREFIX_WARNING
);
6431 peer
->pmax
[afi
][safi
] = 0;
6432 peer
->pmax_threshold
[afi
][safi
] = 0;
6433 peer
->pmax_restart
[afi
][safi
] = 0;
6436 * Remove flags and configuration from all peer-group members, unless
6437 * they are explicitely overriding peer-group configuration.
6439 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6440 struct peer
*member
;
6441 struct listnode
*node
;
6443 for (ALL_LIST_ELEMENTS_RO(peer
->group
->peer
, node
, member
)) {
6444 /* Skip peers with overridden configuration. */
6445 if (CHECK_FLAG(member
->af_flags_override
[afi
][safi
],
6446 PEER_FLAG_MAX_PREFIX
))
6449 /* Remove flag and configuration on peer-group member.
6451 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6452 PEER_FLAG_MAX_PREFIX
);
6453 UNSET_FLAG(member
->af_flags
[afi
][safi
],
6454 PEER_FLAG_MAX_PREFIX_WARNING
);
6455 member
->pmax
[afi
][safi
] = 0;
6456 member
->pmax_threshold
[afi
][safi
] = 0;
6457 member
->pmax_restart
[afi
][safi
] = 0;
6464 int is_ebgp_multihop_configured(struct peer
*peer
)
6466 struct peer_group
*group
;
6467 struct listnode
*node
, *nnode
;
6470 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6471 group
= peer
->group
;
6472 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6473 && (group
->conf
->ttl
!= BGP_DEFAULT_TTL
))
6476 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6477 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6478 && (peer1
->ttl
!= BGP_DEFAULT_TTL
))
6482 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6483 && (peer
->ttl
!= BGP_DEFAULT_TTL
))
6489 /* Set # of hops between us and BGP peer. */
6490 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6492 struct peer_group
*group
;
6493 struct listnode
*node
, *nnode
;
6496 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6497 gtsm_hops
, peer
->host
);
6499 /* We cannot configure ttl-security hops when ebgp-multihop is already
6500 set. For non peer-groups, the check is simple. For peer-groups,
6502 slightly messy, because we need to check both the peer-group
6504 and all peer-group members for any trace of ebgp-multihop
6506 before actually applying the ttl-security rules. Cisco really made a
6507 mess of this configuration parameter, and OpenBGPD got it right.
6510 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6511 if (is_ebgp_multihop_configured(peer
))
6512 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6514 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6515 peer
->gtsm_hops
= gtsm_hops
;
6517 /* Calling ebgp multihop also resets the session.
6518 * On restart, NHT will get setup correctly as will the
6519 * min & max ttls on the socket. The return value is
6522 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6527 group
= peer
->group
;
6528 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6530 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6532 /* Calling ebgp multihop also resets the
6534 * On restart, NHT will get setup correctly as
6536 * min & max ttls on the socket. The return
6540 peer_ebgp_multihop_set(peer
, MAXTTL
);
6544 /* Post the first gtsm setup or if its ibgp, maxttl setting
6546 * necessary, just set the minttl.
6548 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6549 peer
->gtsm_hops
= gtsm_hops
;
6552 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6553 MAXTTL
+ 1 - gtsm_hops
);
6554 if ((peer
->status
< Established
) && peer
->doppelganger
6555 && (peer
->doppelganger
->fd
>= 0))
6556 sockopt_minttl(peer
->su
.sa
.sa_family
,
6557 peer
->doppelganger
->fd
,
6558 MAXTTL
+ 1 - gtsm_hops
);
6560 group
= peer
->group
;
6561 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6563 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6565 /* Change setting of existing peer
6566 * established then change value (may break
6568 * not established yet (teardown session and
6570 * no session then do nothing (will get
6571 * handled by next connection)
6573 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6575 peer
->su
.sa
.sa_family
, peer
->fd
,
6576 MAXTTL
+ 1 - peer
->gtsm_hops
);
6577 if ((peer
->status
< Established
)
6578 && peer
->doppelganger
6579 && (peer
->doppelganger
->fd
>= 0))
6580 sockopt_minttl(peer
->su
.sa
.sa_family
,
6581 peer
->doppelganger
->fd
,
6582 MAXTTL
+ 1 - gtsm_hops
);
6590 int peer_ttl_security_hops_unset(struct peer
*peer
)
6592 struct peer_group
*group
;
6593 struct listnode
*node
, *nnode
;
6596 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6599 /* if a peer-group member, then reset to peer-group default rather than
6601 if (peer_group_active(peer
))
6602 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6604 peer
->gtsm_hops
= 0;
6606 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6607 /* Invoking ebgp_multihop_set will set the TTL back to the
6609 * value as well as restting the NHT and such. The session is
6612 if (peer
->sort
== BGP_PEER_EBGP
)
6613 ret
= peer_ebgp_multihop_unset(peer
);
6616 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6619 if ((peer
->status
< Established
) && peer
->doppelganger
6620 && (peer
->doppelganger
->fd
>= 0))
6621 sockopt_minttl(peer
->su
.sa
.sa_family
,
6622 peer
->doppelganger
->fd
, 0);
6625 group
= peer
->group
;
6626 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6627 peer
->gtsm_hops
= 0;
6628 if (peer
->sort
== BGP_PEER_EBGP
)
6629 ret
= peer_ebgp_multihop_unset(peer
);
6632 sockopt_minttl(peer
->su
.sa
.sa_family
,
6635 if ((peer
->status
< Established
)
6636 && peer
->doppelganger
6637 && (peer
->doppelganger
->fd
>= 0))
6638 sockopt_minttl(peer
->su
.sa
.sa_family
,
6639 peer
->doppelganger
->fd
,
6649 * If peer clear is invoked in a loop for all peers on the BGP instance,
6650 * it may end up freeing the doppelganger, and if this was the next node
6651 * to the current node, we would end up accessing the freed next node.
6652 * Pass along additional parameter which can be updated if next node
6653 * is freed; only required when walking the peer list on BGP instance.
6655 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6657 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6658 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6659 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6660 if (peer
->t_pmax_restart
) {
6661 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6662 if (bgp_debug_neighbor_events(peer
))
6664 "%s Maximum-prefix restart timer canceled",
6667 BGP_EVENT_ADD(peer
, BGP_Start
);
6671 peer
->v_start
= BGP_INIT_START_TIMER
;
6672 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6673 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6674 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6676 bgp_session_reset_safe(peer
, nnode
);
6681 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6682 enum bgp_clear_type stype
)
6684 struct peer_af
*paf
;
6686 if (peer
->status
!= Established
)
6689 if (!peer
->afc
[afi
][safi
])
6690 return BGP_ERR_AF_UNCONFIGURED
;
6692 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6694 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6695 /* Clear the "neighbor x.x.x.x default-originate" flag */
6696 paf
= peer_af_find(peer
, afi
, safi
);
6697 if (paf
&& paf
->subgroup
6698 && CHECK_FLAG(paf
->subgroup
->sflags
,
6699 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6700 UNSET_FLAG(paf
->subgroup
->sflags
,
6701 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6703 bgp_announce_route(peer
, afi
, safi
);
6706 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6707 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6708 PEER_CAP_ORF_PREFIX_SM_ADV
)
6709 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6710 PEER_CAP_ORF_PREFIX_RM_RCV
)
6711 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6712 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6713 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6714 uint8_t prefix_type
;
6716 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6717 PEER_CAP_ORF_PREFIX_RM_RCV
))
6718 prefix_type
= ORF_TYPE_PREFIX
;
6720 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6722 if (filter
->plist
[FILTER_IN
].plist
) {
6723 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6724 PEER_STATUS_ORF_PREFIX_SEND
))
6725 bgp_route_refresh_send(
6726 peer
, afi
, safi
, prefix_type
,
6728 bgp_route_refresh_send(peer
, afi
, safi
,
6730 REFRESH_IMMEDIATE
, 0);
6732 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6733 PEER_STATUS_ORF_PREFIX_SEND
))
6734 bgp_route_refresh_send(
6735 peer
, afi
, safi
, prefix_type
,
6736 REFRESH_IMMEDIATE
, 1);
6738 bgp_route_refresh_send(peer
, afi
, safi
,
6745 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6746 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6747 /* If neighbor has soft reconfiguration inbound flag.
6748 Use Adj-RIB-In database. */
6749 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6750 PEER_FLAG_SOFT_RECONFIG
))
6751 bgp_soft_reconfig_in(peer
, afi
, safi
);
6753 /* If neighbor has route refresh capability, send route
6755 message to the peer. */
6756 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6757 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6758 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6761 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6767 /* Display peer uptime.*/
6768 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, bool use_json
,
6771 time_t uptime1
, epoch_tbuf
;
6774 /* If there is no connection has been done before print `never'. */
6777 json_object_string_add(json
, "peerUptime", "never");
6778 json_object_int_add(json
, "peerUptimeMsec", 0);
6780 snprintf(buf
, len
, "never");
6784 /* Get current time. */
6785 uptime1
= bgp_clock();
6787 tm
= gmtime(&uptime1
);
6789 if (uptime1
< ONE_DAY_SECOND
)
6790 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6792 else if (uptime1
< ONE_WEEK_SECOND
)
6793 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6795 else if (uptime1
< ONE_YEAR_SECOND
)
6796 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6797 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6799 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6801 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6804 epoch_tbuf
= time(NULL
) - uptime1
;
6805 json_object_string_add(json
, "peerUptime", buf
);
6806 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6807 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6814 void bgp_master_init(struct thread_master
*master
, const int buffer_size
)
6818 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
6821 bm
->bgp
= list_new();
6822 bm
->listen_sockets
= list_new();
6823 bm
->port
= BGP_PORT_DEFAULT
;
6824 bm
->master
= master
;
6825 bm
->start_time
= bgp_clock();
6826 bm
->t_rmap_update
= NULL
;
6827 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
6828 bm
->terminating
= false;
6829 bm
->socket_buffer
= buffer_size
;
6831 bgp_process_queue_init();
6834 /* init the rd id space.
6835 assign 0th index in the bitfield,
6836 so that we start with id 1
6838 bf_init(bm
->rd_idspace
, UINT16_MAX
);
6839 bf_assign_zero_index(bm
->rd_idspace
);
6841 /* mpls label dynamic allocation pool */
6842 bgp_lp_init(bm
->master
, &bm
->labelpool
);
6844 QOBJ_REG(bm
, bgp_master
);
6848 * Free up connected routes and interfaces for a BGP instance. Invoked upon
6849 * instance delete (non-default only) or BGP exit.
6851 static void bgp_if_finish(struct bgp
*bgp
)
6854 struct interface
*ifp
;
6856 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
6858 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
6861 FOR_ALL_INTERFACES (vrf
, ifp
) {
6862 struct listnode
*c_node
, *c_nnode
;
6863 struct connected
*c
;
6865 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
6866 bgp_connected_delete(bgp
, c
);
6870 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
6872 struct vrf
*vrf
= NULL
;
6873 struct listnode
*next
;
6876 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
)
6877 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
6879 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6880 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
6883 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
6887 static void bgp_instasn_autocomplete(vector comps
, struct cmd_token
*token
)
6889 struct listnode
*next
, *next2
;
6890 struct bgp
*bgp
, *bgp2
;
6893 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
6895 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next2
, bgp2
)) {
6896 if (bgp2
->as
== bgp
->as
)
6904 snprintf(buf
, sizeof(buf
), "%u", bgp
->as
);
6905 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, buf
));
6909 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
6910 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
6911 {.varname
= "instasn", .completions
= bgp_instasn_autocomplete
},
6912 {.completions
= NULL
},
6915 struct frr_pthread
*bgp_pth_io
;
6916 struct frr_pthread
*bgp_pth_ka
;
6918 static void bgp_pthreads_init(void)
6920 assert(!bgp_pth_io
);
6921 assert(!bgp_pth_ka
);
6923 struct frr_pthread_attr io
= {
6924 .start
= frr_pthread_attr_default
.start
,
6925 .stop
= frr_pthread_attr_default
.stop
,
6927 struct frr_pthread_attr ka
= {
6928 .start
= bgp_keepalives_start
,
6929 .stop
= bgp_keepalives_stop
,
6931 bgp_pth_io
= frr_pthread_new(&io
, "BGP I/O thread", "bgpd_io");
6932 bgp_pth_ka
= frr_pthread_new(&ka
, "BGP Keepalives thread", "bgpd_ka");
6935 void bgp_pthreads_run(void)
6937 frr_pthread_run(bgp_pth_io
, NULL
);
6938 frr_pthread_run(bgp_pth_ka
, NULL
);
6940 /* Wait until threads are ready. */
6941 frr_pthread_wait_running(bgp_pth_io
);
6942 frr_pthread_wait_running(bgp_pth_ka
);
6945 void bgp_pthreads_finish(void)
6947 frr_pthread_stop_all();
6950 void bgp_init(unsigned short instance
)
6953 /* allocates some vital data structures used by peer commands in
6956 /* pre-init pthreads */
6957 bgp_pthreads_init();
6960 bgp_zebra_init(bm
->master
, instance
);
6963 vnc_zebra_init(bm
->master
);
6966 /* BGP VTY commands installation. */
6974 bgp_route_map_init();
6975 bgp_scan_vty_init();
6980 bgp_ethernetvpn_init();
6981 bgp_flowspec_vty_init();
6983 /* Access list initialize. */
6985 access_list_add_hook(peer_distribute_update
);
6986 access_list_delete_hook(peer_distribute_update
);
6988 /* Filter list initialize. */
6990 as_list_add_hook(peer_aslist_add
);
6991 as_list_delete_hook(peer_aslist_del
);
6993 /* Prefix list initialize.*/
6995 prefix_list_add_hook(peer_prefix_list_update
);
6996 prefix_list_delete_hook(peer_prefix_list_update
);
6998 /* Community list initialize. */
6999 bgp_clist
= community_list_init();
7004 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7007 void bgp_terminate(void)
7011 struct listnode
*node
, *nnode
;
7012 struct listnode
*mnode
, *mnnode
;
7016 /* Close the listener sockets first as this prevents peers from
7018 * to reconnect on receiving the peer unconfig message. In the presence
7019 * of a large number of peers this will ensure that no peer is left with
7020 * a dangling connection
7022 /* reverse bgp_master_init */
7025 if (bm
->listen_sockets
)
7026 list_delete(&bm
->listen_sockets
);
7028 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7029 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7030 if (peer
->status
== Established
7031 || peer
->status
== OpenSent
7032 || peer
->status
== OpenConfirm
)
7033 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7034 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7036 if (bm
->process_main_queue
)
7037 work_queue_free_and_null(&bm
->process_main_queue
);
7039 if (bm
->t_rmap_update
)
7040 BGP_TIMER_OFF(bm
->t_rmap_update
);
7045 struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
7046 const char *ip_str
, bool use_json
)
7052 /* Get peer sockunion. */
7053 ret
= str2sockunion(ip_str
, &su
);
7055 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
7057 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
7061 json_object
*json_no
= NULL
;
7062 json_no
= json_object_new_object();
7063 json_object_string_add(
7065 "malformedAddressOrName",
7067 vty_out(vty
, "%s\n",
7068 json_object_to_json_string_ext(
7070 JSON_C_TO_STRING_PRETTY
));
7071 json_object_free(json_no
);
7074 "%% Malformed address or name: %s\n",
7082 /* Peer structure lookup. */
7083 peer
= peer_lookup(bgp
, &su
);
7086 json_object
*json_no
= NULL
;
7087 json_no
= json_object_new_object();
7088 json_object_string_add(json_no
, "warning",
7089 "No such neighbor in this view/vrf");
7090 vty_out(vty
, "%s\n",
7091 json_object_to_json_string_ext(
7092 json_no
, JSON_C_TO_STRING_PRETTY
));
7093 json_object_free(json_no
);
7095 vty_out(vty
, "No such neighbor in this view/vrf\n");