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"
48 #include "bgpd/bgpd.h"
49 #include "bgpd/bgp_table.h"
50 #include "bgpd/bgp_aspath.h"
51 #include "bgpd/bgp_route.h"
52 #include "bgpd/bgp_dump.h"
53 #include "bgpd/bgp_debug.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_attr.h"
56 #include "bgpd/bgp_regex.h"
57 #include "bgpd/bgp_clist.h"
58 #include "bgpd/bgp_fsm.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_zebra.h"
61 #include "bgpd/bgp_open.h"
62 #include "bgpd/bgp_filter.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_mplsvpn.h"
67 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
68 #include "bgpd/rfapi/rfapi_backend.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_advertise.h"
72 #include "bgpd/bgp_network.h"
73 #include "bgpd/bgp_vty.h"
74 #include "bgpd/bgp_mpath.h"
75 #include "bgpd/bgp_nht.h"
76 #include "bgpd/bgp_updgrp.h"
77 #include "bgpd/bgp_bfd.h"
78 #include "bgpd/bgp_memory.h"
79 #include "bgpd/bgp_evpn_vty.h"
80 #include "bgpd/bgp_keepalives.h"
81 #include "bgpd/bgp_io.h"
84 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
85 DEFINE_QOBJ_TYPE(bgp_master
)
87 DEFINE_QOBJ_TYPE(peer
)
89 /* BGP process wide configuration. */
90 static struct bgp_master bgp_master
;
92 /* BGP process wide configuration pointer to export. */
93 struct bgp_master
*bm
;
95 /* BGP community-list. */
96 struct community_list_handler
*bgp_clist
;
98 unsigned int multipath_num
= MULTIPATH_NUM
;
100 static void bgp_if_finish(struct bgp
*bgp
);
102 extern struct zclient
*zclient
;
104 void bgp_session_reset(struct peer
*peer
)
106 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
107 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
108 peer_delete(peer
->doppelganger
);
110 BGP_EVENT_ADD(peer
, BGP_Stop
);
114 * During session reset, we may delete the doppelganger peer, which would
115 * be the next node to the current node. If the session reset was invoked
116 * during walk of peer list, we would end up accessing the freed next
117 * node. This function moves the next node along.
119 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
124 n
= (nnode
) ? *nnode
: NULL
;
125 npeer
= (n
) ? listgetdata(n
) : NULL
;
127 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
128 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
129 PEER_FLAG_CONFIG_NODE
))) {
130 if (peer
->doppelganger
== npeer
)
131 /* nnode and *nnode are confirmed to be non-NULL here */
132 *nnode
= (*nnode
)->next
;
133 peer_delete(peer
->doppelganger
);
136 BGP_EVENT_ADD(peer
, BGP_Stop
);
139 /* BGP global flag manipulation. */
140 int bgp_option_set(int flag
)
144 case BGP_OPT_MULTIPLE_INSTANCE
:
145 case BGP_OPT_CONFIG_CISCO
:
146 case BGP_OPT_NO_LISTEN
:
147 SET_FLAG(bm
->options
, flag
);
150 return BGP_ERR_INVALID_FLAG
;
155 int bgp_option_unset(int flag
)
158 case BGP_OPT_MULTIPLE_INSTANCE
:
159 if (listcount(bm
->bgp
) > 1)
160 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
163 case BGP_OPT_CONFIG_CISCO
:
164 UNSET_FLAG(bm
->options
, flag
);
167 return BGP_ERR_INVALID_FLAG
;
172 int bgp_option_check(int flag
)
174 return CHECK_FLAG(bm
->options
, flag
);
177 /* BGP flag manipulation. */
178 int bgp_flag_set(struct bgp
*bgp
, int flag
)
180 SET_FLAG(bgp
->flags
, flag
);
184 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
186 UNSET_FLAG(bgp
->flags
, flag
);
190 int bgp_flag_check(struct bgp
*bgp
, int flag
)
192 return CHECK_FLAG(bgp
->flags
, flag
);
195 /* Internal function to set BGP structure configureation flag. */
196 static void bgp_config_set(struct bgp
*bgp
, int config
)
198 SET_FLAG(bgp
->config
, config
);
201 static void bgp_config_unset(struct bgp
*bgp
, int config
)
203 UNSET_FLAG(bgp
->config
, config
);
206 static int bgp_config_check(struct bgp
*bgp
, int config
)
208 return CHECK_FLAG(bgp
->config
, config
);
211 /* Set BGP router identifier. */
212 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
215 struct listnode
*node
, *nnode
;
217 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
220 /* EVPN uses router id in RD, withdraw them */
221 if (bgp
->advertise_all_vni
)
222 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
224 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
226 /* Set all peer's local identifier with this value. */
227 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
228 IPV4_ADDR_COPY(&peer
->local_id
, id
);
230 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
231 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
232 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
233 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
237 /* EVPN uses router id in RD, update them */
238 if (bgp
->advertise_all_vni
)
239 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
244 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
246 struct listnode
*node
, *nnode
;
249 if (vrf_id
== VRF_DEFAULT
) {
250 /* Router-id change for default VRF has to also update all
252 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
253 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
256 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
257 if (!bgp
->router_id_static
.s_addr
)
258 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
261 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
263 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
265 if (!bgp
->router_id_static
.s_addr
)
266 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
271 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
273 bgp
->router_id_static
= id
;
274 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
278 /* BGP's cluster-id control. */
279 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
282 struct listnode
*node
, *nnode
;
284 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
285 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
288 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
289 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
291 /* Clear all IBGP peer. */
292 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
293 if (peer
->sort
!= BGP_PEER_IBGP
)
296 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
297 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
298 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
299 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
305 int bgp_cluster_id_unset(struct bgp
*bgp
)
308 struct listnode
*node
, *nnode
;
310 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
313 bgp
->cluster_id
.s_addr
= 0;
314 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
316 /* Clear all IBGP peer. */
317 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
318 if (peer
->sort
!= BGP_PEER_IBGP
)
321 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
322 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
323 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
324 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
330 /* time_t value that is monotonicly increasing
331 * and uneffected by adjustments to system clock
333 time_t bgp_clock(void)
341 /* BGP timer configuration. */
342 int bgp_timers_set(struct bgp
*bgp
, u_int32_t keepalive
, u_int32_t holdtime
)
344 bgp
->default_keepalive
=
345 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
346 bgp
->default_holdtime
= holdtime
;
351 int bgp_timers_unset(struct bgp
*bgp
)
353 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
354 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
359 /* BGP confederation configuration. */
360 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
363 struct listnode
*node
, *nnode
;
367 return BGP_ERR_INVALID_AS
;
369 /* Remember - were we doing confederation before? */
370 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
372 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
374 /* If we were doing confederation already, this is just an external
375 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
376 were not doing confederation before, reset all EBGP sessions. */
377 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
378 /* We're looking for peers who's AS is not local or part of our
380 if (already_confed
) {
381 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
383 if (BGP_IS_VALID_STATE_FOR_NOTIF(
386 PEER_DOWN_CONFED_ID_CHANGE
;
388 peer
, BGP_NOTIFY_CEASE
,
389 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
391 bgp_session_reset_safe(peer
, &nnode
);
394 /* Not doign confederation before, so reset every
397 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
398 /* Reset the local_as to be our EBGP one */
399 if (peer_sort(peer
) == BGP_PEER_EBGP
)
401 if (BGP_IS_VALID_STATE_FOR_NOTIF(
404 PEER_DOWN_CONFED_ID_CHANGE
;
406 peer
, BGP_NOTIFY_CEASE
,
407 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
409 bgp_session_reset_safe(peer
, &nnode
);
416 int bgp_confederation_id_unset(struct bgp
*bgp
)
419 struct listnode
*node
, *nnode
;
422 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
424 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
425 /* We're looking for peers who's AS is not local */
426 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
427 peer
->local_as
= bgp
->as
;
428 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
429 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
430 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
431 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
435 bgp_session_reset_safe(peer
, &nnode
);
441 /* Is an AS part of the confed or not? */
442 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
449 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
450 if (bgp
->confed_peers
[i
] == as
)
456 /* Add an AS to the confederation set. */
457 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
460 struct listnode
*node
, *nnode
;
463 return BGP_ERR_INVALID_BGP
;
466 return BGP_ERR_INVALID_AS
;
468 if (bgp_confederation_peers_check(bgp
, as
))
471 if (bgp
->confed_peers
)
473 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
474 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
477 XMALLOC(MTYPE_BGP_CONFED_LIST
,
478 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
480 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
481 bgp
->confed_peers_cnt
++;
483 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
484 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
485 if (peer
->as
== as
) {
486 peer
->local_as
= bgp
->as
;
487 if (BGP_IS_VALID_STATE_FOR_NOTIF(
490 PEER_DOWN_CONFED_PEER_CHANGE
;
492 peer
, BGP_NOTIFY_CEASE
,
493 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
495 bgp_session_reset_safe(peer
, &nnode
);
502 /* Delete an AS from the confederation set. */
503 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
508 struct listnode
*node
, *nnode
;
513 if (!bgp_confederation_peers_check(bgp
, as
))
516 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
517 if (bgp
->confed_peers
[i
] == as
)
518 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
519 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
521 bgp
->confed_peers_cnt
--;
523 if (bgp
->confed_peers_cnt
== 0) {
524 if (bgp
->confed_peers
)
525 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
526 bgp
->confed_peers
= NULL
;
529 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
530 bgp
->confed_peers_cnt
* sizeof(as_t
));
532 /* Now reset any peer who's remote AS has just been removed from the
534 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
535 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
536 if (peer
->as
== as
) {
537 peer
->local_as
= bgp
->confed_id
;
538 if (BGP_IS_VALID_STATE_FOR_NOTIF(
541 PEER_DOWN_CONFED_PEER_CHANGE
;
543 peer
, BGP_NOTIFY_CEASE
,
544 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
546 bgp_session_reset_safe(peer
, &nnode
);
554 /* Local preference configuration. */
555 int bgp_default_local_preference_set(struct bgp
*bgp
, u_int32_t local_pref
)
560 bgp
->default_local_pref
= local_pref
;
565 int bgp_default_local_preference_unset(struct bgp
*bgp
)
570 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
575 /* Local preference configuration. */
576 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
,
577 u_int32_t queue_size
)
582 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
587 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
591 bgp
->default_subgroup_pkt_queue_max
=
592 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
597 /* Listen limit configuration. */
598 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
603 bgp
->dynamic_neighbors_limit
= listen_limit
;
608 int bgp_listen_limit_unset(struct bgp
*bgp
)
613 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
618 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
619 afi_t
*afi
, safi_t
*safi
)
621 /* Map from IANA values to internal values, return error if
622 * values are unrecognized.
624 *afi
= afi_iana2int(pkt_afi
);
625 *safi
= safi_iana2int(pkt_safi
);
626 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
632 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
633 iana_safi_t
*pkt_safi
)
635 /* Map from internal values to IANA values, return error if
636 * internal values are bad (unexpected).
638 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
640 *pkt_afi
= afi_int2iana(afi
);
641 *pkt_safi
= safi_int2iana(safi
);
645 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
653 afid
= afindex(afi
, safi
);
654 if (afid
>= BGP_AF_MAX
)
657 assert(peer
->peer_af_array
[afid
] == NULL
);
659 /* Allocate new peer af */
660 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
663 zlog_err("Could not create af structure for peer %s",
668 peer
->peer_af_array
[afid
] = af
;
677 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
684 afid
= afindex(afi
, safi
);
685 if (afid
>= BGP_AF_MAX
)
688 return peer
->peer_af_array
[afid
];
691 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
699 afid
= afindex(afi
, safi
);
700 if (afid
>= BGP_AF_MAX
)
703 af
= peer
->peer_af_array
[afid
];
707 bgp_stop_announce_route_timer(af
);
709 if (PAF_SUBGRP(af
)) {
710 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
711 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
712 af
->subgroup
->update_group
->id
,
713 af
->subgroup
->id
, peer
->host
);
716 update_subgroup_remove_peer(af
->subgroup
, af
);
718 peer
->peer_af_array
[afid
] = NULL
;
719 XFREE(MTYPE_BGP_PEER_AF
, af
);
723 /* Peer comparison function for sorting. */
724 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
726 if (p1
->group
&& !p2
->group
)
729 if (!p1
->group
&& p2
->group
)
732 if (p1
->group
== p2
->group
) {
733 if (p1
->conf_if
&& !p2
->conf_if
)
736 if (!p1
->conf_if
&& p2
->conf_if
)
739 if (p1
->conf_if
&& p2
->conf_if
)
740 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
742 return strcmp(p1
->group
->name
, p2
->group
->name
);
744 return sockunion_cmp(&p1
->su
, &p2
->su
);
747 static unsigned int peer_hash_key_make(void *p
)
749 struct peer
*peer
= p
;
750 return sockunion_hash(&peer
->su
);
753 static int peer_hash_same(const void *p1
, const void *p2
)
755 const struct peer
*peer1
= p1
;
756 const struct peer
*peer2
= p2
;
757 return (sockunion_same(&peer1
->su
, &peer2
->su
)
758 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
759 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
762 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
765 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
768 /* Return true if flag is set for the peer but not the peer-group */
769 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
772 struct peer
*g_peer
= NULL
;
774 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
775 if (peer_group_active(peer
)) {
776 g_peer
= peer
->group
->conf
;
778 /* If this flag is not set for the peer's peer-group
779 * then return true */
780 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
785 /* peer is not in a peer-group but the flag is set to return
795 /* Reset all address family specific configuration. */
796 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
799 struct bgp_filter
*filter
;
800 char orf_name
[BUFSIZ
];
802 filter
= &peer
->filter
[afi
][safi
];
804 /* Clear neighbor filter and route-map */
805 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
806 if (filter
->dlist
[i
].name
) {
807 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
808 filter
->dlist
[i
].name
= NULL
;
810 if (filter
->plist
[i
].name
) {
811 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
812 filter
->plist
[i
].name
= NULL
;
814 if (filter
->aslist
[i
].name
) {
815 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
816 filter
->aslist
[i
].name
= NULL
;
819 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
820 if (filter
->map
[i
].name
) {
821 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
822 filter
->map
[i
].name
= NULL
;
826 /* Clear unsuppress map. */
827 if (filter
->usmap
.name
)
828 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
829 filter
->usmap
.name
= NULL
;
830 filter
->usmap
.map
= NULL
;
832 /* Clear neighbor's all address family flags. */
833 peer
->af_flags
[afi
][safi
] = 0;
835 /* Clear neighbor's all address family sflags. */
836 peer
->af_sflags
[afi
][safi
] = 0;
838 /* Clear neighbor's all address family capabilities. */
839 peer
->af_cap
[afi
][safi
] = 0;
842 peer
->orf_plist
[afi
][safi
] = NULL
;
843 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
844 prefix_bgp_orf_remove_all(afi
, orf_name
);
846 /* Set default neighbor send-community. */
847 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
848 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
849 SET_FLAG(peer
->af_flags
[afi
][safi
],
850 PEER_FLAG_SEND_EXT_COMMUNITY
);
851 SET_FLAG(peer
->af_flags
[afi
][safi
],
852 PEER_FLAG_SEND_LARGE_COMMUNITY
);
855 /* Clear neighbor default_originate_rmap */
856 if (peer
->default_rmap
[afi
][safi
].name
)
857 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
858 peer
->default_rmap
[afi
][safi
].name
= NULL
;
859 peer
->default_rmap
[afi
][safi
].map
= NULL
;
861 /* Clear neighbor maximum-prefix */
862 peer
->pmax
[afi
][safi
] = 0;
863 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
866 /* peer global config reset */
867 static void peer_global_config_reset(struct peer
*peer
)
872 peer
->change_local_as
= 0;
873 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
874 if (peer
->update_source
) {
875 sockunion_free(peer
->update_source
);
876 peer
->update_source
= NULL
;
878 if (peer
->update_if
) {
879 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
880 peer
->update_if
= NULL
;
883 if (peer_sort(peer
) == BGP_PEER_IBGP
)
884 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
886 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
888 /* This is a per-peer specific flag and so we must preserve it */
889 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
894 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
900 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
902 /* Reset some other configs back to defaults. */
903 peer
->v_start
= BGP_INIT_START_TIMER
;
904 peer
->password
= NULL
;
905 peer
->local_id
= peer
->bgp
->router_id
;
906 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
907 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
909 bfd_info_free(&(peer
->bfd_info
));
911 /* Set back the CONFIG_NODE flag. */
912 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
915 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
916 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
923 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
924 if (peer
->as_type
== AS_INTERNAL
)
925 return BGP_PEER_IBGP
;
927 else if (peer
->as_type
== AS_EXTERNAL
)
928 return BGP_PEER_EBGP
;
930 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
931 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
936 peer1
= listnode_head(peer
->group
->peer
);
941 return BGP_PEER_INTERNAL
;
945 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
946 if (peer
->local_as
== 0)
947 return BGP_PEER_INTERNAL
;
949 if (peer
->local_as
== peer
->as
) {
950 if (bgp
->as
== bgp
->confed_id
) {
951 if (peer
->local_as
== bgp
->as
)
952 return BGP_PEER_IBGP
;
954 return BGP_PEER_EBGP
;
956 if (peer
->local_as
== bgp
->confed_id
)
957 return BGP_PEER_EBGP
;
959 return BGP_PEER_IBGP
;
963 if (bgp_confederation_peers_check(bgp
, peer
->as
))
964 return BGP_PEER_CONFED
;
966 return BGP_PEER_EBGP
;
968 if (peer
->as_type
!= AS_SPECIFIED
)
969 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
972 return (peer
->local_as
== 0
974 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
979 /* Calculate and cache the peer "sort" */
980 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
982 peer
->sort
= peer_calc_sort(peer
);
986 static void peer_free(struct peer
*peer
)
988 assert(peer
->status
== Deleted
);
992 /* this /ought/ to have been done already through bgp_stop earlier,
993 * but just to be sure..
997 bgp_writes_off(peer
);
998 assert(!peer
->t_write
);
999 assert(!peer
->t_read
);
1000 BGP_EVENT_FLUSH(peer
);
1002 pthread_mutex_destroy(&peer
->io_mtx
);
1004 /* Free connected nexthop, if present */
1005 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1006 && !peer_dynamic_neighbor(peer
))
1007 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1010 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1013 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1017 /* Free allocated host character. */
1019 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1023 if (peer
->domainname
) {
1024 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1025 peer
->domainname
= NULL
;
1029 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1030 peer
->ifname
= NULL
;
1033 /* Update source configuration. */
1034 if (peer
->update_source
) {
1035 sockunion_free(peer
->update_source
);
1036 peer
->update_source
= NULL
;
1039 if (peer
->update_if
) {
1040 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1041 peer
->update_if
= NULL
;
1044 if (peer
->notify
.data
)
1045 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1046 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1048 if (peer
->clear_node_queue
) {
1049 work_queue_free(peer
->clear_node_queue
);
1050 peer
->clear_node_queue
= NULL
;
1053 bgp_sync_delete(peer
);
1055 if (peer
->conf_if
) {
1056 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1057 peer
->conf_if
= NULL
;
1060 bfd_info_free(&(peer
->bfd_info
));
1062 bgp_unlock(peer
->bgp
);
1064 memset(peer
, 0, sizeof(struct peer
));
1066 XFREE(MTYPE_BGP_PEER
, peer
);
1069 /* increase reference count on a struct peer */
1070 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1072 assert(peer
&& (peer
->lock
>= 0));
1075 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1083 /* decrease reference count on a struct peer
1084 * struct peer is freed and NULL returned if last reference
1086 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1088 assert(peer
&& (peer
->lock
> 0));
1091 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1096 if (peer
->lock
== 0) {
1104 /* Allocate new peer object, implicitely locked. */
1105 struct peer
*peer_new(struct bgp
*bgp
)
1112 /* bgp argument is absolutely required */
1117 /* Allocate new peer. */
1118 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1120 /* Set default value. */
1122 peer
->v_start
= BGP_INIT_START_TIMER
;
1123 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1124 peer
->status
= Idle
;
1125 peer
->ostatus
= Idle
;
1126 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1127 peer
->bgp
= bgp_lock(bgp
);
1128 peer
= peer_lock(peer
); /* initial reference */
1129 peer
->password
= NULL
;
1131 /* Set default flags. */
1132 FOREACH_AFI_SAFI (afi
, safi
) {
1133 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1134 SET_FLAG(peer
->af_flags
[afi
][safi
],
1135 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 peer
->orf_plist
[afi
][safi
] = NULL
;
1143 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1145 /* Create buffers. */
1146 peer
->ibuf
= stream_fifo_new();
1147 peer
->obuf
= stream_fifo_new();
1148 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1150 /* We use a larger buffer for peer->obuf_work in the event that:
1151 * - We RX a BGP_UPDATE where the attributes alone are just
1152 * under BGP_MAX_PACKET_SIZE
1153 * - The user configures an outbound route-map that does many as-path
1154 * prepends or adds many communities. At most they can have
1156 * args in a route-map so there is a finite limit on how large they
1158 * make the attributes.
1160 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1162 * checking for every single attribute as we construct an UPDATE.
1165 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1167 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1169 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1171 bgp_sync_init(peer
);
1173 /* Get service port number. */
1174 sp
= getservbyname("bgp", "tcp");
1175 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1177 QOBJ_REG(peer
, peer
);
1182 * This function is invoked when a duplicate peer structure associated with
1183 * a neighbor is being deleted. If this about-to-be-deleted structure is
1184 * the one with all the config, then we have to copy over the info.
1186 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1188 struct peer_af
*paf
;
1196 /* The following function is used by both peer group config copy to
1197 * individual peer and when we transfer config
1199 if (peer_src
->change_local_as
)
1200 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1202 /* peer flags apply */
1203 peer_dst
->flags
= peer_src
->flags
;
1204 peer_dst
->cap
= peer_src
->cap
;
1205 peer_dst
->config
= peer_src
->config
;
1207 peer_dst
->local_as
= peer_src
->local_as
;
1208 peer_dst
->ifindex
= peer_src
->ifindex
;
1209 peer_dst
->port
= peer_src
->port
;
1210 (void)peer_sort(peer_dst
);
1211 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1214 peer_dst
->holdtime
= peer_src
->holdtime
;
1215 peer_dst
->keepalive
= peer_src
->keepalive
;
1216 peer_dst
->connect
= peer_src
->connect
;
1217 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1218 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1219 peer_dst
->routeadv
= peer_src
->routeadv
;
1220 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1222 /* password apply */
1223 if (peer_src
->password
&& !peer_dst
->password
)
1224 peer_dst
->password
=
1225 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1227 FOREACH_AFI_SAFI (afi
, safi
) {
1228 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1229 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1230 peer_dst
->allowas_in
[afi
][safi
] =
1231 peer_src
->allowas_in
[afi
][safi
];
1232 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1235 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1236 paf
= peer_src
->peer_af_array
[afidx
];
1238 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1241 /* update-source apply */
1242 if (peer_src
->update_source
) {
1243 if (peer_dst
->update_source
)
1244 sockunion_free(peer_dst
->update_source
);
1245 if (peer_dst
->update_if
) {
1246 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1247 peer_dst
->update_if
= NULL
;
1249 peer_dst
->update_source
=
1250 sockunion_dup(peer_src
->update_source
);
1251 } else if (peer_src
->update_if
) {
1252 if (peer_dst
->update_if
)
1253 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1254 if (peer_dst
->update_source
) {
1255 sockunion_free(peer_dst
->update_source
);
1256 peer_dst
->update_source
= NULL
;
1258 peer_dst
->update_if
=
1259 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1262 if (peer_src
->ifname
) {
1263 if (peer_dst
->ifname
)
1264 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1267 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1271 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1272 struct interface
*ifp
)
1274 struct connected
*ifc
;
1277 struct listnode
*node
;
1279 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1280 * IPv4 address of the other end.
1282 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1283 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1284 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1285 if (p
.prefixlen
== 30) {
1286 peer
->su
.sa
.sa_family
= AF_INET
;
1287 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1289 peer
->su
.sin
.sin_addr
.s_addr
=
1291 else if (addr
% 4 == 2)
1292 peer
->su
.sin
.sin_addr
.s_addr
=
1294 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1295 peer
->su
.sin
.sin_len
=
1296 sizeof(struct sockaddr_in
);
1297 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1299 } else if (p
.prefixlen
== 31) {
1300 peer
->su
.sa
.sa_family
= AF_INET
;
1301 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1303 peer
->su
.sin
.sin_addr
.s_addr
=
1306 peer
->su
.sin
.sin_addr
.s_addr
=
1308 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1309 peer
->su
.sin
.sin_len
=
1310 sizeof(struct sockaddr_in
);
1311 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1313 } else if (bgp_debug_neighbor_events(peer
))
1315 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1323 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1324 struct interface
*ifp
)
1326 struct nbr_connected
*ifc_nbr
;
1328 /* Have we learnt the peer's IPv6 link-local address? */
1329 if (ifp
->nbr_connected
1330 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1331 peer
->su
.sa
.sa_family
= AF_INET6
;
1332 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1333 sizeof(struct in6_addr
));
1335 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1337 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1345 * Set or reset the peer address socketunion structure based on the
1346 * learnt/derived peer address. If the address has changed, update the
1347 * password on the listen socket, if needed.
1349 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1351 struct interface
*ifp
;
1353 int peer_addr_updated
= 0;
1358 prev_family
= peer
->su
.sa
.sa_family
;
1359 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1361 /* If BGP unnumbered is not "v6only", we first see if we can
1363 * peer's IPv4 address.
1365 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1367 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1369 /* If "v6only" or we can't derive peer's IPv4 address, see if
1371 * learnt the peer's IPv6 link-local address. This is from the
1373 * IPv6 address in router advertisement.
1375 if (!peer_addr_updated
)
1377 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1379 /* If we could derive the peer address, we may need to install the
1381 * configured for the peer, if any, on the listen socket. Otherwise,
1383 * that peer's address is not available and uninstall the password, if
1386 if (peer_addr_updated
) {
1387 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1390 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1391 bgp_md5_unset(peer
);
1392 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1393 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1396 /* Since our su changed we need to del/add peer to the peerhash */
1397 hash_release(peer
->bgp
->peerhash
, peer
);
1398 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1401 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1404 struct bgp_node
*rn
, *nrn
;
1406 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1407 rn
= bgp_route_next(rn
)) {
1408 if (rn
->info
!= NULL
) {
1409 /* Special handling for 2-level routing
1411 if (safi
== SAFI_MPLS_VPN
1412 || safi
== SAFI_ENCAP
1413 || safi
== SAFI_EVPN
) {
1414 for (nrn
= bgp_table_top((
1418 nrn
= bgp_route_next(nrn
))
1419 bgp_process(bgp
, nrn
,
1422 bgp_process(bgp
, rn
, afi
, safi
);
1427 /* Force a bestpath recalculation for all prefixes. This is used
1428 * when 'bgp bestpath' commands are entered.
1430 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1435 FOREACH_AFI_SAFI (afi
, safi
) {
1436 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1440 /* Create new BGP peer. */
1441 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1442 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1443 int as_type
, afi_t afi
, safi_t safi
,
1444 struct peer_group
*group
)
1448 char buf
[SU_ADDRSTRLEN
];
1450 peer
= peer_new(bgp
);
1452 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1453 bgp_peer_conf_if_to_su_update(peer
);
1455 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1456 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1459 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1461 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1462 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1464 peer
->local_as
= local_as
;
1465 peer
->as
= remote_as
;
1466 peer
->as_type
= as_type
;
1467 peer
->local_id
= bgp
->router_id
;
1468 peer
->v_holdtime
= bgp
->default_holdtime
;
1469 peer
->v_keepalive
= bgp
->default_keepalive
;
1470 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1471 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1473 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1475 peer
= peer_lock(peer
); /* bgp peer list reference */
1476 peer
->group
= group
;
1477 listnode_add_sort(bgp
->peer
, peer
);
1478 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1480 /* Adjust update-group coalesce timer heuristics for # peers. */
1481 if (bgp
->heuristic_coalesce
) {
1482 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1484 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1485 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1488 active
= peer_active(peer
);
1490 /* Last read and reset time set */
1491 peer
->readtime
= peer
->resettime
= bgp_clock();
1493 /* Default TTL set. */
1494 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1496 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1499 peer
->afc
[afi
][safi
] = 1;
1500 peer_af_create(peer
, afi
, safi
);
1503 /* Set up peer's events and timers. */
1504 if (!active
&& peer_active(peer
))
1505 bgp_timer_set(peer
);
1510 /* Make accept BGP peer. This function is only called from the test code */
1511 struct peer
*peer_create_accept(struct bgp
*bgp
)
1515 peer
= peer_new(bgp
);
1517 peer
= peer_lock(peer
); /* bgp peer list reference */
1518 listnode_add_sort(bgp
->peer
, peer
);
1524 * Return true if we have a peer configured to use this afi/safi
1526 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1528 struct listnode
*node
;
1531 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1532 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1535 if (peer
->afc
[afi
][safi
])
1542 /* Change peer's AS number. */
1543 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1545 bgp_peer_sort_t type
;
1549 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1550 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1551 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1552 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1553 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1555 bgp_session_reset(peer
);
1557 type
= peer_sort(peer
);
1559 peer
->as_type
= as_specified
;
1561 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1562 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1563 && peer
->bgp
->as
!= as
)
1564 peer
->local_as
= peer
->bgp
->confed_id
;
1566 peer
->local_as
= peer
->bgp
->as
;
1568 /* Advertisement-interval reset */
1571 conf
= peer
->group
->conf
;
1573 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1574 peer
->v_routeadv
= conf
->routeadv
;
1576 /* Only go back to the default advertisement-interval if the user had
1578 * already configured it */
1579 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1580 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1581 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1583 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1586 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1588 else if (type
== BGP_PEER_IBGP
)
1591 /* reflector-client reset */
1592 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1593 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1594 PEER_FLAG_REFLECTOR_CLIENT
);
1595 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1596 PEER_FLAG_REFLECTOR_CLIENT
);
1597 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1598 PEER_FLAG_REFLECTOR_CLIENT
);
1599 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1600 PEER_FLAG_REFLECTOR_CLIENT
);
1601 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1602 PEER_FLAG_REFLECTOR_CLIENT
);
1603 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1604 PEER_FLAG_REFLECTOR_CLIENT
);
1605 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1606 PEER_FLAG_REFLECTOR_CLIENT
);
1607 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1608 PEER_FLAG_REFLECTOR_CLIENT
);
1609 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1610 PEER_FLAG_REFLECTOR_CLIENT
);
1611 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1612 PEER_FLAG_REFLECTOR_CLIENT
);
1613 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1614 PEER_FLAG_REFLECTOR_CLIENT
);
1617 /* local-as reset */
1618 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1619 peer
->change_local_as
= 0;
1620 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1621 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1625 /* If peer does not exist, create new one. If peer already exists,
1626 set AS number to the peer. */
1627 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1628 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1634 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1636 peer
= peer_lookup(bgp
, su
);
1639 /* Not allowed for a dynamic peer. */
1640 if (peer_dynamic_neighbor(peer
)) {
1642 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1645 /* When this peer is a member of peer-group. */
1647 if (peer
->group
->conf
->as
) {
1648 /* Return peer group's AS number. */
1649 *as
= peer
->group
->conf
->as
;
1650 return BGP_ERR_PEER_GROUP_MEMBER
;
1652 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1653 if ((as_type
!= AS_INTERNAL
)
1654 && (bgp
->as
!= *as
)) {
1656 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1659 if ((as_type
!= AS_EXTERNAL
)
1660 && (bgp
->as
== *as
)) {
1662 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1667 /* Existing peer's AS number change. */
1668 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1669 || (peer
->as_type
!= as_type
))
1670 peer_as_change(peer
, *as
, as_type
);
1673 return BGP_ERR_NO_INTERFACE_CONFIG
;
1675 /* If the peer is not part of our confederation, and its not an
1676 iBGP peer then spoof the source AS */
1677 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1678 && !bgp_confederation_peers_check(bgp
, *as
)
1680 local_as
= bgp
->confed_id
;
1684 /* If this is IPv4 unicast configuration and "no bgp default
1685 ipv4-unicast" is specified. */
1687 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1688 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1689 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1692 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1699 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1700 struct peer
*peer
, afi_t afi
,
1704 int out
= FILTER_OUT
;
1706 struct bgp_filter
*pfilter
;
1707 struct bgp_filter
*gfilter
;
1710 pfilter
= &peer
->filter
[afi
][safi
];
1711 gfilter
= &conf
->filter
[afi
][safi
];
1713 /* peer af_flags apply */
1714 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1716 /* maximum-prefix */
1717 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1718 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1719 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1722 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1725 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1727 /* default-originate route-map */
1728 if (conf
->default_rmap
[afi
][safi
].name
) {
1729 if (peer
->default_rmap
[afi
][safi
].name
)
1730 XFREE(MTYPE_BGP_FILTER_NAME
,
1731 peer
->default_rmap
[afi
][safi
].name
);
1732 peer
->default_rmap
[afi
][safi
].name
=
1733 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1734 conf
->default_rmap
[afi
][safi
].name
);
1735 peer
->default_rmap
[afi
][safi
].map
=
1736 conf
->default_rmap
[afi
][safi
].map
;
1739 /* inbound filter apply */
1740 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1741 if (pfilter
->dlist
[in
].name
)
1742 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1743 pfilter
->dlist
[in
].name
=
1744 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1745 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1748 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1749 if (pfilter
->plist
[in
].name
)
1750 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1751 pfilter
->plist
[in
].name
=
1752 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1753 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1756 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1757 if (pfilter
->aslist
[in
].name
)
1758 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1759 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1760 gfilter
->aslist
[in
].name
);
1761 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1764 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1765 if (pfilter
->map
[RMAP_IN
].name
)
1766 XFREE(MTYPE_BGP_FILTER_NAME
,
1767 pfilter
->map
[RMAP_IN
].name
);
1768 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1769 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1770 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1773 /* outbound filter apply */
1774 if (gfilter
->dlist
[out
].name
) {
1775 if (pfilter
->dlist
[out
].name
)
1776 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1777 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1778 gfilter
->dlist
[out
].name
);
1779 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1781 if (pfilter
->dlist
[out
].name
)
1782 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1783 pfilter
->dlist
[out
].name
= NULL
;
1784 pfilter
->dlist
[out
].alist
= NULL
;
1787 if (gfilter
->plist
[out
].name
) {
1788 if (pfilter
->plist
[out
].name
)
1789 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1790 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1791 gfilter
->plist
[out
].name
);
1792 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1794 if (pfilter
->plist
[out
].name
)
1795 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1796 pfilter
->plist
[out
].name
= NULL
;
1797 pfilter
->plist
[out
].plist
= NULL
;
1800 if (gfilter
->aslist
[out
].name
) {
1801 if (pfilter
->aslist
[out
].name
)
1802 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1803 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1804 gfilter
->aslist
[out
].name
);
1805 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1807 if (pfilter
->aslist
[out
].name
)
1808 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1809 pfilter
->aslist
[out
].name
= NULL
;
1810 pfilter
->aslist
[out
].aslist
= NULL
;
1813 if (gfilter
->map
[RMAP_OUT
].name
) {
1814 if (pfilter
->map
[RMAP_OUT
].name
)
1815 XFREE(MTYPE_BGP_FILTER_NAME
,
1816 pfilter
->map
[RMAP_OUT
].name
);
1817 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1818 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1819 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1821 if (pfilter
->map
[RMAP_OUT
].name
)
1822 XFREE(MTYPE_BGP_FILTER_NAME
,
1823 pfilter
->map
[RMAP_OUT
].name
);
1824 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1825 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1828 if (gfilter
->usmap
.name
) {
1829 if (pfilter
->usmap
.name
)
1830 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1831 pfilter
->usmap
.name
=
1832 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1833 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1835 if (pfilter
->usmap
.name
)
1836 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1837 pfilter
->usmap
.name
= NULL
;
1838 pfilter
->usmap
.map
= NULL
;
1842 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1846 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1847 zlog_err("%s was called for peer-group %s", __func__
,
1852 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1854 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1855 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1856 return BGP_ERR_PEER_SAFI_CONFLICT
;
1858 /* Nothing to do if we've already activated this peer */
1859 if (peer
->afc
[afi
][safi
])
1862 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1865 active
= peer_active(peer
);
1866 peer
->afc
[afi
][safi
] = 1;
1869 peer_group2peer_config_copy_af(peer
->group
, peer
,
1872 if (!active
&& peer_active(peer
)) {
1873 bgp_timer_set(peer
);
1875 if (peer
->status
== Established
) {
1876 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1877 peer
->afc_adv
[afi
][safi
] = 1;
1878 bgp_capability_send(peer
, afi
, safi
,
1880 CAPABILITY_ACTION_SET
);
1881 if (peer
->afc_recv
[afi
][safi
]) {
1882 peer
->afc_nego
[afi
][safi
] = 1;
1883 bgp_announce_route(peer
, afi
, safi
);
1886 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1887 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1888 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1891 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1892 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1893 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1894 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1901 /* Activate the peer or peer group for specified AFI and SAFI. */
1902 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1905 struct peer_group
*group
;
1906 struct listnode
*node
, *nnode
;
1907 struct peer
*tmp_peer
;
1910 /* Nothing to do if we've already activated this peer */
1911 if (peer
->afc
[afi
][safi
])
1916 /* This is a peer-group so activate all of the members of the
1917 * peer-group as well */
1918 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1920 /* Do not activate a peer for both SAFI_UNICAST and
1921 * SAFI_LABELED_UNICAST */
1922 if ((safi
== SAFI_UNICAST
1923 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1924 || (safi
== SAFI_LABELED_UNICAST
1925 && peer
->afc
[afi
][SAFI_UNICAST
]))
1926 return BGP_ERR_PEER_SAFI_CONFLICT
;
1928 peer
->afc
[afi
][safi
] = 1;
1929 group
= peer
->group
;
1931 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1932 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1935 ret
|= peer_activate_af(peer
, afi
, safi
);
1938 /* If this is the first peer to be activated for this afi/labeled-unicast
1939 * recalc bestpaths to trigger label allocation */
1940 if (safi
== SAFI_LABELED_UNICAST
&& !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1942 if (BGP_DEBUG(zebra
, ZEBRA
))
1943 zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels");
1945 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1946 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1952 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1955 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1956 zlog_err("%s was called for peer-group %s", __func__
,
1961 /* Nothing to do if we've already deactivated this peer */
1962 if (!peer
->afc
[afi
][safi
])
1965 /* De-activate the address family configuration. */
1966 peer
->afc
[afi
][safi
] = 0;
1968 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1969 zlog_err("couldn't delete af structure for peer %s",
1974 if (peer
->status
== Established
) {
1975 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1976 peer
->afc_adv
[afi
][safi
] = 0;
1977 peer
->afc_nego
[afi
][safi
] = 0;
1979 if (peer_active_nego(peer
)) {
1980 bgp_capability_send(peer
, afi
, safi
,
1982 CAPABILITY_ACTION_UNSET
);
1983 bgp_clear_route(peer
, afi
, safi
);
1984 peer
->pcount
[afi
][safi
] = 0;
1986 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1987 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1988 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1991 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1992 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1993 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2000 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2003 struct peer_group
*group
;
2004 struct peer
*tmp_peer
;
2005 struct listnode
*node
, *nnode
;
2008 /* Nothing to do if we've already de-activated this peer */
2009 if (!peer
->afc
[afi
][safi
])
2012 /* This is a peer-group so de-activate all of the members of the
2013 * peer-group as well */
2014 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2015 peer
->afc
[afi
][safi
] = 0;
2016 group
= peer
->group
;
2018 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2019 zlog_err("couldn't delete af structure for peer %s",
2023 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2024 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2027 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2032 /* If this is the last peer to be deactivated for this afi/labeled-unicast
2033 * recalc bestpaths to trigger label deallocation */
2034 if (safi
== SAFI_LABELED_UNICAST
&&
2035 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] &&
2036 !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2038 if (BGP_DEBUG(zebra
, ZEBRA
))
2039 zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2041 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2042 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2047 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2050 return peer_activate(peer
, afi
, safi
);
2052 return peer_deactivate(peer
, afi
, safi
);
2055 static void peer_nsf_stop(struct peer
*peer
)
2060 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2061 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2063 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2064 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2065 peer
->nsf
[afi
][safi
] = 0;
2067 if (peer
->t_gr_restart
) {
2068 BGP_TIMER_OFF(peer
->t_gr_restart
);
2069 if (bgp_debug_neighbor_events(peer
))
2070 zlog_debug("%s graceful restart timer stopped",
2073 if (peer
->t_gr_stale
) {
2074 BGP_TIMER_OFF(peer
->t_gr_stale
);
2075 if (bgp_debug_neighbor_events(peer
))
2077 "%s graceful restart stalepath timer stopped",
2080 bgp_clear_route_all(peer
);
2083 /* Delete peer from confguration.
2085 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2086 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2088 * This function /should/ take care to be idempotent, to guard against
2089 * it being called multiple times through stray events that come in
2090 * that happen to result in this function being called again. That
2091 * said, getting here for a "Deleted" peer is a bug in the neighbour
2094 int peer_delete(struct peer
*peer
)
2100 struct bgp_filter
*filter
;
2101 struct listnode
*pn
;
2104 assert(peer
->status
!= Deleted
);
2107 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2109 bgp_reads_off(peer
);
2110 bgp_writes_off(peer
);
2111 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2112 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2114 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2115 peer_nsf_stop(peer
);
2117 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2119 /* If this peer belongs to peer group, clear up the
2122 if (peer_dynamic_neighbor(peer
))
2123 peer_drop_dynamic_neighbor(peer
);
2125 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2127 peer
); /* group->peer list reference */
2128 list_delete_node(peer
->group
->peer
, pn
);
2133 /* Withdraw all information from routing table. We can not use
2134 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2135 * executed after peer structure is deleted.
2137 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2139 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2141 if (peer
->doppelganger
) {
2142 peer
->doppelganger
->doppelganger
= NULL
;
2143 peer
->doppelganger
= NULL
;
2146 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2147 bgp_fsm_change_status(peer
, Deleted
);
2149 /* Remove from NHT */
2150 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2151 bgp_unlink_nexthop_by_peer(peer
);
2153 /* Password configuration */
2154 if (peer
->password
) {
2155 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2156 peer
->password
= NULL
;
2158 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2159 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2160 bgp_md5_unset(peer
);
2163 bgp_timer_set(peer
); /* stops all timers for Deleted */
2165 /* Delete from all peer list. */
2166 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2167 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2168 peer_unlock(peer
); /* bgp peer list reference */
2169 list_delete_node(bgp
->peer
, pn
);
2170 hash_release(bgp
->peerhash
, peer
);
2175 stream_fifo_free(peer
->ibuf
);
2180 stream_fifo_free(peer
->obuf
);
2184 if (peer
->ibuf_work
) {
2185 ringbuf_del(peer
->ibuf_work
);
2186 peer
->ibuf_work
= NULL
;
2189 if (peer
->obuf_work
) {
2190 stream_free(peer
->obuf_work
);
2191 peer
->obuf_work
= NULL
;
2194 if (peer
->scratch
) {
2195 stream_free(peer
->scratch
);
2196 peer
->scratch
= NULL
;
2199 /* Local and remote addresses. */
2200 if (peer
->su_local
) {
2201 sockunion_free(peer
->su_local
);
2202 peer
->su_local
= NULL
;
2205 if (peer
->su_remote
) {
2206 sockunion_free(peer
->su_remote
);
2207 peer
->su_remote
= NULL
;
2210 /* Free filter related memory. */
2211 FOREACH_AFI_SAFI (afi
, safi
) {
2212 filter
= &peer
->filter
[afi
][safi
];
2214 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2215 if (filter
->dlist
[i
].name
) {
2216 XFREE(MTYPE_BGP_FILTER_NAME
,
2217 filter
->dlist
[i
].name
);
2218 filter
->dlist
[i
].name
= NULL
;
2221 if (filter
->plist
[i
].name
) {
2222 XFREE(MTYPE_BGP_FILTER_NAME
,
2223 filter
->plist
[i
].name
);
2224 filter
->plist
[i
].name
= NULL
;
2227 if (filter
->aslist
[i
].name
) {
2228 XFREE(MTYPE_BGP_FILTER_NAME
,
2229 filter
->aslist
[i
].name
);
2230 filter
->aslist
[i
].name
= NULL
;
2234 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2235 if (filter
->map
[i
].name
) {
2236 XFREE(MTYPE_BGP_FILTER_NAME
,
2237 filter
->map
[i
].name
);
2238 filter
->map
[i
].name
= NULL
;
2242 if (filter
->usmap
.name
) {
2243 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2244 filter
->usmap
.name
= NULL
;
2247 if (peer
->default_rmap
[afi
][safi
].name
) {
2248 XFREE(MTYPE_ROUTE_MAP_NAME
,
2249 peer
->default_rmap
[afi
][safi
].name
);
2250 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2254 FOREACH_AFI_SAFI (afi
, safi
)
2255 peer_af_delete(peer
, afi
, safi
);
2257 if (peer
->hostname
) {
2258 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2259 peer
->hostname
= NULL
;
2262 if (peer
->domainname
) {
2263 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2264 peer
->domainname
= NULL
;
2267 peer_unlock(peer
); /* initial reference */
2272 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2274 return strcmp(g1
->name
, g2
->name
);
2277 /* Peer group cofiguration. */
2278 static struct peer_group
*peer_group_new(void)
2280 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2281 sizeof(struct peer_group
));
2284 static void peer_group_free(struct peer_group
*group
)
2286 XFREE(MTYPE_PEER_GROUP
, group
);
2289 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2291 struct peer_group
*group
;
2292 struct listnode
*node
, *nnode
;
2294 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2295 if (strcmp(group
->name
, name
) == 0)
2301 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2303 struct peer_group
*group
;
2306 group
= peer_group_lookup(bgp
, name
);
2310 group
= peer_group_new();
2313 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2314 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2315 group
->peer
= list_new();
2316 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2317 group
->listen_range
[afi
] = list_new();
2318 group
->conf
= peer_new(bgp
);
2319 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2320 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2321 if (group
->conf
->host
)
2322 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2323 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2324 group
->conf
->group
= group
;
2325 group
->conf
->as
= 0;
2326 group
->conf
->ttl
= 1;
2327 group
->conf
->gtsm_hops
= 0;
2328 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2329 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2330 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2331 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2332 group
->conf
->keepalive
= 0;
2333 group
->conf
->holdtime
= 0;
2334 group
->conf
->connect
= 0;
2335 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2336 listnode_add_sort(bgp
->group
, group
);
2341 static void peer_group2peer_config_copy(struct peer_group
*group
,
2351 peer
->as
= conf
->as
;
2354 if (conf
->change_local_as
)
2355 peer
->change_local_as
= conf
->change_local_as
;
2358 peer
->ttl
= conf
->ttl
;
2361 peer
->gtsm_hops
= conf
->gtsm_hops
;
2363 /* this flag is per-neighbor and so has to be preserved */
2364 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2366 /* peer flags apply */
2367 peer
->flags
= conf
->flags
;
2370 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2372 /* peer config apply */
2373 peer
->config
= conf
->config
;
2375 /* peer timers apply */
2376 peer
->holdtime
= conf
->holdtime
;
2377 peer
->keepalive
= conf
->keepalive
;
2378 peer
->connect
= conf
->connect
;
2379 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2380 peer
->v_connect
= conf
->connect
;
2382 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2384 /* advertisement-interval reset */
2385 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2386 peer
->v_routeadv
= conf
->routeadv
;
2387 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2388 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2390 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2392 /* password apply */
2393 if (conf
->password
&& !peer
->password
)
2394 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2396 if (!BGP_PEER_SU_UNSPEC(peer
))
2399 /* update-source apply */
2400 if (conf
->update_source
) {
2401 if (peer
->update_source
)
2402 sockunion_free(peer
->update_source
);
2403 if (peer
->update_if
) {
2404 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2405 peer
->update_if
= NULL
;
2407 peer
->update_source
= sockunion_dup(conf
->update_source
);
2408 } else if (conf
->update_if
) {
2409 if (peer
->update_if
)
2410 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2411 if (peer
->update_source
) {
2412 sockunion_free(peer
->update_source
);
2413 peer
->update_source
= NULL
;
2416 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2419 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2422 /* Peer group's remote AS configuration. */
2423 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2426 struct peer_group
*group
;
2428 struct listnode
*node
, *nnode
;
2430 group
= peer_group_lookup(bgp
, group_name
);
2434 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2438 /* When we setup peer-group AS number all peer group member's AS
2439 number must be updated to same number. */
2440 peer_as_change(group
->conf
, *as
, as_type
);
2442 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2443 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2444 || (peer
->as_type
!= as_type
))
2445 peer_as_change(peer
, *as
, as_type
);
2451 int peer_group_delete(struct peer_group
*group
)
2455 struct prefix
*prefix
;
2457 struct listnode
*node
, *nnode
;
2462 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2463 other
= peer
->doppelganger
;
2465 if (other
&& other
->status
!= Deleted
) {
2466 other
->group
= NULL
;
2470 list_delete_and_null(&group
->peer
);
2472 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2473 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2475 prefix_free(prefix
);
2477 list_delete_and_null(&group
->listen_range
[afi
]);
2480 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2483 bfd_info_free(&(group
->conf
->bfd_info
));
2485 group
->conf
->group
= NULL
;
2486 peer_delete(group
->conf
);
2488 /* Delete from all peer_group list. */
2489 listnode_delete(bgp
->group
, group
);
2491 peer_group_free(group
);
2496 int peer_group_remote_as_delete(struct peer_group
*group
)
2498 struct peer
*peer
, *other
;
2499 struct listnode
*node
, *nnode
;
2501 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2502 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2505 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2506 other
= peer
->doppelganger
;
2510 if (other
&& other
->status
!= Deleted
) {
2511 other
->group
= NULL
;
2515 list_delete_all_node(group
->peer
);
2517 group
->conf
->as
= 0;
2518 group
->conf
->as_type
= AS_UNSPECIFIED
;
2523 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2525 struct prefix
*prefix
;
2526 struct listnode
*node
, *nnode
;
2529 afi
= family2afi(range
->family
);
2531 /* Group needs remote AS configured. */
2532 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2533 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2535 /* Ensure no duplicates. Currently we don't care about overlaps. */
2536 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2537 if (prefix_same(range
, prefix
))
2541 prefix
= prefix_new();
2542 prefix_copy(prefix
, range
);
2543 listnode_add(group
->listen_range
[afi
], prefix
);
2547 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2549 struct prefix
*prefix
, prefix2
;
2550 struct listnode
*node
, *nnode
;
2553 char buf
[PREFIX2STR_BUFFER
];
2555 afi
= family2afi(range
->family
);
2557 /* Identify the listen range. */
2558 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2559 if (prefix_same(range
, prefix
))
2564 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2566 prefix2str(prefix
, buf
, sizeof(buf
));
2568 /* Dispose off any dynamic neighbors that exist due to this listen range
2570 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2571 if (!peer_dynamic_neighbor(peer
))
2574 sockunion2hostprefix(&peer
->su
, &prefix2
);
2575 if (prefix_match(prefix
, &prefix2
)) {
2576 if (bgp_debug_neighbor_events(peer
))
2578 "Deleting dynamic neighbor %s group %s upon "
2579 "delete of listen range %s",
2580 peer
->host
, group
->name
, buf
);
2585 /* Get rid of the listen range */
2586 listnode_delete(group
->listen_range
[afi
], prefix
);
2591 /* Bind specified peer to peer group. */
2592 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2593 struct peer_group
*group
, as_t
*as
)
2595 int first_member
= 0;
2598 int cap_enhe_preset
= 0;
2600 /* Lookup the peer. */
2602 peer
= peer_lookup(bgp
, su
);
2604 /* The peer exist, bind it to the peer-group */
2606 /* When the peer already belongs to a peer-group, check the
2608 if (peer_group_active(peer
)) {
2610 /* The peer is already bound to the peer-group,
2613 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2616 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2619 /* The peer has not specified a remote-as, inherit it from the
2621 if (peer
->as_type
== AS_UNSPECIFIED
) {
2622 peer
->as_type
= group
->conf
->as_type
;
2623 peer
->as
= group
->conf
->as
;
2626 if (!group
->conf
->as
) {
2627 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2628 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2631 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2634 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2638 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2639 cap_enhe_preset
= 1;
2641 peer_group2peer_config_copy(group
, peer
);
2644 * Capability extended-nexthop is enabled for an interface
2646 * default. So, fix that up here.
2648 if (peer
->conf_if
&& cap_enhe_preset
)
2649 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2651 FOREACH_AFI_SAFI (afi
, safi
) {
2652 if (group
->conf
->afc
[afi
][safi
]) {
2653 peer
->afc
[afi
][safi
] = 1;
2655 if (peer_af_find(peer
, afi
, safi
)
2656 || peer_af_create(peer
, afi
, safi
)) {
2657 peer_group2peer_config_copy_af(
2658 group
, peer
, afi
, safi
);
2660 } else if (peer
->afc
[afi
][safi
])
2661 peer_deactivate(peer
, afi
, safi
);
2665 assert(group
&& peer
->group
== group
);
2667 struct listnode
*pn
;
2668 pn
= listnode_lookup(bgp
->peer
, peer
);
2669 list_delete_node(bgp
->peer
, pn
);
2670 peer
->group
= group
;
2671 listnode_add_sort(bgp
->peer
, peer
);
2673 peer
= peer_lock(peer
); /* group->peer list reference */
2674 listnode_add(group
->peer
, peer
);
2678 /* Advertisement-interval reset */
2679 if (!CHECK_FLAG(group
->conf
->config
,
2680 PEER_CONFIG_ROUTEADV
)) {
2681 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2682 group
->conf
->v_routeadv
=
2683 BGP_DEFAULT_IBGP_ROUTEADV
;
2685 group
->conf
->v_routeadv
=
2686 BGP_DEFAULT_EBGP_ROUTEADV
;
2689 /* ebgp-multihop reset */
2690 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2691 group
->conf
->ttl
= MAXTTL
;
2693 /* local-as reset */
2694 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2695 group
->conf
->change_local_as
= 0;
2696 UNSET_FLAG(peer
->flags
,
2697 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2698 UNSET_FLAG(peer
->flags
,
2699 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2703 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2705 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2706 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2707 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2708 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2710 bgp_session_reset(peer
);
2714 /* Create a new peer. */
2716 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2717 && (!group
->conf
->as
)) {
2718 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2721 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2722 group
->conf
->as_type
, 0, 0, group
);
2724 peer
= peer_lock(peer
); /* group->peer list reference */
2725 listnode_add(group
->peer
, peer
);
2727 peer_group2peer_config_copy(group
, peer
);
2729 /* If the peer-group is active for this afi/safi then activate
2731 FOREACH_AFI_SAFI (afi
, safi
) {
2732 if (group
->conf
->afc
[afi
][safi
]) {
2733 peer
->afc
[afi
][safi
] = 1;
2734 peer_af_create(peer
, afi
, safi
);
2735 peer_group2peer_config_copy_af(group
, peer
, afi
,
2737 } else if (peer
->afc
[afi
][safi
])
2738 peer_deactivate(peer
, afi
, safi
);
2741 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2743 /* Set up peer's events and timers. */
2744 if (peer_active(peer
))
2745 bgp_timer_set(peer
);
2751 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2752 struct peer_group
*group
)
2758 if (group
!= peer
->group
)
2759 return BGP_ERR_PEER_GROUP_MISMATCH
;
2761 FOREACH_AFI_SAFI (afi
, safi
) {
2762 if (peer
->afc
[afi
][safi
]) {
2763 peer
->afc
[afi
][safi
] = 0;
2764 peer_af_flag_reset(peer
, afi
, safi
);
2766 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2768 "couldn't delete af structure for peer %s",
2774 assert(listnode_lookup(group
->peer
, peer
));
2775 peer_unlock(peer
); /* peer group list reference */
2776 listnode_delete(group
->peer
, peer
);
2778 other
= peer
->doppelganger
;
2780 if (group
->conf
->as
) {
2782 if (other
&& other
->status
!= Deleted
) {
2785 listnode_delete(group
->peer
, other
);
2787 other
->group
= NULL
;
2793 bgp_bfd_deregister_peer(peer
);
2794 peer_global_config_reset(peer
);
2796 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2797 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2798 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2799 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2801 bgp_session_reset(peer
);
2806 static int bgp_startup_timer_expire(struct thread
*thread
)
2810 bgp
= THREAD_ARG(thread
);
2811 bgp
->t_startup
= NULL
;
2816 /* BGP instance creation by `router bgp' commands. */
2817 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2818 enum bgp_instance_type inst_type
)
2824 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2827 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2828 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2829 zlog_debug("Creating Default VRF, AS %u", *as
);
2831 zlog_debug("Creating %s %s, AS %u",
2832 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2839 bgp
->inst_type
= inst_type
;
2840 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2842 bgp
->peer_self
= peer_new(bgp
);
2843 if (bgp
->peer_self
->host
)
2844 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2845 bgp
->peer_self
->host
=
2846 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2847 if (bgp
->peer_self
->hostname
!= NULL
) {
2848 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2849 bgp
->peer_self
->hostname
= NULL
;
2851 if (cmd_hostname_get())
2852 bgp
->peer_self
->hostname
=
2853 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2855 if (bgp
->peer_self
->domainname
!= NULL
) {
2856 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2857 bgp
->peer_self
->domainname
= NULL
;
2859 if (cmd_domainname_get())
2860 bgp
->peer_self
->domainname
=
2861 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2862 bgp
->peer
= list_new();
2863 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2864 bgp
->peerhash
= hash_create(peer_hash_key_make
,
2867 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2869 bgp
->group
= list_new();
2870 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2872 FOREACH_AFI_SAFI (afi
, safi
) {
2873 bgp
->route
[afi
][safi
] = bgp_table_init(afi
, safi
);
2874 bgp
->aggregate
[afi
][safi
] = bgp_table_init(afi
, safi
);
2875 bgp
->rib
[afi
][safi
] = bgp_table_init(afi
, safi
);
2877 /* Enable maximum-paths */
2878 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2880 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2884 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2885 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2886 bgp
->default_subgroup_pkt_queue_max
=
2887 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2888 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2889 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2890 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2891 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2892 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2893 bgp
->dynamic_neighbors_count
= 0;
2894 #if DFLT_BGP_IMPORT_CHECK
2895 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2897 #if DFLT_BGP_SHOW_HOSTNAME
2898 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2900 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2901 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2903 #if DFLT_BGP_DETERMINISTIC_MED
2904 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2906 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2911 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2912 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2914 assert(bgp
->rfapi_cfg
);
2916 #endif /* ENABLE_BGP_VNC */
2919 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2921 /* TODO - The startup timer needs to be run for the whole of BGP
2923 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2924 bgp
->restart_time
, &bgp
->t_startup
);
2927 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2928 memory_order_relaxed
);
2929 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2930 memory_order_relaxed
);
2931 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2935 update_bgp_group_init(bgp
);
2940 /* Return the "default VRF" instance of BGP. */
2941 struct bgp
*bgp_get_default(void)
2944 struct listnode
*node
, *nnode
;
2946 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2947 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2952 /* Lookup BGP entry. */
2953 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2956 struct listnode
*node
, *nnode
;
2958 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2960 && ((bgp
->name
== NULL
&& name
== NULL
)
2961 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2966 /* Lookup BGP structure by view name. */
2967 struct bgp
*bgp_lookup_by_name(const char *name
)
2970 struct listnode
*node
, *nnode
;
2972 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2973 if ((bgp
->name
== NULL
&& name
== NULL
)
2974 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2979 /* Lookup BGP instance based on VRF id. */
2980 /* Note: Only to be used for incoming messages from Zebra. */
2981 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2985 /* Lookup VRF (in tree) and follow link. */
2986 vrf
= vrf_lookup_by_id(vrf_id
);
2989 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2992 /* Called from VTY commands. */
2993 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
2994 enum bgp_instance_type inst_type
)
2998 /* Multiple instance check. */
2999 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3001 bgp
= bgp_lookup_by_name(name
);
3003 bgp
= bgp_get_default();
3005 /* Already exists. */
3007 if (bgp
->as
!= *as
) {
3009 return BGP_ERR_INSTANCE_MISMATCH
;
3011 if (bgp
->inst_type
!= inst_type
)
3012 return BGP_ERR_INSTANCE_MISMATCH
;
3017 /* BGP instance name can not be specified for single instance.
3020 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3022 /* Get default BGP structure if exists. */
3023 bgp
= bgp_get_default();
3026 if (bgp
->as
!= *as
) {
3028 return BGP_ERR_AS_MISMATCH
;
3035 bgp
= bgp_create(as
, name
, inst_type
);
3036 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3037 bgp_address_init(bgp
);
3038 bgp_tip_hash_init(bgp
);
3042 bgp
->t_rmap_def_originate_eval
= NULL
;
3044 /* Create BGP server socket, if first instance. */
3045 if (list_isempty(bm
->bgp
) && !bgp_option_check(BGP_OPT_NO_LISTEN
)) {
3046 if (bgp_socket(bm
->port
, bm
->address
) < 0)
3047 return BGP_ERR_INVALID_VALUE
;
3050 listnode_add(bm
->bgp
, bgp
);
3052 /* If Default instance or VRF, link to the VRF structure, if present. */
3053 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3054 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3057 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3059 bgp_vrf_link(bgp
, vrf
);
3062 /* Register with Zebra, if needed */
3063 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3064 bgp_zebra_instance_register(bgp
);
3071 * Make BGP instance "up". Applies only to VRFs (non-default) and
3072 * implies the VRF has been learnt from Zebra.
3074 void bgp_instance_up(struct bgp
*bgp
)
3077 struct listnode
*node
, *next
;
3079 /* Register with zebra. */
3080 bgp_zebra_instance_register(bgp
);
3082 /* Kick off any peers that may have been configured. */
3083 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3084 if (!BGP_PEER_START_SUPPRESSED(peer
))
3085 BGP_EVENT_ADD(peer
, BGP_Start
);
3088 /* Process any networks that have been configured. */
3089 bgp_static_add(bgp
);
3093 * Make BGP instance "down". Applies only to VRFs (non-default) and
3094 * implies the VRF has been deleted by Zebra.
3096 void bgp_instance_down(struct bgp
*bgp
)
3099 struct listnode
*node
;
3100 struct listnode
*next
;
3103 if (bgp
->t_rmap_def_originate_eval
) {
3104 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3105 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3109 /* Bring down peers, so corresponding routes are purged. */
3110 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3111 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3112 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3113 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3115 bgp_session_reset(peer
);
3118 /* Purge network and redistributed routes. */
3119 bgp_purge_static_redist_routes(bgp
);
3121 /* Cleanup registered nexthops (flags) */
3122 bgp_cleanup_nexthops(bgp
);
3125 /* Delete BGP instance. */
3126 int bgp_delete(struct bgp
*bgp
)
3129 struct peer_group
*group
;
3130 struct listnode
*node
, *next
;
3135 THREAD_OFF(bgp
->t_startup
);
3137 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3138 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3139 zlog_debug("Deleting Default VRF");
3141 zlog_debug("Deleting %s %s",
3142 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3149 if (bgp
->t_rmap_def_originate_eval
) {
3150 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3151 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3155 /* Inform peers we're going down. */
3156 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3157 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3158 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3159 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3162 /* Delete static routes (networks). */
3163 bgp_static_delete(bgp
);
3165 /* Unset redistribution. */
3166 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3167 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3168 if (i
!= ZEBRA_ROUTE_BGP
)
3169 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3171 /* Free peers and peer-groups. */
3172 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3173 peer_group_delete(group
);
3175 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3178 if (bgp
->peer_self
) {
3179 peer_delete(bgp
->peer_self
);
3180 bgp
->peer_self
= NULL
;
3183 update_bgp_group_free(bgp
);
3185 /* TODO - Other memory may need to be freed - e.g., NHT */
3190 bgp_cleanup_routes(bgp
);
3192 /* Remove visibility via the master list - there may however still be
3193 * routes to be processed still referencing the struct bgp.
3195 listnode_delete(bm
->bgp
, bgp
);
3196 if (list_isempty(bm
->bgp
))
3199 /* Deregister from Zebra, if needed */
3200 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3201 bgp_zebra_instance_deregister(bgp
);
3203 /* Free interfaces in this instance. */
3206 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3208 bgp_vrf_unlink(bgp
, vrf
);
3210 thread_master_free_unused(bm
->master
);
3211 bgp_unlock(bgp
); /* initial reference */
3216 void bgp_free(struct bgp
*bgp
)
3220 struct bgp_table
*table
;
3221 struct bgp_node
*rn
;
3222 struct bgp_rmap
*rmap
;
3226 list_delete_and_null(&bgp
->group
);
3227 list_delete_and_null(&bgp
->peer
);
3229 if (bgp
->peerhash
) {
3230 hash_free(bgp
->peerhash
);
3231 bgp
->peerhash
= NULL
;
3234 FOREACH_AFI_SAFI (afi
, safi
) {
3235 /* Special handling for 2-level routing tables. */
3236 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3237 || safi
== SAFI_EVPN
) {
3238 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3239 rn
= bgp_route_next(rn
)) {
3240 table
= (struct bgp_table
*)rn
->info
;
3241 bgp_table_finish(&table
);
3244 if (bgp
->route
[afi
][safi
])
3245 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3246 if (bgp
->aggregate
[afi
][safi
])
3247 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3248 if (bgp
->rib
[afi
][safi
])
3249 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3250 rmap
= &bgp
->table_map
[afi
][safi
];
3252 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3255 bgp_scan_finish(bgp
);
3256 bgp_address_destroy(bgp
);
3257 bgp_tip_hash_destroy(bgp
);
3259 bgp_evpn_cleanup(bgp
);
3262 XFREE(MTYPE_BGP
, bgp
->name
);
3264 XFREE(MTYPE_BGP
, bgp
);
3267 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3270 struct listnode
*node
, *nnode
;
3276 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3277 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3278 && !CHECK_FLAG(peer
->sflags
,
3279 PEER_STATUS_ACCEPT_PEER
))
3281 } else if (bm
->bgp
!= NULL
) {
3282 struct listnode
*bgpnode
, *nbgpnode
;
3284 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3285 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3287 && !strcmp(peer
->conf_if
, conf_if
)
3288 && !CHECK_FLAG(peer
->sflags
,
3289 PEER_STATUS_ACCEPT_PEER
))
3295 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3298 struct listnode
*node
, *nnode
;
3304 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3305 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3306 && !CHECK_FLAG(peer
->sflags
,
3307 PEER_STATUS_ACCEPT_PEER
))
3309 } else if (bm
->bgp
!= NULL
) {
3310 struct listnode
*bgpnode
, *nbgpnode
;
3312 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3313 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3315 && !strcmp(peer
->hostname
, hostname
)
3316 && !CHECK_FLAG(peer
->sflags
,
3317 PEER_STATUS_ACCEPT_PEER
))
3323 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3325 struct peer
*peer
= NULL
;
3326 struct peer tmp_peer
;
3328 memset(&tmp_peer
, 0, sizeof(struct peer
));
3331 * We do not want to find the doppelganger peer so search for the peer
3333 * the hash that has PEER_FLAG_CONFIG_NODE
3335 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3340 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3341 } else if (bm
->bgp
!= NULL
) {
3342 struct listnode
*bgpnode
, *nbgpnode
;
3344 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3345 /* Skip VRFs, this function will not be invoked without
3347 * when examining VRFs.
3349 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3352 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3362 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3363 union sockunion
*su
,
3364 struct peer_group
*group
)
3370 /* Create peer first; we've already checked group config is valid. */
3371 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3372 group
->conf
->as_type
, 0, 0, group
);
3377 peer
= peer_lock(peer
);
3378 listnode_add(group
->peer
, peer
);
3380 peer_group2peer_config_copy(group
, peer
);
3383 * Bind peer for all AFs configured for the group. We don't call
3384 * peer_group_bind as that is sub-optimal and does some stuff we don't
3387 FOREACH_AFI_SAFI (afi
, safi
) {
3388 if (!group
->conf
->afc
[afi
][safi
])
3390 peer
->afc
[afi
][safi
] = 1;
3392 if (!peer_af_find(peer
, afi
, safi
))
3393 peer_af_create(peer
, afi
, safi
);
3395 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3398 /* Mark as dynamic, but also as a "config node" for other things to
3400 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3401 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3407 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3408 struct prefix
*prefix
)
3410 struct listnode
*node
, *nnode
;
3411 struct prefix
*range
;
3414 afi
= family2afi(prefix
->family
);
3416 if (group
->listen_range
[afi
])
3417 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3419 if (prefix_match(range
, prefix
))
3426 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3427 struct prefix
**listen_range
)
3429 struct prefix
*range
= NULL
;
3430 struct peer_group
*group
= NULL
;
3431 struct listnode
*node
, *nnode
;
3433 *listen_range
= NULL
;
3435 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3436 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3439 } else if (bm
->bgp
!= NULL
) {
3440 struct listnode
*bgpnode
, *nbgpnode
;
3442 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3443 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3444 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3450 *listen_range
= range
;
3451 return (group
&& range
) ? group
: NULL
;
3454 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3456 struct peer_group
*group
;
3459 struct prefix prefix
;
3460 struct prefix
*listen_range
;
3462 char buf
[PREFIX2STR_BUFFER
];
3463 char buf1
[PREFIX2STR_BUFFER
];
3465 sockunion2hostprefix(su
, &prefix
);
3467 /* See if incoming connection matches a configured listen range. */
3468 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3479 prefix2str(&prefix
, buf
, sizeof(buf
));
3480 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3482 if (bgp_debug_neighbor_events(NULL
))
3484 "Dynamic Neighbor %s matches group %s listen range %s",
3485 buf
, group
->name
, buf1
);
3487 /* Are we within the listen limit? */
3488 dncount
= gbgp
->dynamic_neighbors_count
;
3490 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3491 if (bgp_debug_neighbor_events(NULL
))
3492 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3493 inet_sutop(su
, buf
),
3494 gbgp
->dynamic_neighbors_limit
);
3498 /* Ensure group is not disabled. */
3499 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3500 if (bgp_debug_neighbor_events(NULL
))
3502 "Dynamic Neighbor %s rejected - group %s disabled",
3507 /* Check that at least one AF is activated for the group. */
3508 if (!peer_group_af_configured(group
)) {
3509 if (bgp_debug_neighbor_events(NULL
))
3511 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3516 /* Create dynamic peer and bind to associated group. */
3517 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3520 gbgp
->dynamic_neighbors_count
= ++dncount
;
3522 if (bgp_debug_neighbor_events(peer
))
3523 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3524 peer
->host
, group
->name
, dncount
);
3529 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3532 if (peer
->group
&& peer
->group
->bgp
) {
3533 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3535 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3537 if (bgp_debug_neighbor_events(peer
))
3538 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3539 peer
->group
->name
, dncount
);
3543 /* If peer is configured at least one address family return 1. */
3544 int peer_active(struct peer
*peer
)
3546 if (BGP_PEER_SU_UNSPEC(peer
))
3548 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3549 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3550 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3551 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3552 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3553 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3554 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3555 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3556 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3561 /* If peer is negotiated at least one address family return 1. */
3562 int peer_active_nego(struct peer
*peer
)
3564 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3565 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3566 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3567 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3568 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3569 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3570 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3571 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3572 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3573 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3574 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3579 /* peer_flag_change_type. */
3580 enum peer_change_type
{
3583 peer_change_reset_in
,
3584 peer_change_reset_out
,
3587 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3588 enum peer_change_type type
)
3590 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3593 if (peer
->status
!= Established
)
3596 if (type
== peer_change_reset
) {
3597 /* If we're resetting session, we've to delete both peer struct
3599 if ((peer
->doppelganger
)
3600 && (peer
->doppelganger
->status
!= Deleted
)
3601 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3602 PEER_FLAG_CONFIG_NODE
)))
3603 peer_delete(peer
->doppelganger
);
3605 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3606 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3607 } else if (type
== peer_change_reset_in
) {
3608 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3609 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3610 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3612 if ((peer
->doppelganger
)
3613 && (peer
->doppelganger
->status
!= Deleted
)
3614 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3615 PEER_FLAG_CONFIG_NODE
)))
3616 peer_delete(peer
->doppelganger
);
3618 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3619 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3621 } else if (type
== peer_change_reset_out
) {
3622 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3623 bgp_announce_route(peer
, afi
, safi
);
3627 struct peer_flag_action
{
3631 /* This flag can be set for peer-group member. */
3632 u_char not_for_member
;
3634 /* Action when the flag is changed. */
3635 enum peer_change_type type
;
3637 /* Peer down cause */
3641 static const struct peer_flag_action peer_flag_action_list
[] = {
3642 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3643 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3644 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3645 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3646 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3647 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3648 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3649 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3652 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3653 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3654 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3655 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3656 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3657 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3658 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3659 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3660 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3661 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3662 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3663 // PEER_FLAG_DEFAULT_ORIGINATE
3664 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3665 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3666 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3667 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3668 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3669 // PEER_FLAG_MAX_PREFIX
3670 // PEER_FLAG_MAX_PREFIX_WARNING
3671 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3672 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3673 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3674 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3675 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3676 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3677 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3678 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3679 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3682 /* Proper action set. */
3683 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3684 int size
, struct peer_flag_action
*action
,
3691 const struct peer_flag_action
*match
= NULL
;
3693 /* Check peer's frag action. */
3694 for (i
= 0; i
< size
; i
++) {
3695 match
= &action_list
[i
];
3697 if (match
->flag
== 0)
3700 if (match
->flag
& flag
) {
3703 if (match
->type
== peer_change_reset_in
)
3705 if (match
->type
== peer_change_reset_out
)
3707 if (match
->type
== peer_change_reset
) {
3711 if (match
->not_for_member
)
3712 action
->not_for_member
= 1;
3716 /* Set peer clear type. */
3717 if (reset_in
&& reset_out
)
3718 action
->type
= peer_change_reset
;
3720 action
->type
= peer_change_reset_in
;
3722 action
->type
= peer_change_reset_out
;
3724 action
->type
= peer_change_none
;
3729 static void peer_flag_modify_action(struct peer
*peer
, u_int32_t flag
)
3731 if (flag
== PEER_FLAG_SHUTDOWN
) {
3732 if (CHECK_FLAG(peer
->flags
, flag
)) {
3733 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3734 peer_nsf_stop(peer
);
3736 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3737 if (peer
->t_pmax_restart
) {
3738 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3739 if (bgp_debug_neighbor_events(peer
))
3741 "%s Maximum-prefix restart timer canceled",
3745 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3746 peer_nsf_stop(peer
);
3748 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3749 char *msg
= peer
->tx_shutdown_message
;
3752 if (!msg
&& peer_group_active(peer
))
3753 msg
= peer
->group
->conf
3754 ->tx_shutdown_message
;
3755 msglen
= msg
? strlen(msg
) : 0;
3763 memcpy(msgbuf
+ 1, msg
, msglen
);
3765 bgp_notify_send_with_data(
3766 peer
, BGP_NOTIFY_CEASE
,
3767 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3768 msgbuf
, msglen
+ 1);
3771 peer
, BGP_NOTIFY_CEASE
,
3772 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3774 bgp_session_reset(peer
);
3776 peer
->v_start
= BGP_INIT_START_TIMER
;
3777 BGP_EVENT_ADD(peer
, BGP_Stop
);
3779 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3780 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3781 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3782 else if (flag
== PEER_FLAG_PASSIVE
)
3783 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3784 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3785 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3787 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3788 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3790 bgp_session_reset(peer
);
3793 /* Change specified peer flag. */
3794 static int peer_flag_modify(struct peer
*peer
, u_int32_t flag
, int set
)
3798 struct peer_group
*group
;
3799 struct peer
*tmp_peer
;
3800 struct listnode
*node
, *nnode
;
3801 struct peer_flag_action action
;
3803 memset(&action
, 0, sizeof(struct peer_flag_action
));
3804 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3806 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3809 /* No flag action is found. */
3811 return BGP_ERR_INVALID_FLAG
;
3813 /* When unset the peer-group member's flag we have to check
3814 peer-group configuration. */
3815 if (!set
&& peer_group_active(peer
))
3816 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3817 if (flag
== PEER_FLAG_SHUTDOWN
)
3818 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3821 /* Flag conflict check. */
3822 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3823 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3824 return BGP_ERR_PEER_FLAG_CONFLICT
;
3826 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3827 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3829 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3834 SET_FLAG(peer
->flags
, flag
);
3836 UNSET_FLAG(peer
->flags
, flag
);
3838 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3839 if (action
.type
== peer_change_reset
)
3840 peer_flag_modify_action(peer
, flag
);
3845 /* peer-group member updates. */
3846 group
= peer
->group
;
3848 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3850 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
3853 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
3857 SET_FLAG(tmp_peer
->flags
, flag
);
3859 UNSET_FLAG(tmp_peer
->flags
, flag
);
3861 if (action
.type
== peer_change_reset
)
3862 peer_flag_modify_action(tmp_peer
, flag
);
3867 int peer_flag_set(struct peer
*peer
, u_int32_t flag
)
3869 return peer_flag_modify(peer
, flag
, 1);
3872 int peer_flag_unset(struct peer
*peer
, u_int32_t flag
)
3874 return peer_flag_modify(peer
, flag
, 0);
3877 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3878 u_int32_t flag
, int set
)
3882 struct listnode
*node
, *nnode
;
3883 struct peer_group
*group
;
3884 struct peer_flag_action action
;
3885 struct peer
*tmp_peer
;
3887 int addpath_tx_used
;
3889 memset(&action
, 0, sizeof(struct peer_flag_action
));
3890 size
= sizeof peer_af_flag_action_list
3891 / sizeof(struct peer_flag_action
);
3893 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3896 /* No flag action is found. */
3898 return BGP_ERR_INVALID_FLAG
;
3900 /* Special check for reflector client. */
3901 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3902 && peer_sort(peer
) != BGP_PEER_IBGP
)
3903 return BGP_ERR_NOT_INTERNAL_PEER
;
3905 /* Special check for remove-private-AS. */
3906 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3907 && peer_sort(peer
) == BGP_PEER_IBGP
)
3908 return BGP_ERR_REMOVE_PRIVATE_AS
;
3910 /* as-override is not allowed for IBGP peers */
3911 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3912 return BGP_ERR_AS_OVERRIDE
;
3914 /* When current flag configuration is same as requested one. */
3915 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3916 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
3918 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
3923 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3925 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3927 /* Execute action when peer is established. */
3928 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
3929 && peer
->status
== Established
) {
3930 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3931 bgp_clear_adj_in(peer
, afi
, safi
);
3933 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3934 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
3935 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
3936 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
3937 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
3938 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3939 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
3940 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3942 peer_change_action(peer
, afi
, safi
, action
.type
);
3946 /* Peer group member updates. */
3947 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3948 group
= peer
->group
;
3950 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3952 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
3957 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
3961 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3963 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3965 if (tmp_peer
->status
== Established
) {
3966 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3967 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
3969 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3970 tmp_peer
->last_reset
=
3971 PEER_DOWN_RR_CLIENT_CHANGE
;
3973 == PEER_FLAG_RSERVER_CLIENT
)
3974 tmp_peer
->last_reset
=
3975 PEER_DOWN_RS_CLIENT_CHANGE
;
3977 == PEER_FLAG_ORF_PREFIX_SM
)
3978 tmp_peer
->last_reset
=
3979 PEER_DOWN_CAPABILITY_CHANGE
;
3981 == PEER_FLAG_ORF_PREFIX_RM
)
3982 tmp_peer
->last_reset
=
3983 PEER_DOWN_CAPABILITY_CHANGE
;
3985 peer_change_action(tmp_peer
, afi
, safi
,
3992 /* Track if addpath TX is in use */
3993 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
3994 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
3996 addpath_tx_used
= 0;
3999 addpath_tx_used
= 1;
4001 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4002 if (!bgp_flag_check(
4003 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4005 "%s: enabling bgp deterministic-med, this is required"
4006 " for addpath-tx-bestpath-per-AS",
4010 BGP_FLAG_DETERMINISTIC_MED
);
4011 bgp_recalculate_all_bestpaths(bgp
);
4015 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4017 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4018 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4020 tmp_peer
->af_flags
[afi
][safi
],
4021 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4022 addpath_tx_used
= 1;
4028 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4034 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int32_t flag
)
4036 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4039 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
4042 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4046 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4048 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4049 peer
->tx_shutdown_message
=
4050 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4054 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4056 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4061 /* EBGP multihop configuration. */
4062 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4064 struct peer_group
*group
;
4065 struct listnode
*node
, *nnode
;
4068 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4071 /* see comment in peer_ttl_security_hops_set() */
4072 if (ttl
!= MAXTTL
) {
4073 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4074 group
= peer
->group
;
4075 if (group
->conf
->gtsm_hops
!= 0)
4076 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4078 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4080 if (peer1
->sort
== BGP_PEER_IBGP
)
4083 if (peer1
->gtsm_hops
!= 0)
4084 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4087 if (peer
->gtsm_hops
!= 0)
4088 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4094 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4095 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4096 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4097 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4098 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4100 bgp_session_reset(peer
);
4103 group
= peer
->group
;
4104 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4105 if (peer
->sort
== BGP_PEER_IBGP
)
4108 peer
->ttl
= group
->conf
->ttl
;
4110 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4111 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4112 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4114 bgp_session_reset(peer
);
4120 int peer_ebgp_multihop_unset(struct peer
*peer
)
4122 struct peer_group
*group
;
4123 struct listnode
*node
, *nnode
;
4125 if (peer
->sort
== BGP_PEER_IBGP
)
4128 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4129 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4131 if (peer_group_active(peer
))
4132 peer
->ttl
= peer
->group
->conf
->ttl
;
4136 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4137 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4138 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4139 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4141 bgp_session_reset(peer
);
4143 group
= peer
->group
;
4144 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4145 if (peer
->sort
== BGP_PEER_IBGP
)
4150 if (peer
->fd
>= 0) {
4151 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4153 peer
, BGP_NOTIFY_CEASE
,
4154 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4156 bgp_session_reset(peer
);
4163 /* Neighbor description. */
4164 int peer_description_set(struct peer
*peer
, const char *desc
)
4167 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4169 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4174 int peer_description_unset(struct peer
*peer
)
4177 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4184 /* Neighbor update-source. */
4185 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4187 struct peer_group
*group
;
4188 struct listnode
*node
, *nnode
;
4190 if (peer
->update_if
) {
4191 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4192 && strcmp(peer
->update_if
, ifname
) == 0)
4195 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4196 peer
->update_if
= NULL
;
4199 if (peer
->update_source
) {
4200 sockunion_free(peer
->update_source
);
4201 peer
->update_source
= NULL
;
4204 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4206 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4207 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4208 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4209 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4210 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4212 bgp_session_reset(peer
);
4216 /* peer-group member updates. */
4217 group
= peer
->group
;
4218 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4219 if (peer
->update_if
) {
4220 if (strcmp(peer
->update_if
, ifname
) == 0)
4223 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4224 peer
->update_if
= NULL
;
4227 if (peer
->update_source
) {
4228 sockunion_free(peer
->update_source
);
4229 peer
->update_source
= NULL
;
4232 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4234 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4235 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4236 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4237 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4239 bgp_session_reset(peer
);
4244 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4246 struct peer_group
*group
;
4247 struct listnode
*node
, *nnode
;
4249 if (peer
->update_source
) {
4250 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4251 && sockunion_cmp(peer
->update_source
, su
) == 0)
4253 sockunion_free(peer
->update_source
);
4254 peer
->update_source
= NULL
;
4257 if (peer
->update_if
) {
4258 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4259 peer
->update_if
= NULL
;
4262 peer
->update_source
= sockunion_dup(su
);
4264 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4265 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4266 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4267 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4268 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4270 bgp_session_reset(peer
);
4274 /* peer-group member updates. */
4275 group
= peer
->group
;
4276 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4277 if (peer
->update_source
) {
4278 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4280 sockunion_free(peer
->update_source
);
4281 peer
->update_source
= NULL
;
4284 if (peer
->update_if
) {
4285 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4286 peer
->update_if
= NULL
;
4289 peer
->update_source
= sockunion_dup(su
);
4291 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4292 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4293 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4294 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4296 bgp_session_reset(peer
);
4301 int peer_update_source_unset(struct peer
*peer
)
4303 union sockunion
*su
;
4304 struct peer_group
*group
;
4305 struct listnode
*node
, *nnode
;
4307 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4308 && !peer
->update_if
)
4311 if (peer
->update_source
) {
4312 sockunion_free(peer
->update_source
);
4313 peer
->update_source
= NULL
;
4315 if (peer
->update_if
) {
4316 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4317 peer
->update_if
= NULL
;
4320 if (peer_group_active(peer
)) {
4321 group
= peer
->group
;
4323 if (group
->conf
->update_source
) {
4324 su
= sockunion_dup(group
->conf
->update_source
);
4325 peer
->update_source
= su
;
4326 } else if (group
->conf
->update_if
)
4327 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4328 group
->conf
->update_if
);
4331 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4332 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4333 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4334 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4335 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4337 bgp_session_reset(peer
);
4341 /* peer-group member updates. */
4342 group
= peer
->group
;
4343 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4344 if (!peer
->update_source
&& !peer
->update_if
)
4347 if (peer
->update_source
) {
4348 sockunion_free(peer
->update_source
);
4349 peer
->update_source
= NULL
;
4352 if (peer
->update_if
) {
4353 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4354 peer
->update_if
= NULL
;
4357 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4358 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4359 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4360 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4362 bgp_session_reset(peer
);
4367 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4370 struct peer_group
*group
;
4371 struct listnode
*node
, *nnode
;
4373 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4374 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4376 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4377 SET_FLAG(peer
->af_flags
[afi
][safi
],
4378 PEER_FLAG_DEFAULT_ORIGINATE
);
4381 if (peer
->default_rmap
[afi
][safi
].name
)
4382 XFREE(MTYPE_ROUTE_MAP_NAME
,
4383 peer
->default_rmap
[afi
][safi
].name
);
4384 peer
->default_rmap
[afi
][safi
].name
=
4385 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4386 peer
->default_rmap
[afi
][safi
].map
=
4387 route_map_lookup_by_name(rmap
);
4391 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4392 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4393 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4394 bgp_default_originate(peer
, afi
, safi
, 0);
4395 bgp_announce_route(peer
, afi
, safi
);
4400 /* peer-group member updates. */
4401 group
= peer
->group
;
4402 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4403 SET_FLAG(peer
->af_flags
[afi
][safi
],
4404 PEER_FLAG_DEFAULT_ORIGINATE
);
4407 if (peer
->default_rmap
[afi
][safi
].name
)
4408 XFREE(MTYPE_ROUTE_MAP_NAME
,
4409 peer
->default_rmap
[afi
][safi
].name
);
4410 peer
->default_rmap
[afi
][safi
].name
=
4411 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4412 peer
->default_rmap
[afi
][safi
].map
=
4413 route_map_lookup_by_name(rmap
);
4416 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4417 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4418 bgp_default_originate(peer
, afi
, safi
, 0);
4419 bgp_announce_route(peer
, afi
, safi
);
4425 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4427 struct peer_group
*group
;
4428 struct listnode
*node
, *nnode
;
4430 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4431 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4432 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4433 PEER_FLAG_DEFAULT_ORIGINATE
);
4435 if (peer
->default_rmap
[afi
][safi
].name
)
4436 XFREE(MTYPE_ROUTE_MAP_NAME
,
4437 peer
->default_rmap
[afi
][safi
].name
);
4438 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4439 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4442 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4443 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4444 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4445 bgp_default_originate(peer
, afi
, safi
, 1);
4446 bgp_announce_route(peer
, afi
, safi
);
4451 /* peer-group member updates. */
4452 group
= peer
->group
;
4453 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4454 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4455 PEER_FLAG_DEFAULT_ORIGINATE
);
4457 if (peer
->default_rmap
[afi
][safi
].name
)
4458 XFREE(MTYPE_ROUTE_MAP_NAME
,
4459 peer
->default_rmap
[afi
][safi
].name
);
4460 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4461 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4463 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4464 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4465 bgp_default_originate(peer
, afi
, safi
, 1);
4466 bgp_announce_route(peer
, afi
, safi
);
4472 int peer_port_set(struct peer
*peer
, u_int16_t port
)
4478 int peer_port_unset(struct peer
*peer
)
4480 peer
->port
= BGP_PORT_DEFAULT
;
4485 * Helper function that is called after the name of the policy
4486 * being used by a peer has changed (AF specific). Automatically
4487 * initiates inbound or outbound processing as needed.
4489 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4493 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4494 if (peer
->status
== Established
)
4495 bgp_announce_route(peer
, afi
, safi
);
4497 if (peer
->status
!= Established
)
4500 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4501 PEER_FLAG_SOFT_RECONFIG
))
4502 bgp_soft_reconfig_in(peer
, afi
, safi
);
4503 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4504 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4505 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4510 /* neighbor weight. */
4511 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int16_t weight
)
4513 struct peer_group
*group
;
4514 struct listnode
*node
, *nnode
;
4516 if (peer
->weight
[afi
][safi
] != weight
) {
4517 peer
->weight
[afi
][safi
] = weight
;
4518 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4519 peer_on_policy_change(peer
, afi
, safi
, 0);
4522 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4525 /* peer-group member updates. */
4526 group
= peer
->group
;
4527 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4528 if (peer
->weight
[afi
][safi
] != weight
) {
4529 peer
->weight
[afi
][safi
] = weight
;
4530 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4531 peer_on_policy_change(peer
, afi
, safi
, 0);
4537 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4539 struct peer_group
*group
;
4540 struct listnode
*node
, *nnode
;
4542 /* not the peer-group itself but a peer in a peer-group */
4543 if (peer_group_active(peer
)) {
4544 group
= peer
->group
;
4546 /* inherit weight from the peer-group */
4547 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4548 PEER_FLAG_WEIGHT
)) {
4549 peer
->weight
[afi
][safi
] =
4550 group
->conf
->weight
[afi
][safi
];
4551 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4552 peer_on_policy_change(peer
, afi
, safi
, 0);
4554 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4555 PEER_FLAG_WEIGHT
)) {
4556 peer
->weight
[afi
][safi
] = 0;
4557 peer_af_flag_unset(peer
, afi
, safi
,
4559 peer_on_policy_change(peer
, afi
, safi
, 0);
4565 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4566 peer
->weight
[afi
][safi
] = 0;
4567 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4568 peer_on_policy_change(peer
, afi
, safi
, 0);
4571 /* peer-group member updates. */
4572 group
= peer
->group
;
4575 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4577 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4578 PEER_FLAG_WEIGHT
)) {
4579 peer
->weight
[afi
][safi
] = 0;
4580 peer_af_flag_unset(peer
, afi
, safi
,
4582 peer_on_policy_change(peer
, afi
, safi
,
4591 int peer_timers_set(struct peer
*peer
, u_int32_t keepalive
, u_int32_t holdtime
)
4593 struct peer_group
*group
;
4594 struct listnode
*node
, *nnode
;
4596 /* keepalive value check. */
4597 if (keepalive
> 65535)
4598 return BGP_ERR_INVALID_VALUE
;
4600 /* Holdtime value check. */
4601 if (holdtime
> 65535)
4602 return BGP_ERR_INVALID_VALUE
;
4604 /* Holdtime value must be either 0 or greater than 3. */
4605 if (holdtime
< 3 && holdtime
!= 0)
4606 return BGP_ERR_INVALID_VALUE
;
4608 /* Set value to the configuration. */
4609 peer
->holdtime
= holdtime
;
4610 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4612 /* First work on real peers with timers */
4613 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4614 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4615 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4617 /* Now work on the peer-group timers */
4618 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4620 /* peer-group member updates. */
4621 group
= peer
->group
;
4622 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4623 /* Skip peers that have their own timers */
4624 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4627 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4628 peer
->holdtime
= group
->conf
->holdtime
;
4629 peer
->keepalive
= group
->conf
->keepalive
;
4636 int peer_timers_unset(struct peer
*peer
)
4638 struct peer_group
*group
;
4639 struct listnode
*node
, *nnode
;
4641 /* First work on real peers vs the peer-group */
4642 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4643 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4644 peer
->keepalive
= 0;
4647 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4648 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4649 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4650 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4653 /* peer-group member updates. */
4654 group
= peer
->group
;
4655 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4656 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4657 UNSET_FLAG(peer
->config
,
4658 PEER_GROUP_CONFIG_TIMER
);
4660 peer
->keepalive
= 0;
4664 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4665 group
->conf
->holdtime
= 0;
4666 group
->conf
->keepalive
= 0;
4672 int peer_timers_connect_set(struct peer
*peer
, u_int32_t connect
)
4674 struct peer_group
*group
;
4675 struct listnode
*node
, *nnode
;
4677 if (connect
> 65535)
4678 return BGP_ERR_INVALID_VALUE
;
4680 /* Set value to the configuration. */
4681 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4682 peer
->connect
= connect
;
4684 /* Set value to timer setting. */
4685 peer
->v_connect
= connect
;
4687 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4690 /* peer-group member updates. */
4691 group
= peer
->group
;
4692 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4693 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4694 peer
->connect
= connect
;
4695 peer
->v_connect
= connect
;
4700 int peer_timers_connect_unset(struct peer
*peer
)
4702 struct peer_group
*group
;
4703 struct listnode
*node
, *nnode
;
4705 /* Clear configuration. */
4706 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4709 /* Set timer setting to default value. */
4710 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4712 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4715 /* peer-group member updates. */
4716 group
= peer
->group
;
4717 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4718 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4720 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4725 int peer_advertise_interval_set(struct peer
*peer
, u_int32_t routeadv
)
4727 struct peer_group
*group
;
4728 struct listnode
*node
, *nnode
;
4731 return BGP_ERR_INVALID_VALUE
;
4733 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4734 peer
->routeadv
= routeadv
;
4735 peer
->v_routeadv
= routeadv
;
4737 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4738 update_group_adjust_peer_afs(peer
);
4739 if (peer
->status
== Established
)
4740 bgp_announce_route_all(peer
);
4744 /* peer-group member updates. */
4745 group
= peer
->group
;
4746 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4747 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4748 peer
->routeadv
= routeadv
;
4749 peer
->v_routeadv
= routeadv
;
4750 update_group_adjust_peer_afs(peer
);
4751 if (peer
->status
== Established
)
4752 bgp_announce_route_all(peer
);
4758 int peer_advertise_interval_unset(struct peer
*peer
)
4760 struct peer_group
*group
;
4761 struct listnode
*node
, *nnode
;
4763 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4766 if (peer
->sort
== BGP_PEER_IBGP
)
4767 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4769 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4771 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4772 update_group_adjust_peer_afs(peer
);
4773 if (peer
->status
== Established
)
4774 bgp_announce_route_all(peer
);
4778 /* peer-group member updates. */
4779 group
= peer
->group
;
4780 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4781 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4784 if (peer
->sort
== BGP_PEER_IBGP
)
4785 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4787 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4789 update_group_adjust_peer_afs(peer
);
4790 if (peer
->status
== Established
)
4791 bgp_announce_route_all(peer
);
4797 /* neighbor interface */
4798 void peer_interface_set(struct peer
*peer
, const char *str
)
4801 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4802 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4805 void peer_interface_unset(struct peer
*peer
)
4808 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4809 peer
->ifname
= NULL
;
4813 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4814 int allow_num
, int origin
)
4816 struct peer_group
*group
;
4817 struct listnode
*node
, *nnode
;
4820 if (peer
->allowas_in
[afi
][safi
]
4821 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4822 PEER_FLAG_ALLOWAS_IN
)
4823 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4824 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4825 peer
->allowas_in
[afi
][safi
] = 0;
4826 peer_af_flag_unset(peer
, afi
, safi
,
4827 PEER_FLAG_ALLOWAS_IN
);
4828 peer_af_flag_set(peer
, afi
, safi
,
4829 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4830 peer_on_policy_change(peer
, afi
, safi
, 0);
4833 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4836 group
= peer
->group
;
4837 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4838 if (peer
->allowas_in
[afi
][safi
]
4839 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4840 PEER_FLAG_ALLOWAS_IN
)
4841 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4842 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4843 peer
->allowas_in
[afi
][safi
] = 0;
4844 peer_af_flag_unset(peer
, afi
, safi
,
4845 PEER_FLAG_ALLOWAS_IN
);
4846 peer_af_flag_set(peer
, afi
, safi
,
4847 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4848 peer_on_policy_change(peer
, afi
, safi
, 0);
4852 if (allow_num
< 1 || allow_num
> 10)
4853 return BGP_ERR_INVALID_VALUE
;
4855 if (peer
->allowas_in
[afi
][safi
] != allow_num
4856 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4857 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4858 peer
->allowas_in
[afi
][safi
] = allow_num
;
4859 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4860 peer_af_flag_unset(peer
, afi
, safi
,
4861 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4862 peer_on_policy_change(peer
, afi
, safi
, 0);
4865 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4868 group
= peer
->group
;
4869 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4870 if (peer
->allowas_in
[afi
][safi
] != allow_num
4871 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4872 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4873 peer
->allowas_in
[afi
][safi
] = allow_num
;
4874 peer_af_flag_set(peer
, afi
, safi
,
4875 PEER_FLAG_ALLOWAS_IN
);
4876 peer_af_flag_unset(peer
, afi
, safi
,
4877 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4878 peer_on_policy_change(peer
, afi
, safi
, 0);
4886 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4888 struct peer_group
*group
;
4889 struct peer
*tmp_peer
;
4890 struct listnode
*node
, *nnode
;
4892 /* If this is a peer-group we must first clear the flags for all of the
4893 * peer-group members
4895 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4896 group
= peer
->group
;
4897 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4898 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4899 PEER_FLAG_ALLOWAS_IN
)
4900 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4901 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4902 tmp_peer
->allowas_in
[afi
][safi
] = 0;
4903 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4904 PEER_FLAG_ALLOWAS_IN
);
4905 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4906 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4907 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
4912 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
4913 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4914 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4915 peer
->allowas_in
[afi
][safi
] = 0;
4916 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4917 peer_af_flag_unset(peer
, afi
, safi
,
4918 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4919 peer_on_policy_change(peer
, afi
, safi
, 0);
4925 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
4928 struct bgp
*bgp
= peer
->bgp
;
4929 struct peer_group
*group
;
4930 struct listnode
*node
, *nnode
;
4932 if (peer_sort(peer
) != BGP_PEER_EBGP
4933 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
4934 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
4937 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
4940 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
4942 if (peer
->change_local_as
== as
4943 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4945 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4947 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4949 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4953 peer
->change_local_as
= as
;
4955 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4957 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4960 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4962 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4964 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4965 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4966 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4967 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4968 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4970 bgp_session_reset(peer
);
4974 group
= peer
->group
;
4975 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4976 peer
->change_local_as
= as
;
4978 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4980 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4983 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4985 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4987 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4988 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4989 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4990 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4992 BGP_EVENT_ADD(peer
, BGP_Stop
);
4998 int peer_local_as_unset(struct peer
*peer
)
5000 struct peer_group
*group
;
5001 struct listnode
*node
, *nnode
;
5003 if (!peer
->change_local_as
)
5006 peer
->change_local_as
= 0;
5007 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5008 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5010 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5011 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5012 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5013 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5014 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5016 BGP_EVENT_ADD(peer
, BGP_Stop
);
5021 group
= peer
->group
;
5022 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5023 peer
->change_local_as
= 0;
5024 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5025 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5027 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5028 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5029 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5030 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5032 bgp_session_reset(peer
);
5037 /* Set password for authenticating with the peer. */
5038 int peer_password_set(struct peer
*peer
, const char *password
)
5040 struct listnode
*nn
, *nnode
;
5041 int len
= password
? strlen(password
) : 0;
5042 int ret
= BGP_SUCCESS
;
5044 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5045 return BGP_ERR_INVALID_VALUE
;
5047 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5048 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5052 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5054 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5056 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5057 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5058 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5059 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5061 bgp_session_reset(peer
);
5063 if (BGP_PEER_SU_UNSPEC(peer
))
5066 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5067 : BGP_ERR_TCPSIG_FAILED
;
5070 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5071 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5075 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5077 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5079 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5080 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5081 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5083 bgp_session_reset(peer
);
5085 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5086 if (bgp_md5_set(peer
) < 0)
5087 ret
= BGP_ERR_TCPSIG_FAILED
;
5094 int peer_password_unset(struct peer
*peer
)
5096 struct listnode
*nn
, *nnode
;
5098 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5101 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5102 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5103 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5104 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5106 bgp_session_reset(peer
);
5109 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5111 peer
->password
= NULL
;
5113 if (!BGP_PEER_SU_UNSPEC(peer
))
5114 bgp_md5_unset(peer
);
5119 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5120 peer
->password
= NULL
;
5122 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5123 if (!peer
->password
)
5126 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5127 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5128 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5130 bgp_session_reset(peer
);
5132 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5133 peer
->password
= NULL
;
5135 if (!BGP_PEER_SU_UNSPEC(peer
))
5136 bgp_md5_unset(peer
);
5143 /* Set distribute list to the peer. */
5144 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5147 struct bgp_filter
*filter
;
5148 struct peer_group
*group
;
5149 struct listnode
*node
, *nnode
;
5151 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5152 return BGP_ERR_INVALID_VALUE
;
5154 filter
= &peer
->filter
[afi
][safi
];
5156 if (filter
->plist
[direct
].name
)
5157 return BGP_ERR_PEER_FILTER_CONFLICT
;
5159 if (filter
->dlist
[direct
].name
)
5160 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5161 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5162 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5164 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5165 peer_on_policy_change(peer
, afi
, safi
,
5166 (direct
== FILTER_OUT
) ? 1 : 0);
5170 group
= peer
->group
;
5171 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5172 filter
= &peer
->filter
[afi
][safi
];
5174 if (filter
->dlist
[direct
].name
)
5175 XFREE(MTYPE_BGP_FILTER_NAME
,
5176 filter
->dlist
[direct
].name
);
5177 filter
->dlist
[direct
].name
=
5178 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5179 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5180 peer_on_policy_change(peer
, afi
, safi
,
5181 (direct
== FILTER_OUT
) ? 1 : 0);
5187 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5189 struct bgp_filter
*filter
;
5190 struct bgp_filter
*gfilter
;
5191 struct peer_group
*group
;
5192 struct listnode
*node
, *nnode
;
5194 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5195 return BGP_ERR_INVALID_VALUE
;
5197 filter
= &peer
->filter
[afi
][safi
];
5199 /* apply peer-group filter */
5200 if (peer_group_active(peer
)) {
5201 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5203 if (gfilter
->dlist
[direct
].name
) {
5204 if (filter
->dlist
[direct
].name
)
5205 XFREE(MTYPE_BGP_FILTER_NAME
,
5206 filter
->dlist
[direct
].name
);
5207 filter
->dlist
[direct
].name
=
5208 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5209 gfilter
->dlist
[direct
].name
);
5210 filter
->dlist
[direct
].alist
=
5211 gfilter
->dlist
[direct
].alist
;
5212 peer_on_policy_change(peer
, afi
, safi
,
5213 (direct
== FILTER_OUT
) ? 1 : 0);
5218 if (filter
->dlist
[direct
].name
)
5219 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5220 filter
->dlist
[direct
].name
= NULL
;
5221 filter
->dlist
[direct
].alist
= NULL
;
5223 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5224 peer_on_policy_change(peer
, afi
, safi
,
5225 (direct
== FILTER_OUT
) ? 1 : 0);
5229 group
= peer
->group
;
5230 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5231 filter
= &peer
->filter
[afi
][safi
];
5233 if (filter
->dlist
[direct
].name
)
5234 XFREE(MTYPE_BGP_FILTER_NAME
,
5235 filter
->dlist
[direct
].name
);
5236 filter
->dlist
[direct
].name
= NULL
;
5237 filter
->dlist
[direct
].alist
= NULL
;
5238 peer_on_policy_change(peer
, afi
, safi
,
5239 (direct
== FILTER_OUT
) ? 1 : 0);
5245 /* Update distribute list. */
5246 static void peer_distribute_update(struct access_list
*access
)
5251 struct listnode
*mnode
, *mnnode
;
5252 struct listnode
*node
, *nnode
;
5255 struct peer_group
*group
;
5256 struct bgp_filter
*filter
;
5258 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5260 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5261 access
->name
, 0, 0);
5262 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5263 FOREACH_AFI_SAFI (afi
, safi
) {
5264 filter
= &peer
->filter
[afi
][safi
];
5266 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5268 if (filter
->dlist
[direct
].name
)
5269 filter
->dlist
[direct
]
5270 .alist
= access_list_lookup(
5272 filter
->dlist
[direct
]
5275 filter
->dlist
[direct
].alist
=
5280 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5281 FOREACH_AFI_SAFI (afi
, safi
) {
5282 filter
= &group
->conf
->filter
[afi
][safi
];
5284 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5286 if (filter
->dlist
[direct
].name
)
5287 filter
->dlist
[direct
]
5288 .alist
= access_list_lookup(
5290 filter
->dlist
[direct
]
5293 filter
->dlist
[direct
].alist
=
5299 vnc_prefix_list_update(bgp
);
5304 /* Set prefix list to the peer. */
5305 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5308 struct bgp_filter
*filter
;
5309 struct peer_group
*group
;
5310 struct listnode
*node
, *nnode
;
5312 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5313 return BGP_ERR_INVALID_VALUE
;
5315 filter
= &peer
->filter
[afi
][safi
];
5317 if (filter
->dlist
[direct
].name
)
5318 return BGP_ERR_PEER_FILTER_CONFLICT
;
5320 if (filter
->plist
[direct
].name
)
5321 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5322 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5323 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5325 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5326 peer_on_policy_change(peer
, afi
, safi
,
5327 (direct
== FILTER_OUT
) ? 1 : 0);
5331 group
= peer
->group
;
5332 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5333 filter
= &peer
->filter
[afi
][safi
];
5335 if (filter
->plist
[direct
].name
)
5336 XFREE(MTYPE_BGP_FILTER_NAME
,
5337 filter
->plist
[direct
].name
);
5338 filter
->plist
[direct
].name
=
5339 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5340 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5341 peer_on_policy_change(peer
, afi
, safi
,
5342 (direct
== FILTER_OUT
) ? 1 : 0);
5347 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5350 struct bgp_filter
*filter
;
5351 struct bgp_filter
*gfilter
;
5352 struct peer_group
*group
;
5353 struct listnode
*node
, *nnode
;
5355 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5356 return BGP_ERR_INVALID_VALUE
;
5358 filter
= &peer
->filter
[afi
][safi
];
5360 /* apply peer-group filter */
5361 if (peer_group_active(peer
)) {
5362 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5364 if (gfilter
->plist
[direct
].name
) {
5365 if (filter
->plist
[direct
].name
)
5366 XFREE(MTYPE_BGP_FILTER_NAME
,
5367 filter
->plist
[direct
].name
);
5368 filter
->plist
[direct
].name
=
5369 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5370 gfilter
->plist
[direct
].name
);
5371 filter
->plist
[direct
].plist
=
5372 gfilter
->plist
[direct
].plist
;
5373 peer_on_policy_change(peer
, afi
, safi
,
5374 (direct
== FILTER_OUT
) ? 1 : 0);
5379 if (filter
->plist
[direct
].name
)
5380 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5381 filter
->plist
[direct
].name
= NULL
;
5382 filter
->plist
[direct
].plist
= NULL
;
5384 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5385 peer_on_policy_change(peer
, afi
, safi
,
5386 (direct
== FILTER_OUT
) ? 1 : 0);
5390 group
= peer
->group
;
5391 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5392 filter
= &peer
->filter
[afi
][safi
];
5394 if (filter
->plist
[direct
].name
)
5395 XFREE(MTYPE_BGP_FILTER_NAME
,
5396 filter
->plist
[direct
].name
);
5397 filter
->plist
[direct
].name
= NULL
;
5398 filter
->plist
[direct
].plist
= NULL
;
5399 peer_on_policy_change(peer
, afi
, safi
,
5400 (direct
== FILTER_OUT
) ? 1 : 0);
5406 /* Update prefix-list list. */
5407 static void peer_prefix_list_update(struct prefix_list
*plist
)
5409 struct listnode
*mnode
, *mnnode
;
5410 struct listnode
*node
, *nnode
;
5413 struct peer_group
*group
;
5414 struct bgp_filter
*filter
;
5419 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5422 * Update the prefix-list on update groups.
5424 update_group_policy_update(
5425 bgp
, BGP_POLICY_PREFIX_LIST
,
5426 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5428 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5429 FOREACH_AFI_SAFI (afi
, safi
) {
5430 filter
= &peer
->filter
[afi
][safi
];
5432 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5434 if (filter
->plist
[direct
].name
)
5435 filter
->plist
[direct
]
5436 .plist
= prefix_list_lookup(
5438 filter
->plist
[direct
]
5441 filter
->plist
[direct
].plist
=
5446 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5447 FOREACH_AFI_SAFI (afi
, safi
) {
5448 filter
= &group
->conf
->filter
[afi
][safi
];
5450 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5452 if (filter
->plist
[direct
].name
)
5453 filter
->plist
[direct
]
5454 .plist
= prefix_list_lookup(
5456 filter
->plist
[direct
]
5459 filter
->plist
[direct
].plist
=
5467 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5470 struct bgp_filter
*filter
;
5471 struct peer_group
*group
;
5472 struct listnode
*node
, *nnode
;
5474 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5475 return BGP_ERR_INVALID_VALUE
;
5477 filter
= &peer
->filter
[afi
][safi
];
5479 if (filter
->aslist
[direct
].name
)
5480 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5481 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5482 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5484 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5485 peer_on_policy_change(peer
, afi
, safi
,
5486 (direct
== FILTER_OUT
) ? 1 : 0);
5490 group
= peer
->group
;
5491 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5492 filter
= &peer
->filter
[afi
][safi
];
5494 if (filter
->aslist
[direct
].name
)
5495 XFREE(MTYPE_BGP_FILTER_NAME
,
5496 filter
->aslist
[direct
].name
);
5497 filter
->aslist
[direct
].name
=
5498 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5499 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5500 peer_on_policy_change(peer
, afi
, safi
,
5501 (direct
== FILTER_OUT
) ? 1 : 0);
5506 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5508 struct bgp_filter
*filter
;
5509 struct bgp_filter
*gfilter
;
5510 struct peer_group
*group
;
5511 struct listnode
*node
, *nnode
;
5513 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5514 return BGP_ERR_INVALID_VALUE
;
5516 filter
= &peer
->filter
[afi
][safi
];
5518 /* apply peer-group filter */
5519 if (peer_group_active(peer
)) {
5520 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5522 if (gfilter
->aslist
[direct
].name
) {
5523 if (filter
->aslist
[direct
].name
)
5524 XFREE(MTYPE_BGP_FILTER_NAME
,
5525 filter
->aslist
[direct
].name
);
5526 filter
->aslist
[direct
].name
=
5527 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5528 gfilter
->aslist
[direct
].name
);
5529 filter
->aslist
[direct
].aslist
=
5530 gfilter
->aslist
[direct
].aslist
;
5531 peer_on_policy_change(peer
, afi
, safi
,
5532 (direct
== FILTER_OUT
) ? 1 : 0);
5537 if (filter
->aslist
[direct
].name
)
5538 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5539 filter
->aslist
[direct
].name
= NULL
;
5540 filter
->aslist
[direct
].aslist
= NULL
;
5542 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5543 peer_on_policy_change(peer
, afi
, safi
,
5544 (direct
== FILTER_OUT
) ? 1 : 0);
5548 group
= peer
->group
;
5549 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5550 filter
= &peer
->filter
[afi
][safi
];
5552 if (filter
->aslist
[direct
].name
)
5553 XFREE(MTYPE_BGP_FILTER_NAME
,
5554 filter
->aslist
[direct
].name
);
5555 filter
->aslist
[direct
].name
= NULL
;
5556 filter
->aslist
[direct
].aslist
= NULL
;
5557 peer_on_policy_change(peer
, afi
, safi
,
5558 (direct
== FILTER_OUT
) ? 1 : 0);
5564 static void peer_aslist_update(const char *aslist_name
)
5569 struct listnode
*mnode
, *mnnode
;
5570 struct listnode
*node
, *nnode
;
5573 struct peer_group
*group
;
5574 struct bgp_filter
*filter
;
5576 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5577 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5580 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5581 FOREACH_AFI_SAFI (afi
, safi
) {
5582 filter
= &peer
->filter
[afi
][safi
];
5584 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5586 if (filter
->aslist
[direct
].name
)
5587 filter
->aslist
[direct
]
5588 .aslist
= as_list_lookup(
5589 filter
->aslist
[direct
]
5592 filter
->aslist
[direct
].aslist
=
5597 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5598 FOREACH_AFI_SAFI (afi
, safi
) {
5599 filter
= &group
->conf
->filter
[afi
][safi
];
5601 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5603 if (filter
->aslist
[direct
].name
)
5604 filter
->aslist
[direct
]
5605 .aslist
= as_list_lookup(
5606 filter
->aslist
[direct
]
5609 filter
->aslist
[direct
].aslist
=
5617 static void peer_aslist_add(char *aslist_name
)
5619 peer_aslist_update(aslist_name
);
5620 route_map_notify_dependencies((char *)aslist_name
,
5621 RMAP_EVENT_ASLIST_ADDED
);
5624 static void peer_aslist_del(const char *aslist_name
)
5626 peer_aslist_update(aslist_name
);
5627 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5631 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5634 struct bgp_filter
*filter
;
5635 struct peer_group
*group
;
5636 struct listnode
*node
, *nnode
;
5638 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5639 return BGP_ERR_INVALID_VALUE
;
5641 filter
= &peer
->filter
[afi
][safi
];
5643 if (filter
->map
[direct
].name
)
5644 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5646 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5647 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5649 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5650 peer_on_policy_change(peer
, afi
, safi
,
5651 (direct
== RMAP_OUT
) ? 1 : 0);
5655 group
= peer
->group
;
5656 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5657 filter
= &peer
->filter
[afi
][safi
];
5659 if (filter
->map
[direct
].name
)
5660 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5661 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5662 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5663 peer_on_policy_change(peer
, afi
, safi
,
5664 (direct
== RMAP_OUT
) ? 1 : 0);
5669 /* Unset route-map from the peer. */
5670 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5672 struct bgp_filter
*filter
;
5673 struct bgp_filter
*gfilter
;
5674 struct peer_group
*group
;
5675 struct listnode
*node
, *nnode
;
5677 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5678 return BGP_ERR_INVALID_VALUE
;
5680 filter
= &peer
->filter
[afi
][safi
];
5682 /* apply peer-group filter */
5683 if (peer_group_active(peer
)) {
5684 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5686 if (gfilter
->map
[direct
].name
) {
5687 if (filter
->map
[direct
].name
)
5688 XFREE(MTYPE_BGP_FILTER_NAME
,
5689 filter
->map
[direct
].name
);
5690 filter
->map
[direct
].name
=
5691 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5692 gfilter
->map
[direct
].name
);
5693 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5694 peer_on_policy_change(peer
, afi
, safi
,
5695 (direct
== RMAP_OUT
) ? 1 : 0);
5700 if (filter
->map
[direct
].name
)
5701 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5702 filter
->map
[direct
].name
= NULL
;
5703 filter
->map
[direct
].map
= NULL
;
5705 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5706 peer_on_policy_change(peer
, afi
, safi
,
5707 (direct
== RMAP_OUT
) ? 1 : 0);
5711 group
= peer
->group
;
5712 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5713 filter
= &peer
->filter
[afi
][safi
];
5715 if (filter
->map
[direct
].name
)
5716 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5717 filter
->map
[direct
].name
= NULL
;
5718 filter
->map
[direct
].map
= NULL
;
5719 peer_on_policy_change(peer
, afi
, safi
,
5720 (direct
== RMAP_OUT
) ? 1 : 0);
5725 /* Set unsuppress-map to the peer. */
5726 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5729 struct bgp_filter
*filter
;
5730 struct peer_group
*group
;
5731 struct listnode
*node
, *nnode
;
5733 filter
= &peer
->filter
[afi
][safi
];
5735 if (filter
->usmap
.name
)
5736 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5738 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5739 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5741 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5742 peer_on_policy_change(peer
, afi
, safi
, 1);
5746 group
= peer
->group
;
5747 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5748 filter
= &peer
->filter
[afi
][safi
];
5750 if (filter
->usmap
.name
)
5751 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5752 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5753 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5754 peer_on_policy_change(peer
, afi
, safi
, 1);
5759 /* Unset route-map from the peer. */
5760 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5762 struct bgp_filter
*filter
;
5763 struct peer_group
*group
;
5764 struct listnode
*node
, *nnode
;
5766 filter
= &peer
->filter
[afi
][safi
];
5768 if (filter
->usmap
.name
)
5769 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5770 filter
->usmap
.name
= NULL
;
5771 filter
->usmap
.map
= NULL
;
5773 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5774 peer_on_policy_change(peer
, afi
, safi
, 1);
5778 group
= peer
->group
;
5779 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5780 filter
= &peer
->filter
[afi
][safi
];
5782 if (filter
->usmap
.name
)
5783 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5784 filter
->usmap
.name
= NULL
;
5785 filter
->usmap
.map
= NULL
;
5786 peer_on_policy_change(peer
, afi
, safi
, 1);
5791 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5792 u_int32_t max
, u_char threshold
, int warning
,
5795 struct peer_group
*group
;
5796 struct listnode
*node
, *nnode
;
5798 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5799 peer
->pmax
[afi
][safi
] = max
;
5800 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5801 peer
->pmax_restart
[afi
][safi
] = restart
;
5803 SET_FLAG(peer
->af_flags
[afi
][safi
],
5804 PEER_FLAG_MAX_PREFIX_WARNING
);
5806 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5807 PEER_FLAG_MAX_PREFIX_WARNING
);
5809 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5810 group
= peer
->group
;
5811 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5812 SET_FLAG(peer
->af_flags
[afi
][safi
],
5813 PEER_FLAG_MAX_PREFIX
);
5814 peer
->pmax
[afi
][safi
] = max
;
5815 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5816 peer
->pmax_restart
[afi
][safi
] = restart
;
5818 SET_FLAG(peer
->af_flags
[afi
][safi
],
5819 PEER_FLAG_MAX_PREFIX_WARNING
);
5821 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5822 PEER_FLAG_MAX_PREFIX_WARNING
);
5824 if ((peer
->status
== Established
)
5825 && (peer
->afc
[afi
][safi
]))
5826 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5829 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5830 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5836 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5838 struct peer_group
*group
;
5839 struct listnode
*node
, *nnode
;
5841 /* apply peer-group config */
5842 if (peer_group_active(peer
)) {
5843 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5844 PEER_FLAG_MAX_PREFIX
))
5845 SET_FLAG(peer
->af_flags
[afi
][safi
],
5846 PEER_FLAG_MAX_PREFIX
);
5848 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5849 PEER_FLAG_MAX_PREFIX
);
5851 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5852 PEER_FLAG_MAX_PREFIX_WARNING
))
5853 SET_FLAG(peer
->af_flags
[afi
][safi
],
5854 PEER_FLAG_MAX_PREFIX_WARNING
);
5856 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5857 PEER_FLAG_MAX_PREFIX_WARNING
);
5859 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
5860 peer
->pmax_threshold
[afi
][safi
] =
5861 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
5862 peer
->pmax_restart
[afi
][safi
] =
5863 peer
->group
->conf
->pmax_restart
[afi
][safi
];
5867 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5868 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
5869 peer
->pmax
[afi
][safi
] = 0;
5870 peer
->pmax_threshold
[afi
][safi
] = 0;
5871 peer
->pmax_restart
[afi
][safi
] = 0;
5873 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5876 group
= peer
->group
;
5877 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5878 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5879 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5880 PEER_FLAG_MAX_PREFIX_WARNING
);
5881 peer
->pmax
[afi
][safi
] = 0;
5882 peer
->pmax_threshold
[afi
][safi
] = 0;
5883 peer
->pmax_restart
[afi
][safi
] = 0;
5888 int is_ebgp_multihop_configured(struct peer
*peer
)
5890 struct peer_group
*group
;
5891 struct listnode
*node
, *nnode
;
5894 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5895 group
= peer
->group
;
5896 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
5897 && (group
->conf
->ttl
!= 1))
5900 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
5901 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
5902 && (peer1
->ttl
!= 1))
5906 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
5912 /* Set # of hops between us and BGP peer. */
5913 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
5915 struct peer_group
*group
;
5916 struct listnode
*node
, *nnode
;
5919 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
5920 gtsm_hops
, peer
->host
);
5922 /* We cannot configure ttl-security hops when ebgp-multihop is already
5923 set. For non peer-groups, the check is simple. For peer-groups,
5925 slightly messy, because we need to check both the peer-group
5927 and all peer-group members for any trace of ebgp-multihop
5929 before actually applying the ttl-security rules. Cisco really made a
5930 mess of this configuration parameter, and OpenBGPD got it right.
5933 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
5934 if (is_ebgp_multihop_configured(peer
))
5935 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
5937 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5938 peer
->gtsm_hops
= gtsm_hops
;
5940 /* Calling ebgp multihop also resets the session.
5941 * On restart, NHT will get setup correctly as will the
5942 * min & max ttls on the socket. The return value is
5945 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
5950 group
= peer
->group
;
5951 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5953 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5955 /* Calling ebgp multihop also resets the
5957 * On restart, NHT will get setup correctly as
5959 * min & max ttls on the socket. The return
5963 peer_ebgp_multihop_set(peer
, MAXTTL
);
5967 /* Post the first gtsm setup or if its ibgp, maxttl setting
5969 * necessary, just set the minttl.
5971 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5972 peer
->gtsm_hops
= gtsm_hops
;
5975 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
5976 MAXTTL
+ 1 - gtsm_hops
);
5977 if ((peer
->status
< Established
) && peer
->doppelganger
5978 && (peer
->doppelganger
->fd
>= 0))
5979 sockopt_minttl(peer
->su
.sa
.sa_family
,
5980 peer
->doppelganger
->fd
,
5981 MAXTTL
+ 1 - gtsm_hops
);
5983 group
= peer
->group
;
5984 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5986 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5988 /* Change setting of existing peer
5989 * established then change value (may break
5991 * not established yet (teardown session and
5993 * no session then do nothing (will get
5994 * handled by next connection)
5996 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
5998 peer
->su
.sa
.sa_family
, peer
->fd
,
5999 MAXTTL
+ 1 - peer
->gtsm_hops
);
6000 if ((peer
->status
< Established
)
6001 && peer
->doppelganger
6002 && (peer
->doppelganger
->fd
>= 0))
6003 sockopt_minttl(peer
->su
.sa
.sa_family
,
6004 peer
->doppelganger
->fd
,
6005 MAXTTL
+ 1 - gtsm_hops
);
6013 int peer_ttl_security_hops_unset(struct peer
*peer
)
6015 struct peer_group
*group
;
6016 struct listnode
*node
, *nnode
;
6019 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6022 /* if a peer-group member, then reset to peer-group default rather than
6024 if (peer_group_active(peer
))
6025 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6027 peer
->gtsm_hops
= 0;
6029 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6030 /* Invoking ebgp_multihop_set will set the TTL back to the
6032 * value as well as restting the NHT and such. The session is
6035 if (peer
->sort
== BGP_PEER_EBGP
)
6036 ret
= peer_ebgp_multihop_unset(peer
);
6039 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6042 if ((peer
->status
< Established
) && peer
->doppelganger
6043 && (peer
->doppelganger
->fd
>= 0))
6044 sockopt_minttl(peer
->su
.sa
.sa_family
,
6045 peer
->doppelganger
->fd
, 0);
6048 group
= peer
->group
;
6049 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6050 peer
->gtsm_hops
= 0;
6051 if (peer
->sort
== BGP_PEER_EBGP
)
6052 ret
= peer_ebgp_multihop_unset(peer
);
6055 sockopt_minttl(peer
->su
.sa
.sa_family
,
6058 if ((peer
->status
< Established
)
6059 && peer
->doppelganger
6060 && (peer
->doppelganger
->fd
>= 0))
6061 sockopt_minttl(peer
->su
.sa
.sa_family
,
6062 peer
->doppelganger
->fd
,
6072 * If peer clear is invoked in a loop for all peers on the BGP instance,
6073 * it may end up freeing the doppelganger, and if this was the next node
6074 * to the current node, we would end up accessing the freed next node.
6075 * Pass along additional parameter which can be updated if next node
6076 * is freed; only required when walking the peer list on BGP instance.
6078 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6080 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6081 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6082 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6083 if (peer
->t_pmax_restart
) {
6084 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6085 if (bgp_debug_neighbor_events(peer
))
6087 "%s Maximum-prefix restart timer canceled",
6090 BGP_EVENT_ADD(peer
, BGP_Start
);
6094 peer
->v_start
= BGP_INIT_START_TIMER
;
6095 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6096 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6097 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6099 bgp_session_reset_safe(peer
, nnode
);
6104 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6105 enum bgp_clear_type stype
)
6107 struct peer_af
*paf
;
6109 if (peer
->status
!= Established
)
6112 if (!peer
->afc
[afi
][safi
])
6113 return BGP_ERR_AF_UNCONFIGURED
;
6115 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6117 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6118 /* Clear the "neighbor x.x.x.x default-originate" flag */
6119 paf
= peer_af_find(peer
, afi
, safi
);
6120 if (paf
&& paf
->subgroup
6121 && CHECK_FLAG(paf
->subgroup
->sflags
,
6122 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6123 UNSET_FLAG(paf
->subgroup
->sflags
,
6124 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6126 bgp_announce_route(peer
, afi
, safi
);
6129 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6130 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6131 PEER_CAP_ORF_PREFIX_SM_ADV
)
6132 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6133 PEER_CAP_ORF_PREFIX_RM_RCV
)
6134 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6135 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6136 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6139 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6140 PEER_CAP_ORF_PREFIX_RM_RCV
))
6141 prefix_type
= ORF_TYPE_PREFIX
;
6143 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6145 if (filter
->plist
[FILTER_IN
].plist
) {
6146 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6147 PEER_STATUS_ORF_PREFIX_SEND
))
6148 bgp_route_refresh_send(
6149 peer
, afi
, safi
, prefix_type
,
6151 bgp_route_refresh_send(peer
, afi
, safi
,
6153 REFRESH_IMMEDIATE
, 0);
6155 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6156 PEER_STATUS_ORF_PREFIX_SEND
))
6157 bgp_route_refresh_send(
6158 peer
, afi
, safi
, prefix_type
,
6159 REFRESH_IMMEDIATE
, 1);
6161 bgp_route_refresh_send(peer
, afi
, safi
,
6168 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6169 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6170 /* If neighbor has soft reconfiguration inbound flag.
6171 Use Adj-RIB-In database. */
6172 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6173 PEER_FLAG_SOFT_RECONFIG
))
6174 bgp_soft_reconfig_in(peer
, afi
, safi
);
6176 /* If neighbor has route refresh capability, send route
6178 message to the peer. */
6179 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6180 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6181 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6184 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6190 /* Display peer uptime.*/
6191 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, u_char use_json
,
6194 time_t uptime1
, epoch_tbuf
;
6197 /* Check buffer length. */
6198 if (len
< BGP_UPTIME_LEN
) {
6200 zlog_warn("peer_uptime (): buffer shortage %lu",
6202 /* XXX: should return status instead of buf... */
6203 snprintf(buf
, len
, "<error> ");
6208 /* If there is no connection has been done before print `never'. */
6211 json_object_string_add(json
, "peerUptime", "never");
6212 json_object_int_add(json
, "peerUptimeMsec", 0);
6214 snprintf(buf
, len
, "never");
6218 /* Get current time. */
6219 uptime1
= bgp_clock();
6221 tm
= gmtime(&uptime1
);
6223 if (uptime1
< ONE_DAY_SECOND
)
6224 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6226 else if (uptime1
< ONE_WEEK_SECOND
)
6227 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6229 else if (uptime1
< ONE_YEAR_SECOND
)
6230 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6231 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6233 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6235 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6238 epoch_tbuf
= time(NULL
) - uptime1
;
6239 json_object_string_add(json
, "peerUptime", buf
);
6240 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6241 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6248 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6249 afi_t afi
, safi_t safi
)
6251 struct bgp_filter
*filter
;
6252 struct bgp_filter
*gfilter
= NULL
;
6255 int out
= FILTER_OUT
;
6258 filter
= &peer
->filter
[afi
][safi
];
6260 if (peer_group_active(peer
))
6261 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6263 /* distribute-list. */
6264 if (filter
->dlist
[in
].name
)
6265 if (!gfilter
|| !gfilter
->dlist
[in
].name
6266 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6268 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6269 addr
, filter
->dlist
[in
].name
);
6272 if (filter
->dlist
[out
].name
&& !gfilter
) {
6273 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6274 filter
->dlist
[out
].name
);
6278 if (filter
->plist
[in
].name
)
6279 if (!gfilter
|| !gfilter
->plist
[in
].name
6280 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6282 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6283 filter
->plist
[in
].name
);
6286 if (filter
->plist
[out
].name
)
6287 if (!gfilter
|| !gfilter
->plist
[out
].name
6288 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6290 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6291 filter
->plist
[out
].name
);
6295 if (filter
->map
[RMAP_IN
].name
)
6296 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6297 || strcmp(filter
->map
[RMAP_IN
].name
,
6298 gfilter
->map
[RMAP_IN
].name
)
6300 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6301 filter
->map
[RMAP_IN
].name
);
6304 if (filter
->map
[RMAP_OUT
].name
)
6305 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6306 || strcmp(filter
->map
[RMAP_OUT
].name
,
6307 gfilter
->map
[RMAP_OUT
].name
)
6309 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6310 filter
->map
[RMAP_OUT
].name
);
6313 /* unsuppress-map */
6314 if (filter
->usmap
.name
&& !gfilter
) {
6315 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6316 filter
->usmap
.name
);
6320 if (filter
->aslist
[in
].name
)
6321 if (!gfilter
|| !gfilter
->aslist
[in
].name
6322 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6324 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6325 filter
->aslist
[in
].name
);
6328 if (filter
->aslist
[out
].name
&& !gfilter
) {
6329 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6330 filter
->aslist
[out
].name
);
6334 /* BGP peer configuration display function. */
6335 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6338 struct peer
*g_peer
= NULL
;
6339 char buf
[SU_ADDRSTRLEN
];
6341 int if_pg_printed
= FALSE
;
6342 int if_ras_printed
= FALSE
;
6344 /* Skip dynamic neighbors. */
6345 if (peer_dynamic_neighbor(peer
))
6349 addr
= peer
->conf_if
;
6353 /************************************
6354 ****** Global to the neighbor ******
6355 ************************************/
6356 if (peer
->conf_if
) {
6357 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6358 vty_out(vty
, " neighbor %s interface v6only", addr
);
6360 vty_out(vty
, " neighbor %s interface", addr
);
6362 if (peer_group_active(peer
)) {
6363 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6364 if_pg_printed
= TRUE
;
6365 } else if (peer
->as_type
== AS_SPECIFIED
) {
6366 vty_out(vty
, " remote-as %u", peer
->as
);
6367 if_ras_printed
= TRUE
;
6368 } else if (peer
->as_type
== AS_INTERNAL
) {
6369 vty_out(vty
, " remote-as internal");
6370 if_ras_printed
= TRUE
;
6371 } else if (peer
->as_type
== AS_EXTERNAL
) {
6372 vty_out(vty
, " remote-as external");
6373 if_ras_printed
= TRUE
;
6379 /* remote-as and peer-group */
6380 /* peer is a member of a peer-group */
6381 if (peer_group_active(peer
)) {
6382 g_peer
= peer
->group
->conf
;
6384 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6385 if (peer
->as_type
== AS_SPECIFIED
) {
6386 vty_out(vty
, " neighbor %s remote-as %u\n",
6388 } else if (peer
->as_type
== AS_INTERNAL
) {
6390 " neighbor %s remote-as internal\n",
6392 } else if (peer
->as_type
== AS_EXTERNAL
) {
6394 " neighbor %s remote-as external\n",
6399 /* For swpX peers we displayed the peer-group
6400 * via 'neighbor swpX interface peer-group WORD' */
6402 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6406 /* peer is NOT a member of a peer-group */
6408 /* peer is a peer-group, declare the peer-group */
6409 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6410 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6413 if (!if_ras_printed
) {
6414 if (peer
->as_type
== AS_SPECIFIED
) {
6415 vty_out(vty
, " neighbor %s remote-as %u\n",
6417 } else if (peer
->as_type
== AS_INTERNAL
) {
6419 " neighbor %s remote-as internal\n",
6421 } else if (peer
->as_type
== AS_EXTERNAL
) {
6423 " neighbor %s remote-as external\n",
6430 if (peer
->change_local_as
) {
6431 if (!peer_group_active(peer
)
6432 || peer
->change_local_as
!= g_peer
->change_local_as
6433 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6434 != CHECK_FLAG(g_peer
->flags
,
6435 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6436 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6437 != CHECK_FLAG(g_peer
->flags
,
6438 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6439 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6440 peer
->change_local_as
,
6441 CHECK_FLAG(peer
->flags
,
6442 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6445 CHECK_FLAG(peer
->flags
,
6446 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6454 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6458 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6459 if (!peer_group_active(peer
)
6460 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6461 || peer
->tx_shutdown_message
) {
6462 if (peer
->tx_shutdown_message
)
6464 " neighbor %s shutdown message %s\n",
6465 addr
, peer
->tx_shutdown_message
);
6467 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6472 if (peer
->bfd_info
) {
6473 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6474 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6479 if (peer
->password
) {
6480 if (!peer_group_active(peer
) || !g_peer
->password
6481 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6482 vty_out(vty
, " neighbor %s password %s\n", addr
,
6488 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6489 if (!peer_group_active(peer
)) {
6490 vty_out(vty
, " neighbor %s solo\n", addr
);
6495 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6496 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6499 /* Local interface name */
6501 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6505 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6506 if (!peer_group_active(peer
)
6507 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6508 vty_out(vty
, " neighbor %s passive\n", addr
);
6513 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6514 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6515 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6516 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6521 /* ttl-security hops */
6522 if (peer
->gtsm_hops
!= 0) {
6523 if (!peer_group_active(peer
)
6524 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6525 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6526 addr
, peer
->gtsm_hops
);
6530 /* disable-connected-check */
6531 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6532 if (!peer_group_active(peer
)
6533 || !CHECK_FLAG(g_peer
->flags
,
6534 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6535 vty_out(vty
, " neighbor %s disable-connected-check\n",
6541 if (peer
->update_if
) {
6542 if (!peer_group_active(peer
) || !g_peer
->update_if
6543 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6544 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6548 if (peer
->update_source
) {
6549 if (!peer_group_active(peer
) || !g_peer
->update_source
6550 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6552 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6553 sockunion2str(peer
->update_source
, buf
,
6558 /* advertisement-interval */
6559 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6560 && ((!peer_group_active(peer
)
6561 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6562 || (peer_group_active(peer
)
6563 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6564 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6569 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6570 && ((!peer_group_active(peer
)
6571 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6572 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6573 || (peer_group_active(peer
)
6574 && (peer
->keepalive
!= g_peer
->keepalive
6575 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6576 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6577 peer
->keepalive
, peer
->holdtime
);
6580 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6581 && ((!peer_group_active(peer
)
6582 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6583 || (peer_group_active(peer
)
6584 && peer
->connect
!= g_peer
->connect
)))
6587 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6591 /* capability dynamic */
6592 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6593 if (!peer_group_active(peer
)
6594 || !CHECK_FLAG(g_peer
->flags
,
6595 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6596 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6600 /* capability extended-nexthop */
6601 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6602 if (!peer_group_active(peer
)
6603 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6605 " no neighbor %s capability extended-nexthop\n",
6610 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6611 if (!peer_group_active(peer
)
6612 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6614 " neighbor %s capability extended-nexthop\n",
6619 /* dont-capability-negotiation */
6620 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6621 if (!peer_group_active(peer
)
6622 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6623 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6628 /* override-capability */
6629 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6630 if (!peer_group_active(peer
)
6631 || !CHECK_FLAG(g_peer
->flags
,
6632 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6633 vty_out(vty
, " neighbor %s override-capability\n",
6638 /* strict-capability-match */
6639 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6640 if (!peer_group_active(peer
)
6641 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6642 vty_out(vty
, " neighbor %s strict-capability-match\n",
6648 /* BGP peer configuration display function. */
6649 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6650 struct peer
*peer
, afi_t afi
, safi_t safi
)
6652 struct peer
*g_peer
= NULL
;
6655 /* Skip dynamic neighbors. */
6656 if (peer_dynamic_neighbor(peer
))
6660 addr
= peer
->conf_if
;
6664 /************************************
6665 ****** Per AF to the neighbor ******
6666 ************************************/
6667 if (peer_group_active(peer
)) {
6668 g_peer
= peer
->group
->conf
;
6670 /* If the peer-group is active but peer is not, print a 'no
6672 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6673 vty_out(vty
, " no neighbor %s activate\n", addr
);
6676 /* If the peer-group is not active but peer is, print an
6678 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6679 vty_out(vty
, " neighbor %s activate\n", addr
);
6682 if (peer
->afc
[afi
][safi
]) {
6683 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6684 if (bgp_flag_check(bgp
,
6685 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6686 vty_out(vty
, " neighbor %s activate\n",
6690 vty_out(vty
, " neighbor %s activate\n", addr
);
6692 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6693 if (!bgp_flag_check(bgp
,
6694 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6696 " no neighbor %s activate\n",
6703 /* addpath TX knobs */
6704 if (peergroup_af_flag_check(peer
, afi
, safi
,
6705 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6706 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6709 if (peergroup_af_flag_check(peer
, afi
, safi
,
6710 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6711 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6715 /* ORF capability. */
6716 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6717 || peergroup_af_flag_check(peer
, afi
, safi
,
6718 PEER_FLAG_ORF_PREFIX_RM
)) {
6719 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6721 if (peergroup_af_flag_check(peer
, afi
, safi
,
6722 PEER_FLAG_ORF_PREFIX_SM
)
6723 && peergroup_af_flag_check(peer
, afi
, safi
,
6724 PEER_FLAG_ORF_PREFIX_RM
))
6725 vty_out(vty
, " both");
6726 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6727 PEER_FLAG_ORF_PREFIX_SM
))
6728 vty_out(vty
, " send");
6730 vty_out(vty
, " receive");
6734 /* Route reflector client. */
6735 if (peergroup_af_flag_check(peer
, afi
, safi
,
6736 PEER_FLAG_REFLECTOR_CLIENT
)) {
6737 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6740 /* next-hop-self force */
6741 if (peergroup_af_flag_check(peer
, afi
, safi
,
6742 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6743 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6747 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6748 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6751 /* remove-private-AS */
6752 if (peergroup_af_flag_check(peer
, afi
, safi
,
6753 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6754 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6758 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6759 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6760 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6764 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6765 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6766 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6769 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6770 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6771 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6775 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6776 vty_out(vty
, " neighbor %s as-override\n", addr
);
6779 /* send-community print. */
6780 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6781 if (peergroup_af_flag_check(peer
, afi
, safi
,
6782 PEER_FLAG_SEND_COMMUNITY
)
6783 && peergroup_af_flag_check(peer
, afi
, safi
,
6784 PEER_FLAG_SEND_EXT_COMMUNITY
)
6785 && peergroup_af_flag_check(
6787 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6788 vty_out(vty
, " neighbor %s send-community all\n",
6790 } else if (peergroup_af_flag_check(
6792 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6793 vty_out(vty
, " neighbor %s send-community large\n",
6795 } else if (peergroup_af_flag_check(
6797 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6798 vty_out(vty
, " neighbor %s send-community extended\n",
6800 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6801 PEER_FLAG_SEND_COMMUNITY
)) {
6802 vty_out(vty
, " neighbor %s send-community\n", addr
);
6805 if (!peer_af_flag_check(peer
, afi
, safi
,
6806 PEER_FLAG_SEND_COMMUNITY
)
6807 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6808 PEER_FLAG_SEND_COMMUNITY
))
6809 && !peer_af_flag_check(peer
, afi
, safi
,
6810 PEER_FLAG_SEND_EXT_COMMUNITY
)
6812 || peer_af_flag_check(g_peer
, afi
, safi
,
6813 PEER_FLAG_SEND_EXT_COMMUNITY
))
6814 && !peer_af_flag_check(peer
, afi
, safi
,
6815 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6816 && (!g_peer
|| peer_af_flag_check(
6818 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6819 vty_out(vty
, " no neighbor %s send-community all\n",
6822 if (!peer_af_flag_check(peer
, afi
, safi
,
6823 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6825 || peer_af_flag_check(
6827 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6829 " no neighbor %s send-community large\n",
6833 if (!peer_af_flag_check(peer
, afi
, safi
,
6834 PEER_FLAG_SEND_EXT_COMMUNITY
)
6836 || peer_af_flag_check(
6838 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6840 " no neighbor %s send-community extended\n",
6844 if (!peer_af_flag_check(peer
, afi
, safi
,
6845 PEER_FLAG_SEND_COMMUNITY
)
6846 && (!g_peer
|| peer_af_flag_check(
6848 PEER_FLAG_SEND_COMMUNITY
))) {
6850 " no neighbor %s send-community\n",
6856 /* Default information */
6857 if (peergroup_af_flag_check(peer
, afi
, safi
,
6858 PEER_FLAG_DEFAULT_ORIGINATE
)
6860 && ((peer
->default_rmap
[afi
][safi
].name
6861 && !g_peer
->default_rmap
[afi
][safi
].name
)
6862 || (!peer
->default_rmap
[afi
][safi
].name
6863 && g_peer
->default_rmap
[afi
][safi
].name
)
6864 || (peer
->default_rmap
[afi
][safi
].name
6865 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
6866 g_peer
->default_rmap
[afi
][safi
].name
))))) {
6867 vty_out(vty
, " neighbor %s default-originate", addr
);
6868 if (peer
->default_rmap
[afi
][safi
].name
)
6869 vty_out(vty
, " route-map %s",
6870 peer
->default_rmap
[afi
][safi
].name
);
6874 /* Soft reconfiguration inbound. */
6875 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
6876 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
6880 /* maximum-prefix. */
6881 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
6882 if (!peer_group_active(peer
)
6883 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
6884 || g_peer
->pmax_threshold
[afi
][safi
]
6885 != peer
->pmax_threshold
[afi
][safi
]
6886 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
6887 PEER_FLAG_MAX_PREFIX_WARNING
)
6888 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6889 PEER_FLAG_MAX_PREFIX_WARNING
)) {
6890 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
6891 peer
->pmax
[afi
][safi
]);
6892 if (peer
->pmax_threshold
[afi
][safi
]
6893 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
6895 peer
->pmax_threshold
[afi
][safi
]);
6896 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6897 PEER_FLAG_MAX_PREFIX_WARNING
))
6898 vty_out(vty
, " warning-only");
6899 if (peer
->pmax_restart
[afi
][safi
])
6900 vty_out(vty
, " restart %u",
6901 peer
->pmax_restart
[afi
][safi
]);
6905 /* Route server client. */
6906 if (peergroup_af_flag_check(peer
, afi
, safi
,
6907 PEER_FLAG_RSERVER_CLIENT
)) {
6908 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
6911 /* Nexthop-local unchanged. */
6912 if (peergroup_af_flag_check(peer
, afi
, safi
,
6913 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
6914 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
6917 /* allowas-in <1-10> */
6918 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
6919 if (!peer_group_active(peer
)
6920 || !peer_af_flag_check(g_peer
, afi
, safi
,
6921 PEER_FLAG_ALLOWAS_IN
)
6922 || peer
->allowas_in
[afi
][safi
]
6923 != g_peer
->allowas_in
[afi
][safi
]) {
6924 if (peer
->allowas_in
[afi
][safi
] == 3) {
6925 vty_out(vty
, " neighbor %s allowas-in\n",
6928 vty_out(vty
, " neighbor %s allowas-in %d\n",
6929 addr
, peer
->allowas_in
[afi
][safi
]);
6934 /* allowas-in origin */
6935 else if (peer_af_flag_check(peer
, afi
, safi
,
6936 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6937 if (!peer_group_active(peer
)
6938 || !peer_af_flag_check(g_peer
, afi
, safi
,
6939 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6940 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
6945 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
6946 if (!peer_group_active(peer
)
6947 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
6948 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
6949 if (peer
->weight
[afi
][safi
]) {
6950 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
6951 peer
->weight
[afi
][safi
]);
6956 bgp_config_write_filter(vty
, peer
, afi
, safi
);
6958 /* atribute-unchanged. */
6959 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
) ||
6960 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6961 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
6963 if (!peer_group_active(peer
) ||
6964 peergroup_af_flag_check(peer
, afi
, safi
,
6965 PEER_FLAG_AS_PATH_UNCHANGED
) ||
6966 peergroup_af_flag_check(peer
, afi
, safi
,
6967 PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6968 peergroup_af_flag_check(peer
, afi
, safi
,
6969 PEER_FLAG_MED_UNCHANGED
)) {
6972 " neighbor %s attribute-unchanged%s%s%s\n",
6974 peer_af_flag_check(peer
, afi
, safi
,
6975 PEER_FLAG_AS_PATH_UNCHANGED
)
6978 peer_af_flag_check(peer
, afi
, safi
,
6979 PEER_FLAG_NEXTHOP_UNCHANGED
)
6982 peer_af_flag_check(peer
, afi
, safi
,
6983 PEER_FLAG_MED_UNCHANGED
)
6990 /* Address family based peer configuration display. */
6991 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
6995 struct peer_group
*group
;
6996 struct listnode
*node
, *nnode
;
6999 vty_frame(vty
, " !\n address-family ");
7000 if (afi
== AFI_IP
) {
7001 if (safi
== SAFI_UNICAST
)
7002 vty_frame(vty
, "ipv4 unicast");
7003 else if (safi
== SAFI_LABELED_UNICAST
)
7004 vty_frame(vty
, "ipv4 labeled-unicast");
7005 else if (safi
== SAFI_MULTICAST
)
7006 vty_frame(vty
, "ipv4 multicast");
7007 else if (safi
== SAFI_MPLS_VPN
)
7008 vty_frame(vty
, "ipv4 vpn");
7009 else if (safi
== SAFI_ENCAP
)
7010 vty_frame(vty
, "ipv4 encap");
7011 } else if (afi
== AFI_IP6
) {
7012 if (safi
== SAFI_UNICAST
)
7013 vty_frame(vty
, "ipv6 unicast");
7014 else if (safi
== SAFI_LABELED_UNICAST
)
7015 vty_frame(vty
, "ipv6 labeled-unicast");
7016 else if (safi
== SAFI_MULTICAST
)
7017 vty_frame(vty
, "ipv6 multicast");
7018 else if (safi
== SAFI_MPLS_VPN
)
7019 vty_frame(vty
, "ipv6 vpn");
7020 else if (safi
== SAFI_ENCAP
)
7021 vty_frame(vty
, "ipv6 encap");
7022 } else if (afi
== AFI_L2VPN
) {
7023 if (safi
== SAFI_EVPN
)
7024 vty_frame(vty
, "l2vpn evpn");
7026 vty_frame(vty
, "\n");
7028 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7030 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7032 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7034 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7035 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7037 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7038 /* Skip dynamic neighbors. */
7039 if (peer_dynamic_neighbor(peer
))
7042 /* Do not display doppelganger peers */
7043 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7044 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7047 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7048 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7050 if (safi
== SAFI_EVPN
)
7051 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7053 vty_endframe(vty
, " exit-address-family\n");
7056 int bgp_config_write(struct vty
*vty
)
7060 struct peer_group
*group
;
7062 struct listnode
*node
, *nnode
;
7063 struct listnode
*mnode
, *mnnode
;
7065 /* BGP Multiple instance. */
7066 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7067 vty_out(vty
, "no bgp multiple-instance\n");
7071 /* BGP Config type. */
7072 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7073 vty_out(vty
, "bgp config-type cisco\n");
7077 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7078 vty_out(vty
, "bgp route-map delay-timer %u\n",
7079 bm
->rmap_update_timer
);
7082 vty_out(vty
, "!\n");
7084 /* BGP configuration. */
7085 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7086 /* Router bgp ASN */
7087 vty_out(vty
, "router bgp %u", bgp
->as
);
7089 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7091 vty_out(vty
, " %s %s",
7093 == BGP_INSTANCE_TYPE_VIEW
)
7100 /* No Synchronization */
7101 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7102 vty_out(vty
, " no synchronization\n");
7104 /* BGP fast-external-failover. */
7105 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7106 vty_out(vty
, " no bgp fast-external-failover\n");
7108 /* BGP router ID. */
7109 if (bgp
->router_id_static
.s_addr
!= 0)
7110 vty_out(vty
, " bgp router-id %s\n",
7111 inet_ntoa(bgp
->router_id_static
));
7113 /* BGP log-neighbor-changes. */
7114 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7115 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7116 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7118 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7122 /* BGP configuration. */
7123 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7124 vty_out(vty
, " bgp always-compare-med\n");
7126 /* BGP default ipv4-unicast. */
7127 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7128 vty_out(vty
, " no bgp default ipv4-unicast\n");
7130 /* BGP default local-preference. */
7131 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7132 vty_out(vty
, " bgp default local-preference %u\n",
7133 bgp
->default_local_pref
);
7135 /* BGP default show-hostname */
7136 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7137 != DFLT_BGP_SHOW_HOSTNAME
)
7138 vty_out(vty
, " %sbgp default show-hostname\n",
7139 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7143 /* BGP default subgroup-pkt-queue-max. */
7144 if (bgp
->default_subgroup_pkt_queue_max
7145 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7146 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7147 bgp
->default_subgroup_pkt_queue_max
);
7149 /* BGP client-to-client reflection. */
7150 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7151 vty_out(vty
, " no bgp client-to-client reflection\n");
7153 /* BGP cluster ID. */
7154 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7155 vty_out(vty
, " bgp cluster-id %s\n",
7156 inet_ntoa(bgp
->cluster_id
));
7158 /* Disable ebgp connected nexthop check */
7159 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7161 " bgp disable-ebgp-connected-route-check\n");
7163 /* Confederation identifier*/
7164 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7165 vty_out(vty
, " bgp confederation identifier %i\n",
7168 /* Confederation peer */
7169 if (bgp
->confed_peers_cnt
> 0) {
7172 vty_out(vty
, " bgp confederation peers");
7174 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7175 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7180 /* BGP enforce-first-as. */
7181 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7182 vty_out(vty
, " bgp enforce-first-as\n");
7184 /* BGP deterministic-med. */
7185 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7186 != DFLT_BGP_DETERMINISTIC_MED
)
7187 vty_out(vty
, " %sbgp deterministic-med\n",
7188 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7192 /* BGP update-delay. */
7193 bgp_config_write_update_delay(vty
, bgp
);
7195 if (bgp
->v_maxmed_onstartup
7196 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7197 vty_out(vty
, " bgp max-med on-startup %u",
7198 bgp
->v_maxmed_onstartup
);
7199 if (bgp
->maxmed_onstartup_value
7200 != BGP_MAXMED_VALUE_DEFAULT
)
7202 bgp
->maxmed_onstartup_value
);
7205 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7206 vty_out(vty
, " bgp max-med administrative");
7207 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7208 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7213 bgp_config_write_wpkt_quanta(vty
, bgp
);
7215 bgp_config_write_rpkt_quanta(vty
, bgp
);
7218 bgp_config_write_coalesce_time(vty
, bgp
);
7220 /* BGP graceful-restart. */
7221 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7223 " bgp graceful-restart stalepath-time %u\n",
7224 bgp
->stalepath_time
);
7225 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7226 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7228 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7229 vty_out(vty
, " bgp graceful-restart\n");
7231 /* BGP graceful-shutdown */
7232 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7233 vty_out(vty
, " bgp graceful-shutdown\n");
7235 /* BGP graceful-restart Preserve State F bit. */
7236 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7238 " bgp graceful-restart preserve-fw-state\n");
7240 /* BGP bestpath method. */
7241 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7242 vty_out(vty
, " bgp bestpath as-path ignore\n");
7243 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7244 vty_out(vty
, " bgp bestpath as-path confed\n");
7246 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7247 if (bgp_flag_check(bgp
,
7248 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7250 " bgp bestpath as-path multipath-relax as-set\n");
7253 " bgp bestpath as-path multipath-relax\n");
7257 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7259 " bgp route-reflector allow-outbound-policy\n");
7261 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7262 vty_out(vty
, " bgp bestpath compare-routerid\n");
7263 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7264 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7265 vty_out(vty
, " bgp bestpath med");
7266 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7267 vty_out(vty
, " confed");
7268 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7269 vty_out(vty
, " missing-as-worst");
7273 /* BGP network import check. */
7274 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7275 != DFLT_BGP_IMPORT_CHECK
)
7276 vty_out(vty
, " %sbgp network import-check\n",
7277 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7281 /* BGP flag dampening. */
7282 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7283 BGP_CONFIG_DAMPENING
))
7284 bgp_config_write_damp(vty
);
7286 /* BGP timers configuration. */
7287 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7288 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7289 vty_out(vty
, " timers bgp %u %u\n",
7290 bgp
->default_keepalive
, bgp
->default_holdtime
);
7293 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7294 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7297 /* Normal neighbor configuration. */
7298 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7299 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7300 bgp_config_write_peer_global(vty
, bgp
, peer
);
7303 /* listen range and limit for dynamic BGP neighbors */
7304 bgp_config_write_listen(vty
, bgp
);
7306 /* No auto-summary */
7307 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7308 vty_out(vty
, " no auto-summary\n");
7310 /* IPv4 unicast configuration. */
7311 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7313 /* IPv4 multicast configuration. */
7314 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7316 /* IPv4 labeled-unicast configuration. */
7317 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7319 /* IPv4 VPN configuration. */
7320 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7322 /* ENCAPv4 configuration. */
7323 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7325 /* IPv6 unicast configuration. */
7326 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7328 /* IPv6 multicast configuration. */
7329 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7331 /* IPv6 labeled-unicast configuration. */
7332 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7333 SAFI_LABELED_UNICAST
);
7335 /* IPv6 VPN configuration. */
7336 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7338 /* ENCAPv6 configuration. */
7339 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7341 /* EVPN configuration. */
7342 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7345 bgp_rfapi_cfg_write(vty
, bgp
);
7348 vty_out(vty
, "!\n");
7353 void bgp_master_init(struct thread_master
*master
)
7357 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7360 bm
->bgp
= list_new();
7361 bm
->listen_sockets
= list_new();
7362 bm
->port
= BGP_PORT_DEFAULT
;
7363 bm
->master
= master
;
7364 bm
->start_time
= bgp_clock();
7365 bm
->t_rmap_update
= NULL
;
7366 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7368 bgp_process_queue_init();
7370 /* Enable multiple instances by default. */
7371 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7373 QOBJ_REG(bm
, bgp_master
);
7377 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7378 * instance delete (non-default only) or BGP exit.
7380 static void bgp_if_finish(struct bgp
*bgp
)
7382 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7383 struct interface
*ifp
;
7385 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7388 FOR_ALL_INTERFACES (vrf
, ifp
) {
7389 struct listnode
*c_node
, *c_nnode
;
7390 struct connected
*c
;
7392 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7393 bgp_connected_delete(bgp
, c
);
7397 extern void bgp_snmp_init(void);
7399 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7401 struct vrf
*vrf
= NULL
;
7402 struct listnode
*next
;
7405 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7406 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7407 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7410 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7411 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7414 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7418 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7419 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7420 {.completions
= NULL
},
7423 static void bgp_pthreads_init()
7427 frr_pthread_new("BGP i/o thread", PTHREAD_IO
, bgp_io_start
,
7429 frr_pthread_new("BGP keepalives thread", PTHREAD_KEEPALIVES
,
7430 bgp_keepalives_start
, bgp_keepalives_stop
);
7432 /* pre-run initialization */
7433 bgp_keepalives_init();
7437 void bgp_pthreads_run()
7439 pthread_attr_t attr
;
7440 pthread_attr_init(&attr
);
7441 pthread_attr_setschedpolicy(&attr
, SCHED_FIFO
);
7444 * Please ensure that the io thread is running
7445 * by calling bgp_io_running. The BGP threads
7446 * depend on it being running when we start
7449 frr_pthread_run(PTHREAD_IO
, &attr
, NULL
);
7452 frr_pthread_run(PTHREAD_KEEPALIVES
, &attr
, NULL
);
7455 void bgp_pthreads_finish()
7457 frr_pthread_stop_all();
7458 frr_pthread_finish();
7464 /* allocates some vital data structures used by peer commands in
7467 /* pre-init pthreads */
7468 bgp_pthreads_init();
7471 bgp_zebra_init(bm
->master
);
7474 vnc_zebra_init(bm
->master
);
7477 /* BGP VTY commands installation. */
7485 bgp_route_map_init();
7486 bgp_scan_vty_init();
7491 bgp_ethernetvpn_init();
7493 /* Access list initialize. */
7495 access_list_add_hook(peer_distribute_update
);
7496 access_list_delete_hook(peer_distribute_update
);
7498 /* Filter list initialize. */
7500 as_list_add_hook(peer_aslist_add
);
7501 as_list_delete_hook(peer_aslist_del
);
7503 /* Prefix list initialize.*/
7505 prefix_list_add_hook(peer_prefix_list_update
);
7506 prefix_list_delete_hook(peer_prefix_list_update
);
7508 /* Community list initialize. */
7509 bgp_clist
= community_list_init();
7514 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7517 void bgp_terminate(void)
7521 struct listnode
*node
, *nnode
;
7522 struct listnode
*mnode
, *mnnode
;
7526 /* Close the listener sockets first as this prevents peers from
7528 * to reconnect on receiving the peer unconfig message. In the presence
7529 * of a large number of peers this will ensure that no peer is left with
7530 * a dangling connection
7532 /* reverse bgp_master_init */
7534 if (bm
->listen_sockets
)
7535 list_delete_and_null(&bm
->listen_sockets
);
7537 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7538 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7539 if (peer
->status
== Established
7540 || peer
->status
== OpenSent
7541 || peer
->status
== OpenConfirm
)
7542 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7543 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7545 if (bm
->process_main_queue
) {
7546 work_queue_free(bm
->process_main_queue
);
7547 bm
->process_main_queue
= NULL
;
7550 if (bm
->t_rmap_update
)
7551 BGP_TIMER_OFF(bm
->t_rmap_update
);