1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "sockunion.h"
37 #include "workqueue.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_aspath.h"
49 #include "bgpd/bgp_route.h"
50 #include "bgpd/bgp_dump.h"
51 #include "bgpd/bgp_debug.h"
52 #include "bgpd/bgp_community.h"
53 #include "bgpd/bgp_attr.h"
54 #include "bgpd/bgp_regex.h"
55 #include "bgpd/bgp_clist.h"
56 #include "bgpd/bgp_fsm.h"
57 #include "bgpd/bgp_packet.h"
58 #include "bgpd/bgp_zebra.h"
59 #include "bgpd/bgp_open.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_nexthop.h"
62 #include "bgpd/bgp_damp.h"
63 #include "bgpd/bgp_mplsvpn.h"
65 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
66 #include "bgpd/rfapi/rfapi_backend.h"
68 #include "bgpd/bgp_evpn.h"
69 #include "bgpd/bgp_advertise.h"
70 #include "bgpd/bgp_network.h"
71 #include "bgpd/bgp_vty.h"
72 #include "bgpd/bgp_mpath.h"
73 #include "bgpd/bgp_nht.h"
74 #include "bgpd/bgp_updgrp.h"
75 #include "bgpd/bgp_bfd.h"
76 #include "bgpd/bgp_memory.h"
77 #include "bgpd/bgp_evpn_vty.h"
80 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
81 DEFINE_QOBJ_TYPE(bgp_master
)
83 DEFINE_QOBJ_TYPE(peer
)
85 /* BGP process wide configuration. */
86 static struct bgp_master bgp_master
;
88 /* BGP process wide configuration pointer to export. */
89 struct bgp_master
*bm
;
91 /* BGP community-list. */
92 struct community_list_handler
*bgp_clist
;
94 unsigned int multipath_num
= MULTIPATH_NUM
;
96 static void bgp_if_finish(struct bgp
*bgp
);
98 extern struct zclient
*zclient
;
100 void bgp_session_reset(struct peer
*peer
)
102 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
103 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
104 peer_delete(peer
->doppelganger
);
106 BGP_EVENT_ADD(peer
, BGP_Stop
);
110 * During session reset, we may delete the doppelganger peer, which would
111 * be the next node to the current node. If the session reset was invoked
112 * during walk of peer list, we would end up accessing the freed next
113 * node. This function moves the next node along.
115 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
120 n
= (nnode
) ? *nnode
: NULL
;
121 npeer
= (n
) ? listgetdata(n
) : NULL
;
123 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
124 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
125 PEER_FLAG_CONFIG_NODE
))) {
126 if (peer
->doppelganger
== npeer
)
127 /* nnode and *nnode are confirmed to be non-NULL here */
128 *nnode
= (*nnode
)->next
;
129 peer_delete(peer
->doppelganger
);
132 BGP_EVENT_ADD(peer
, BGP_Stop
);
135 /* BGP global flag manipulation. */
136 int bgp_option_set(int flag
)
140 case BGP_OPT_MULTIPLE_INSTANCE
:
141 case BGP_OPT_CONFIG_CISCO
:
142 case BGP_OPT_NO_LISTEN
:
143 SET_FLAG(bm
->options
, flag
);
146 return BGP_ERR_INVALID_FLAG
;
151 int bgp_option_unset(int flag
)
154 case BGP_OPT_MULTIPLE_INSTANCE
:
155 if (listcount(bm
->bgp
) > 1)
156 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
159 case BGP_OPT_CONFIG_CISCO
:
160 UNSET_FLAG(bm
->options
, flag
);
163 return BGP_ERR_INVALID_FLAG
;
168 int bgp_option_check(int flag
)
170 return CHECK_FLAG(bm
->options
, flag
);
173 /* BGP flag manipulation. */
174 int bgp_flag_set(struct bgp
*bgp
, int flag
)
176 SET_FLAG(bgp
->flags
, flag
);
180 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
182 UNSET_FLAG(bgp
->flags
, flag
);
186 int bgp_flag_check(struct bgp
*bgp
, int flag
)
188 return CHECK_FLAG(bgp
->flags
, flag
);
191 /* Internal function to set BGP structure configureation flag. */
192 static void bgp_config_set(struct bgp
*bgp
, int config
)
194 SET_FLAG(bgp
->config
, config
);
197 static void bgp_config_unset(struct bgp
*bgp
, int config
)
199 UNSET_FLAG(bgp
->config
, config
);
202 static int bgp_config_check(struct bgp
*bgp
, int config
)
204 return CHECK_FLAG(bgp
->config
, config
);
207 /* Set BGP router identifier. */
208 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
211 struct listnode
*node
, *nnode
;
213 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
216 /* EVPN uses router id in RD, withdraw them */
217 if (bgp
->advertise_all_vni
)
218 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
220 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
222 /* Set all peer's local identifier with this value. */
223 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
224 IPV4_ADDR_COPY(&peer
->local_id
, id
);
226 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
227 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
228 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
229 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
233 /* EVPN uses router id in RD, update them */
234 if (bgp
->advertise_all_vni
)
235 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
240 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
242 struct listnode
*node
, *nnode
;
245 if (vrf_id
== VRF_DEFAULT
) {
246 /* Router-id change for default VRF has to also update all
248 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
249 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
252 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
253 if (!bgp
->router_id_static
.s_addr
)
254 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
257 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
259 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
261 if (!bgp
->router_id_static
.s_addr
)
262 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
267 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
269 bgp
->router_id_static
= id
;
270 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
274 /* BGP's cluster-id control. */
275 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
278 struct listnode
*node
, *nnode
;
280 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
281 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
284 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
285 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
287 /* Clear all IBGP peer. */
288 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
289 if (peer
->sort
!= BGP_PEER_IBGP
)
292 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
293 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
294 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
295 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
301 int bgp_cluster_id_unset(struct bgp
*bgp
)
304 struct listnode
*node
, *nnode
;
306 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
309 bgp
->cluster_id
.s_addr
= 0;
310 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
312 /* Clear all IBGP peer. */
313 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
314 if (peer
->sort
!= BGP_PEER_IBGP
)
317 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
318 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
319 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
320 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
326 /* time_t value that is monotonicly increasing
327 * and uneffected by adjustments to system clock
329 time_t bgp_clock(void)
337 /* BGP timer configuration. */
338 int bgp_timers_set(struct bgp
*bgp
, u_int32_t keepalive
, u_int32_t holdtime
)
340 bgp
->default_keepalive
=
341 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
342 bgp
->default_holdtime
= holdtime
;
347 int bgp_timers_unset(struct bgp
*bgp
)
349 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
350 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
355 /* BGP confederation configuration. */
356 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
359 struct listnode
*node
, *nnode
;
363 return BGP_ERR_INVALID_AS
;
365 /* Remember - were we doing confederation before? */
366 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
368 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
370 /* If we were doing confederation already, this is just an external
371 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
372 were not doing confederation before, reset all EBGP sessions. */
373 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
374 /* We're looking for peers who's AS is not local or part of our
376 if (already_confed
) {
377 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
379 if (BGP_IS_VALID_STATE_FOR_NOTIF(
382 PEER_DOWN_CONFED_ID_CHANGE
;
384 peer
, BGP_NOTIFY_CEASE
,
385 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
387 bgp_session_reset_safe(peer
, &nnode
);
390 /* Not doign confederation before, so reset every
393 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
394 /* Reset the local_as to be our EBGP one */
395 if (peer_sort(peer
) == BGP_PEER_EBGP
)
397 if (BGP_IS_VALID_STATE_FOR_NOTIF(
400 PEER_DOWN_CONFED_ID_CHANGE
;
402 peer
, BGP_NOTIFY_CEASE
,
403 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
405 bgp_session_reset_safe(peer
, &nnode
);
412 int bgp_confederation_id_unset(struct bgp
*bgp
)
415 struct listnode
*node
, *nnode
;
418 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
420 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
421 /* We're looking for peers who's AS is not local */
422 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
423 peer
->local_as
= bgp
->as
;
424 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
425 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
426 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
427 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
431 bgp_session_reset_safe(peer
, &nnode
);
437 /* Is an AS part of the confed or not? */
438 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
445 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
446 if (bgp
->confed_peers
[i
] == as
)
452 /* Add an AS to the confederation set. */
453 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
456 struct listnode
*node
, *nnode
;
459 return BGP_ERR_INVALID_BGP
;
462 return BGP_ERR_INVALID_AS
;
464 if (bgp_confederation_peers_check(bgp
, as
))
467 if (bgp
->confed_peers
)
469 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
470 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
473 XMALLOC(MTYPE_BGP_CONFED_LIST
,
474 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
476 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
477 bgp
->confed_peers_cnt
++;
479 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
480 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
481 if (peer
->as
== as
) {
482 peer
->local_as
= bgp
->as
;
483 if (BGP_IS_VALID_STATE_FOR_NOTIF(
486 PEER_DOWN_CONFED_PEER_CHANGE
;
488 peer
, BGP_NOTIFY_CEASE
,
489 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
491 bgp_session_reset_safe(peer
, &nnode
);
498 /* Delete an AS from the confederation set. */
499 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
504 struct listnode
*node
, *nnode
;
509 if (!bgp_confederation_peers_check(bgp
, as
))
512 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
513 if (bgp
->confed_peers
[i
] == as
)
514 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
515 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
517 bgp
->confed_peers_cnt
--;
519 if (bgp
->confed_peers_cnt
== 0) {
520 if (bgp
->confed_peers
)
521 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
522 bgp
->confed_peers
= NULL
;
525 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
526 bgp
->confed_peers_cnt
* sizeof(as_t
));
528 /* Now reset any peer who's remote AS has just been removed from the
530 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
531 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
532 if (peer
->as
== as
) {
533 peer
->local_as
= bgp
->confed_id
;
534 if (BGP_IS_VALID_STATE_FOR_NOTIF(
537 PEER_DOWN_CONFED_PEER_CHANGE
;
539 peer
, BGP_NOTIFY_CEASE
,
540 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
542 bgp_session_reset_safe(peer
, &nnode
);
550 /* Local preference configuration. */
551 int bgp_default_local_preference_set(struct bgp
*bgp
, u_int32_t local_pref
)
556 bgp
->default_local_pref
= local_pref
;
561 int bgp_default_local_preference_unset(struct bgp
*bgp
)
566 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
571 /* Local preference configuration. */
572 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
,
573 u_int32_t queue_size
)
578 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
583 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
587 bgp
->default_subgroup_pkt_queue_max
=
588 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
593 /* Listen limit configuration. */
594 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
599 bgp
->dynamic_neighbors_limit
= listen_limit
;
604 int bgp_listen_limit_unset(struct bgp
*bgp
)
609 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
614 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
615 afi_t
*afi
, safi_t
*safi
)
617 /* Map from IANA values to internal values, return error if
618 * values are unrecognized.
620 *afi
= afi_iana2int(pkt_afi
);
621 *safi
= safi_iana2int(pkt_safi
);
622 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
628 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
629 iana_safi_t
*pkt_safi
)
631 /* Map from internal values to IANA values, return error if
632 * internal values are bad (unexpected).
634 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
636 *pkt_afi
= afi_int2iana(afi
);
637 *pkt_safi
= safi_int2iana(safi
);
641 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
649 afid
= afindex(afi
, safi
);
650 if (afid
>= BGP_AF_MAX
)
653 assert(peer
->peer_af_array
[afid
] == NULL
);
655 /* Allocate new peer af */
656 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
659 zlog_err("Could not create af structure for peer %s",
664 peer
->peer_af_array
[afid
] = af
;
673 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
680 afid
= afindex(afi
, safi
);
681 if (afid
>= BGP_AF_MAX
)
684 return peer
->peer_af_array
[afid
];
687 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
695 afid
= afindex(afi
, safi
);
696 if (afid
>= BGP_AF_MAX
)
699 af
= peer
->peer_af_array
[afid
];
703 bgp_stop_announce_route_timer(af
);
705 if (PAF_SUBGRP(af
)) {
706 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
707 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
708 af
->subgroup
->update_group
->id
,
709 af
->subgroup
->id
, peer
->host
);
712 update_subgroup_remove_peer(af
->subgroup
, af
);
714 peer
->peer_af_array
[afid
] = NULL
;
715 XFREE(MTYPE_BGP_PEER_AF
, af
);
719 /* Peer comparison function for sorting. */
720 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
722 if (p1
->group
&& !p2
->group
)
725 if (!p1
->group
&& p2
->group
)
728 if (p1
->group
== p2
->group
) {
729 if (p1
->conf_if
&& !p2
->conf_if
)
732 if (!p1
->conf_if
&& p2
->conf_if
)
735 if (p1
->conf_if
&& p2
->conf_if
)
736 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
738 return strcmp(p1
->group
->name
, p2
->group
->name
);
740 return sockunion_cmp(&p1
->su
, &p2
->su
);
743 static unsigned int peer_hash_key_make(void *p
)
745 struct peer
*peer
= p
;
746 return sockunion_hash(&peer
->su
);
749 static int peer_hash_same(const void *p1
, const void *p2
)
751 const struct peer
*peer1
= p1
;
752 const struct peer
*peer2
= p2
;
753 return (sockunion_same(&peer1
->su
, &peer2
->su
)
754 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
755 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
758 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
761 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
764 /* Return true if flag is set for the peer but not the peer-group */
765 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
768 struct peer
*g_peer
= NULL
;
770 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
771 if (peer_group_active(peer
)) {
772 g_peer
= peer
->group
->conf
;
774 /* If this flag is not set for the peer's peer-group
775 * then return true */
776 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
781 /* peer is not in a peer-group but the flag is set to return
791 /* Reset all address family specific configuration. */
792 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
795 struct bgp_filter
*filter
;
796 char orf_name
[BUFSIZ
];
798 filter
= &peer
->filter
[afi
][safi
];
800 /* Clear neighbor filter and route-map */
801 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
802 if (filter
->dlist
[i
].name
) {
803 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
804 filter
->dlist
[i
].name
= NULL
;
806 if (filter
->plist
[i
].name
) {
807 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
808 filter
->plist
[i
].name
= NULL
;
810 if (filter
->aslist
[i
].name
) {
811 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
812 filter
->aslist
[i
].name
= NULL
;
815 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
816 if (filter
->map
[i
].name
) {
817 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
818 filter
->map
[i
].name
= NULL
;
822 /* Clear unsuppress map. */
823 if (filter
->usmap
.name
)
824 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
825 filter
->usmap
.name
= NULL
;
826 filter
->usmap
.map
= NULL
;
828 /* Clear neighbor's all address family flags. */
829 peer
->af_flags
[afi
][safi
] = 0;
831 /* Clear neighbor's all address family sflags. */
832 peer
->af_sflags
[afi
][safi
] = 0;
834 /* Clear neighbor's all address family capabilities. */
835 peer
->af_cap
[afi
][safi
] = 0;
838 peer
->orf_plist
[afi
][safi
] = NULL
;
839 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
840 prefix_bgp_orf_remove_all(afi
, orf_name
);
842 /* Set default neighbor send-community. */
843 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
844 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
845 SET_FLAG(peer
->af_flags
[afi
][safi
],
846 PEER_FLAG_SEND_EXT_COMMUNITY
);
847 SET_FLAG(peer
->af_flags
[afi
][safi
],
848 PEER_FLAG_SEND_LARGE_COMMUNITY
);
851 /* Clear neighbor default_originate_rmap */
852 if (peer
->default_rmap
[afi
][safi
].name
)
853 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
854 peer
->default_rmap
[afi
][safi
].name
= NULL
;
855 peer
->default_rmap
[afi
][safi
].map
= NULL
;
857 /* Clear neighbor maximum-prefix */
858 peer
->pmax
[afi
][safi
] = 0;
859 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
862 /* peer global config reset */
863 static void peer_global_config_reset(struct peer
*peer
)
868 peer
->change_local_as
= 0;
869 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
870 if (peer
->update_source
) {
871 sockunion_free(peer
->update_source
);
872 peer
->update_source
= NULL
;
874 if (peer
->update_if
) {
875 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
876 peer
->update_if
= NULL
;
879 if (peer_sort(peer
) == BGP_PEER_IBGP
)
880 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
882 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
884 /* This is a per-peer specific flag and so we must preserve it */
885 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
890 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
896 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
898 /* Reset some other configs back to defaults. */
899 peer
->v_start
= BGP_INIT_START_TIMER
;
900 peer
->password
= NULL
;
901 peer
->local_id
= peer
->bgp
->router_id
;
902 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
903 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
905 bfd_info_free(&(peer
->bfd_info
));
907 /* Set back the CONFIG_NODE flag. */
908 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
911 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
912 static bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
919 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
920 if (peer
->as_type
== AS_INTERNAL
)
921 return BGP_PEER_IBGP
;
923 else if (peer
->as_type
== AS_EXTERNAL
)
924 return BGP_PEER_EBGP
;
926 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
927 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
932 peer1
= listnode_head(peer
->group
->peer
);
937 return BGP_PEER_INTERNAL
;
941 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
942 if (peer
->local_as
== 0)
943 return BGP_PEER_INTERNAL
;
945 if (peer
->local_as
== peer
->as
) {
946 if (bgp
->as
== bgp
->confed_id
) {
947 if (peer
->local_as
== bgp
->as
)
948 return BGP_PEER_IBGP
;
950 return BGP_PEER_EBGP
;
952 if (peer
->local_as
== bgp
->confed_id
)
953 return BGP_PEER_EBGP
;
955 return BGP_PEER_IBGP
;
959 if (bgp_confederation_peers_check(bgp
, peer
->as
))
960 return BGP_PEER_CONFED
;
962 return BGP_PEER_EBGP
;
964 if (peer
->as_type
!= AS_SPECIFIED
)
965 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
968 return (peer
->local_as
== 0
970 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
975 /* Calculate and cache the peer "sort" */
976 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
978 peer
->sort
= peer_calc_sort(peer
);
982 static void peer_free(struct peer
*peer
)
984 assert(peer
->status
== Deleted
);
988 /* this /ought/ to have been done already through bgp_stop earlier,
989 * but just to be sure..
992 BGP_READ_OFF(peer
->t_read
);
993 BGP_WRITE_OFF(peer
->t_write
);
994 BGP_EVENT_FLUSH(peer
);
996 /* Free connected nexthop, if present */
997 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
998 && !peer_dynamic_neighbor(peer
))
999 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1002 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1005 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1009 /* Free allocated host character. */
1011 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1015 if (peer
->domainname
) {
1016 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1017 peer
->domainname
= NULL
;
1021 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1022 peer
->ifname
= NULL
;
1025 /* Update source configuration. */
1026 if (peer
->update_source
) {
1027 sockunion_free(peer
->update_source
);
1028 peer
->update_source
= NULL
;
1031 if (peer
->update_if
) {
1032 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1033 peer
->update_if
= NULL
;
1036 if (peer
->notify
.data
)
1037 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1038 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1040 if (peer
->clear_node_queue
) {
1041 work_queue_free(peer
->clear_node_queue
);
1042 peer
->clear_node_queue
= NULL
;
1045 bgp_sync_delete(peer
);
1047 if (peer
->conf_if
) {
1048 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1049 peer
->conf_if
= NULL
;
1052 bfd_info_free(&(peer
->bfd_info
));
1054 bgp_unlock(peer
->bgp
);
1056 memset(peer
, 0, sizeof(struct peer
));
1058 XFREE(MTYPE_BGP_PEER
, peer
);
1061 /* increase reference count on a struct peer */
1062 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1064 assert(peer
&& (peer
->lock
>= 0));
1067 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1075 /* decrease reference count on a struct peer
1076 * struct peer is freed and NULL returned if last reference
1078 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1080 assert(peer
&& (peer
->lock
> 0));
1083 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1088 if (peer
->lock
== 0) {
1096 /* Allocate new peer object, implicitely locked. */
1097 struct peer
*peer_new(struct bgp
*bgp
)
1104 /* bgp argument is absolutely required */
1109 /* Allocate new peer. */
1110 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1112 /* Set default value. */
1114 peer
->v_start
= BGP_INIT_START_TIMER
;
1115 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1116 peer
->status
= Idle
;
1117 peer
->ostatus
= Idle
;
1118 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1119 peer
->bgp
= bgp_lock(bgp
);
1120 peer
= peer_lock(peer
); /* initial reference */
1121 peer
->password
= NULL
;
1123 /* Set default flags. */
1124 FOREACH_AFI_SAFI (afi
, safi
) {
1125 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1126 SET_FLAG(peer
->af_flags
[afi
][safi
],
1127 PEER_FLAG_SEND_COMMUNITY
);
1128 SET_FLAG(peer
->af_flags
[afi
][safi
],
1129 PEER_FLAG_SEND_EXT_COMMUNITY
);
1130 SET_FLAG(peer
->af_flags
[afi
][safi
],
1131 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1133 peer
->orf_plist
[afi
][safi
] = NULL
;
1135 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1137 /* Create buffers. */
1138 peer
->ibuf
= stream_new(BGP_MAX_PACKET_SIZE
);
1139 peer
->obuf
= stream_fifo_new();
1141 /* We use a larger buffer for peer->work in the event that:
1142 * - We RX a BGP_UPDATE where the attributes alone are just
1143 * under BGP_MAX_PACKET_SIZE
1144 * - The user configures an outbound route-map that does many as-path
1145 * prepends or adds many communities. At most they can have
1147 * args in a route-map so there is a finite limit on how large they
1149 * make the attributes.
1151 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1153 * checking for every single attribute as we construct an UPDATE.
1156 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1157 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1160 bgp_sync_init(peer
);
1162 /* Get service port number. */
1163 sp
= getservbyname("bgp", "tcp");
1164 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1166 QOBJ_REG(peer
, peer
);
1171 * This function is invoked when a duplicate peer structure associated with
1172 * a neighbor is being deleted. If this about-to-be-deleted structure is
1173 * the one with all the config, then we have to copy over the info.
1175 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1177 struct peer_af
*paf
;
1185 /* The following function is used by both peer group config copy to
1186 * individual peer and when we transfer config
1188 if (peer_src
->change_local_as
)
1189 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1191 /* peer flags apply */
1192 peer_dst
->flags
= peer_src
->flags
;
1193 peer_dst
->cap
= peer_src
->cap
;
1194 peer_dst
->config
= peer_src
->config
;
1196 peer_dst
->local_as
= peer_src
->local_as
;
1197 peer_dst
->ifindex
= peer_src
->ifindex
;
1198 peer_dst
->port
= peer_src
->port
;
1199 peer_sort(peer_dst
);
1200 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1203 peer_dst
->holdtime
= peer_src
->holdtime
;
1204 peer_dst
->keepalive
= peer_src
->keepalive
;
1205 peer_dst
->connect
= peer_src
->connect
;
1206 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1207 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1208 peer_dst
->routeadv
= peer_src
->routeadv
;
1209 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1211 /* password apply */
1212 if (peer_src
->password
&& !peer_dst
->password
)
1213 peer_dst
->password
=
1214 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1216 FOREACH_AFI_SAFI (afi
, safi
) {
1217 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1218 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1219 peer_dst
->allowas_in
[afi
][safi
] =
1220 peer_src
->allowas_in
[afi
][safi
];
1221 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1224 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1225 paf
= peer_src
->peer_af_array
[afidx
];
1227 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1230 /* update-source apply */
1231 if (peer_src
->update_source
) {
1232 if (peer_dst
->update_source
)
1233 sockunion_free(peer_dst
->update_source
);
1234 if (peer_dst
->update_if
) {
1235 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1236 peer_dst
->update_if
= NULL
;
1238 peer_dst
->update_source
=
1239 sockunion_dup(peer_src
->update_source
);
1240 } else if (peer_src
->update_if
) {
1241 if (peer_dst
->update_if
)
1242 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1243 if (peer_dst
->update_source
) {
1244 sockunion_free(peer_dst
->update_source
);
1245 peer_dst
->update_source
= NULL
;
1247 peer_dst
->update_if
=
1248 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1251 if (peer_src
->ifname
) {
1252 if (peer_dst
->ifname
)
1253 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1256 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1260 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1261 struct interface
*ifp
)
1263 struct connected
*ifc
;
1266 struct listnode
*node
;
1268 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1269 * IPv4 address of the other end.
1271 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1272 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1273 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1274 if (p
.prefixlen
== 30) {
1275 peer
->su
.sa
.sa_family
= AF_INET
;
1276 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1278 peer
->su
.sin
.sin_addr
.s_addr
=
1280 else if (addr
% 4 == 2)
1281 peer
->su
.sin
.sin_addr
.s_addr
=
1283 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1284 peer
->su
.sin
.sin_len
=
1285 sizeof(struct sockaddr_in
);
1286 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1288 } else if (p
.prefixlen
== 31) {
1289 peer
->su
.sa
.sa_family
= AF_INET
;
1290 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1292 peer
->su
.sin
.sin_addr
.s_addr
=
1295 peer
->su
.sin
.sin_addr
.s_addr
=
1297 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1298 peer
->su
.sin
.sin_len
=
1299 sizeof(struct sockaddr_in
);
1300 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1302 } else if (bgp_debug_neighbor_events(peer
))
1304 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1312 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1313 struct interface
*ifp
)
1315 struct nbr_connected
*ifc_nbr
;
1317 /* Have we learnt the peer's IPv6 link-local address? */
1318 if (ifp
->nbr_connected
1319 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1320 peer
->su
.sa
.sa_family
= AF_INET6
;
1321 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1322 sizeof(struct in6_addr
));
1324 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1326 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1334 * Set or reset the peer address socketunion structure based on the
1335 * learnt/derived peer address. If the address has changed, update the
1336 * password on the listen socket, if needed.
1338 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1340 struct interface
*ifp
;
1342 int peer_addr_updated
= 0;
1347 prev_family
= peer
->su
.sa
.sa_family
;
1348 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1350 /* If BGP unnumbered is not "v6only", we first see if we can
1352 * peer's IPv4 address.
1354 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1356 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1358 /* If "v6only" or we can't derive peer's IPv4 address, see if
1360 * learnt the peer's IPv6 link-local address. This is from the
1362 * IPv6 address in router advertisement.
1364 if (!peer_addr_updated
)
1366 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1368 /* If we could derive the peer address, we may need to install the
1370 * configured for the peer, if any, on the listen socket. Otherwise,
1372 * that peer's address is not available and uninstall the password, if
1375 if (peer_addr_updated
) {
1376 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1379 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1380 bgp_md5_unset(peer
);
1381 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1382 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1385 /* Since our su changed we need to del/add peer to the peerhash */
1386 hash_release(peer
->bgp
->peerhash
, peer
);
1387 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1390 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1393 struct bgp_node
*rn
, *nrn
;
1395 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1396 rn
= bgp_route_next(rn
)) {
1397 if (rn
->info
!= NULL
) {
1398 /* Special handling for 2-level routing
1400 if (safi
== SAFI_MPLS_VPN
1401 || safi
== SAFI_ENCAP
1402 || safi
== SAFI_EVPN
) {
1403 for (nrn
= bgp_table_top((
1407 nrn
= bgp_route_next(nrn
))
1408 bgp_process(bgp
, nrn
,
1411 bgp_process(bgp
, rn
, afi
, safi
);
1416 /* Force a bestpath recalculation for all prefixes. This is used
1417 * when 'bgp bestpath' commands are entered.
1419 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1424 FOREACH_AFI_SAFI (afi
, safi
) {
1425 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1429 /* Create new BGP peer. */
1430 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1431 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1432 int as_type
, afi_t afi
, safi_t safi
,
1433 struct peer_group
*group
)
1437 char buf
[SU_ADDRSTRLEN
];
1439 peer
= peer_new(bgp
);
1441 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1442 bgp_peer_conf_if_to_su_update(peer
);
1444 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1445 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1448 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1450 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1451 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1453 peer
->local_as
= local_as
;
1454 peer
->as
= remote_as
;
1455 peer
->as_type
= as_type
;
1456 peer
->local_id
= bgp
->router_id
;
1457 peer
->v_holdtime
= bgp
->default_holdtime
;
1458 peer
->v_keepalive
= bgp
->default_keepalive
;
1459 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1460 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1462 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1464 peer
= peer_lock(peer
); /* bgp peer list reference */
1465 peer
->group
= group
;
1466 listnode_add_sort(bgp
->peer
, peer
);
1467 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1469 active
= peer_active(peer
);
1471 /* Last read and reset time set */
1472 peer
->readtime
= peer
->resettime
= bgp_clock();
1474 /* Default TTL set. */
1475 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1477 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1480 peer
->afc
[afi
][safi
] = 1;
1481 peer_af_create(peer
, afi
, safi
);
1484 /* Set up peer's events and timers. */
1485 if (!active
&& peer_active(peer
))
1486 bgp_timer_set(peer
);
1491 /* Make accept BGP peer. This function is only called from the test code */
1492 struct peer
*peer_create_accept(struct bgp
*bgp
)
1496 peer
= peer_new(bgp
);
1498 peer
= peer_lock(peer
); /* bgp peer list reference */
1499 listnode_add_sort(bgp
->peer
, peer
);
1505 * Return true if we have a peer configured to use this afi/safi
1507 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1509 struct listnode
*node
;
1512 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1513 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1516 if (peer
->afc
[afi
][safi
])
1523 /* Change peer's AS number. */
1524 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1526 bgp_peer_sort_t type
;
1530 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1531 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1532 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1533 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1534 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1536 bgp_session_reset(peer
);
1538 type
= peer_sort(peer
);
1540 peer
->as_type
= as_specified
;
1542 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1543 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1544 && peer
->bgp
->as
!= as
)
1545 peer
->local_as
= peer
->bgp
->confed_id
;
1547 peer
->local_as
= peer
->bgp
->as
;
1549 /* Advertisement-interval reset */
1552 conf
= peer
->group
->conf
;
1554 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1555 peer
->v_routeadv
= conf
->routeadv
;
1557 /* Only go back to the default advertisement-interval if the user had
1559 * already configured it */
1560 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1561 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1562 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1564 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1567 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1569 else if (type
== BGP_PEER_IBGP
)
1572 /* reflector-client reset */
1573 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1574 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1575 PEER_FLAG_REFLECTOR_CLIENT
);
1576 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1577 PEER_FLAG_REFLECTOR_CLIENT
);
1578 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1579 PEER_FLAG_REFLECTOR_CLIENT
);
1580 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1581 PEER_FLAG_REFLECTOR_CLIENT
);
1582 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1583 PEER_FLAG_REFLECTOR_CLIENT
);
1584 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1585 PEER_FLAG_REFLECTOR_CLIENT
);
1586 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1587 PEER_FLAG_REFLECTOR_CLIENT
);
1588 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1589 PEER_FLAG_REFLECTOR_CLIENT
);
1590 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1591 PEER_FLAG_REFLECTOR_CLIENT
);
1592 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1593 PEER_FLAG_REFLECTOR_CLIENT
);
1594 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1595 PEER_FLAG_REFLECTOR_CLIENT
);
1598 /* local-as reset */
1599 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1600 peer
->change_local_as
= 0;
1601 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1602 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1606 /* If peer does not exist, create new one. If peer already exists,
1607 set AS number to the peer. */
1608 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1609 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1615 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1617 peer
= peer_lookup(bgp
, su
);
1620 /* Not allowed for a dynamic peer. */
1621 if (peer_dynamic_neighbor(peer
)) {
1623 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1626 /* When this peer is a member of peer-group. */
1628 if (peer
->group
->conf
->as
) {
1629 /* Return peer group's AS number. */
1630 *as
= peer
->group
->conf
->as
;
1631 return BGP_ERR_PEER_GROUP_MEMBER
;
1633 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1634 if ((as_type
!= AS_INTERNAL
)
1635 && (bgp
->as
!= *as
)) {
1637 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1640 if ((as_type
!= AS_EXTERNAL
)
1641 && (bgp
->as
== *as
)) {
1643 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1648 /* Existing peer's AS number change. */
1649 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1650 || (peer
->as_type
!= as_type
))
1651 peer_as_change(peer
, *as
, as_type
);
1654 return BGP_ERR_NO_INTERFACE_CONFIG
;
1656 /* If the peer is not part of our confederation, and its not an
1657 iBGP peer then spoof the source AS */
1658 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1659 && !bgp_confederation_peers_check(bgp
, *as
)
1661 local_as
= bgp
->confed_id
;
1665 /* If this is IPv4 unicast configuration and "no bgp default
1666 ipv4-unicast" is specified. */
1668 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1669 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1670 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1673 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1680 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1681 struct peer
*peer
, afi_t afi
,
1685 int out
= FILTER_OUT
;
1687 struct bgp_filter
*pfilter
;
1688 struct bgp_filter
*gfilter
;
1691 pfilter
= &peer
->filter
[afi
][safi
];
1692 gfilter
= &conf
->filter
[afi
][safi
];
1694 /* peer af_flags apply */
1695 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1697 /* maximum-prefix */
1698 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1699 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1700 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1703 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1706 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1708 /* default-originate route-map */
1709 if (conf
->default_rmap
[afi
][safi
].name
) {
1710 if (peer
->default_rmap
[afi
][safi
].name
)
1711 XFREE(MTYPE_BGP_FILTER_NAME
,
1712 peer
->default_rmap
[afi
][safi
].name
);
1713 peer
->default_rmap
[afi
][safi
].name
=
1714 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1715 conf
->default_rmap
[afi
][safi
].name
);
1716 peer
->default_rmap
[afi
][safi
].map
=
1717 conf
->default_rmap
[afi
][safi
].map
;
1720 /* inbound filter apply */
1721 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1722 if (pfilter
->dlist
[in
].name
)
1723 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1724 pfilter
->dlist
[in
].name
=
1725 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1726 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1729 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1730 if (pfilter
->plist
[in
].name
)
1731 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1732 pfilter
->plist
[in
].name
=
1733 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1734 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1737 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1738 if (pfilter
->aslist
[in
].name
)
1739 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1740 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1741 gfilter
->aslist
[in
].name
);
1742 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1745 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1746 if (pfilter
->map
[RMAP_IN
].name
)
1747 XFREE(MTYPE_BGP_FILTER_NAME
,
1748 pfilter
->map
[RMAP_IN
].name
);
1749 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1750 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1751 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1754 /* outbound filter apply */
1755 if (gfilter
->dlist
[out
].name
) {
1756 if (pfilter
->dlist
[out
].name
)
1757 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1758 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1759 gfilter
->dlist
[out
].name
);
1760 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1762 if (pfilter
->dlist
[out
].name
)
1763 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1764 pfilter
->dlist
[out
].name
= NULL
;
1765 pfilter
->dlist
[out
].alist
= NULL
;
1768 if (gfilter
->plist
[out
].name
) {
1769 if (pfilter
->plist
[out
].name
)
1770 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1771 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1772 gfilter
->plist
[out
].name
);
1773 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1775 if (pfilter
->plist
[out
].name
)
1776 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1777 pfilter
->plist
[out
].name
= NULL
;
1778 pfilter
->plist
[out
].plist
= NULL
;
1781 if (gfilter
->aslist
[out
].name
) {
1782 if (pfilter
->aslist
[out
].name
)
1783 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1784 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1785 gfilter
->aslist
[out
].name
);
1786 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1788 if (pfilter
->aslist
[out
].name
)
1789 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1790 pfilter
->aslist
[out
].name
= NULL
;
1791 pfilter
->aslist
[out
].aslist
= NULL
;
1794 if (gfilter
->map
[RMAP_OUT
].name
) {
1795 if (pfilter
->map
[RMAP_OUT
].name
)
1796 XFREE(MTYPE_BGP_FILTER_NAME
,
1797 pfilter
->map
[RMAP_OUT
].name
);
1798 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1799 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1800 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1802 if (pfilter
->map
[RMAP_OUT
].name
)
1803 XFREE(MTYPE_BGP_FILTER_NAME
,
1804 pfilter
->map
[RMAP_OUT
].name
);
1805 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1806 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1809 if (gfilter
->usmap
.name
) {
1810 if (pfilter
->usmap
.name
)
1811 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1812 pfilter
->usmap
.name
=
1813 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1814 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1816 if (pfilter
->usmap
.name
)
1817 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1818 pfilter
->usmap
.name
= NULL
;
1819 pfilter
->usmap
.map
= NULL
;
1823 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1827 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1828 zlog_err("%s was called for peer-group %s", __func__
,
1833 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1835 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1836 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1837 return BGP_ERR_PEER_SAFI_CONFLICT
;
1839 /* Nothing to do if we've already activated this peer */
1840 if (peer
->afc
[afi
][safi
])
1843 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1846 active
= peer_active(peer
);
1847 peer
->afc
[afi
][safi
] = 1;
1850 peer_group2peer_config_copy_af(peer
->group
, peer
,
1853 if (!active
&& peer_active(peer
)) {
1854 bgp_timer_set(peer
);
1856 if (peer
->status
== Established
) {
1857 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1858 peer
->afc_adv
[afi
][safi
] = 1;
1859 bgp_capability_send(peer
, afi
, safi
,
1861 CAPABILITY_ACTION_SET
);
1862 if (peer
->afc_recv
[afi
][safi
]) {
1863 peer
->afc_nego
[afi
][safi
] = 1;
1864 bgp_announce_route(peer
, afi
, safi
);
1867 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1868 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1869 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1877 /* Activate the peer or peer group for specified AFI and SAFI. */
1878 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1881 struct peer_group
*group
;
1882 struct listnode
*node
, *nnode
;
1883 struct peer
*tmp_peer
;
1886 /* Nothing to do if we've already activated this peer */
1887 if (peer
->afc
[afi
][safi
])
1892 /* This is a peer-group so activate all of the members of the
1893 * peer-group as well */
1894 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1896 /* Do not activate a peer for both SAFI_UNICAST and
1897 * SAFI_LABELED_UNICAST */
1898 if ((safi
== SAFI_UNICAST
1899 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1900 || (safi
== SAFI_LABELED_UNICAST
1901 && peer
->afc
[afi
][SAFI_UNICAST
]))
1902 return BGP_ERR_PEER_SAFI_CONFLICT
;
1904 peer
->afc
[afi
][safi
] = 1;
1905 group
= peer
->group
;
1907 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1908 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1911 ret
|= peer_activate_af(peer
, afi
, safi
);
1914 /* If this is the first peer to be activated for this afi/labeled-unicast
1915 * recalc bestpaths to trigger label allocation */
1916 if (safi
== SAFI_LABELED_UNICAST
&& !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1918 if (BGP_DEBUG(zebra
, ZEBRA
))
1919 zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels");
1921 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1922 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1928 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1931 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1932 zlog_err("%s was called for peer-group %s", __func__
,
1937 /* Nothing to do if we've already deactivated this peer */
1938 if (!peer
->afc
[afi
][safi
])
1941 /* De-activate the address family configuration. */
1942 peer
->afc
[afi
][safi
] = 0;
1944 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1945 zlog_err("couldn't delete af structure for peer %s",
1950 if (peer
->status
== Established
) {
1951 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1952 peer
->afc_adv
[afi
][safi
] = 0;
1953 peer
->afc_nego
[afi
][safi
] = 0;
1955 if (peer_active_nego(peer
)) {
1956 bgp_capability_send(peer
, afi
, safi
,
1958 CAPABILITY_ACTION_UNSET
);
1959 bgp_clear_route(peer
, afi
, safi
);
1960 peer
->pcount
[afi
][safi
] = 0;
1962 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1963 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1964 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1967 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
1968 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1969 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1976 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1979 struct peer_group
*group
;
1980 struct peer
*tmp_peer
;
1981 struct listnode
*node
, *nnode
;
1984 /* Nothing to do if we've already de-activated this peer */
1985 if (!peer
->afc
[afi
][safi
])
1988 /* This is a peer-group so de-activate all of the members of the
1989 * peer-group as well */
1990 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1991 peer
->afc
[afi
][safi
] = 0;
1992 group
= peer
->group
;
1994 if (peer_af_delete(peer
, afi
, safi
) != 0) {
1995 zlog_err("couldn't delete af structure for peer %s",
1999 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2000 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2003 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2008 /* If this is the last peer to be deactivated for this afi/labeled-unicast
2009 * recalc bestpaths to trigger label deallocation */
2010 if (safi
== SAFI_LABELED_UNICAST
&&
2011 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] &&
2012 !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2014 if (BGP_DEBUG(zebra
, ZEBRA
))
2015 zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2017 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2018 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2023 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2026 return peer_activate(peer
, afi
, safi
);
2028 return peer_deactivate(peer
, afi
, safi
);
2031 static void peer_nsf_stop(struct peer
*peer
)
2036 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2037 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2039 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2040 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2041 peer
->nsf
[afi
][safi
] = 0;
2043 if (peer
->t_gr_restart
) {
2044 BGP_TIMER_OFF(peer
->t_gr_restart
);
2045 if (bgp_debug_neighbor_events(peer
))
2046 zlog_debug("%s graceful restart timer stopped",
2049 if (peer
->t_gr_stale
) {
2050 BGP_TIMER_OFF(peer
->t_gr_stale
);
2051 if (bgp_debug_neighbor_events(peer
))
2053 "%s graceful restart stalepath timer stopped",
2056 bgp_clear_route_all(peer
);
2059 /* Delete peer from confguration.
2061 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2062 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2064 * This function /should/ take care to be idempotent, to guard against
2065 * it being called multiple times through stray events that come in
2066 * that happen to result in this function being called again. That
2067 * said, getting here for a "Deleted" peer is a bug in the neighbour
2070 int peer_delete(struct peer
*peer
)
2076 struct bgp_filter
*filter
;
2077 struct listnode
*pn
;
2080 assert(peer
->status
!= Deleted
);
2083 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2085 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2086 peer_nsf_stop(peer
);
2088 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2090 /* If this peer belongs to peer group, clear up the
2093 if (peer_dynamic_neighbor(peer
))
2094 peer_drop_dynamic_neighbor(peer
);
2096 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2098 peer
); /* group->peer list reference */
2099 list_delete_node(peer
->group
->peer
, pn
);
2104 /* Withdraw all information from routing table. We can not use
2105 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2106 * executed after peer structure is deleted.
2108 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2110 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2112 if (peer
->doppelganger
) {
2113 peer
->doppelganger
->doppelganger
= NULL
;
2114 peer
->doppelganger
= NULL
;
2117 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2118 bgp_fsm_change_status(peer
, Deleted
);
2120 /* Remove from NHT */
2121 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2122 bgp_unlink_nexthop_by_peer(peer
);
2124 /* Password configuration */
2125 if (peer
->password
) {
2126 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2127 peer
->password
= NULL
;
2129 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2130 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2131 bgp_md5_unset(peer
);
2134 bgp_timer_set(peer
); /* stops all timers for Deleted */
2136 /* Delete from all peer list. */
2137 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2138 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2139 peer_unlock(peer
); /* bgp peer list reference */
2140 list_delete_node(bgp
->peer
, pn
);
2141 hash_release(bgp
->peerhash
, peer
);
2146 stream_free(peer
->ibuf
);
2151 stream_fifo_free(peer
->obuf
);
2156 stream_free(peer
->work
);
2160 if (peer
->scratch
) {
2161 stream_free(peer
->scratch
);
2162 peer
->scratch
= NULL
;
2165 /* Local and remote addresses. */
2166 if (peer
->su_local
) {
2167 sockunion_free(peer
->su_local
);
2168 peer
->su_local
= NULL
;
2171 if (peer
->su_remote
) {
2172 sockunion_free(peer
->su_remote
);
2173 peer
->su_remote
= NULL
;
2176 /* Free filter related memory. */
2177 FOREACH_AFI_SAFI (afi
, safi
) {
2178 filter
= &peer
->filter
[afi
][safi
];
2180 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2181 if (filter
->dlist
[i
].name
) {
2182 XFREE(MTYPE_BGP_FILTER_NAME
,
2183 filter
->dlist
[i
].name
);
2184 filter
->dlist
[i
].name
= NULL
;
2187 if (filter
->plist
[i
].name
) {
2188 XFREE(MTYPE_BGP_FILTER_NAME
,
2189 filter
->plist
[i
].name
);
2190 filter
->plist
[i
].name
= NULL
;
2193 if (filter
->aslist
[i
].name
) {
2194 XFREE(MTYPE_BGP_FILTER_NAME
,
2195 filter
->aslist
[i
].name
);
2196 filter
->aslist
[i
].name
= NULL
;
2200 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2201 if (filter
->map
[i
].name
) {
2202 XFREE(MTYPE_BGP_FILTER_NAME
,
2203 filter
->map
[i
].name
);
2204 filter
->map
[i
].name
= NULL
;
2208 if (filter
->usmap
.name
) {
2209 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2210 filter
->usmap
.name
= NULL
;
2213 if (peer
->default_rmap
[afi
][safi
].name
) {
2214 XFREE(MTYPE_ROUTE_MAP_NAME
,
2215 peer
->default_rmap
[afi
][safi
].name
);
2216 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2220 FOREACH_AFI_SAFI (afi
, safi
)
2221 peer_af_delete(peer
, afi
, safi
);
2223 if (peer
->hostname
) {
2224 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2225 peer
->hostname
= NULL
;
2228 if (peer
->domainname
) {
2229 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2230 peer
->domainname
= NULL
;
2233 peer_unlock(peer
); /* initial reference */
2238 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2240 return strcmp(g1
->name
, g2
->name
);
2243 /* Peer group cofiguration. */
2244 static struct peer_group
*peer_group_new(void)
2246 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2247 sizeof(struct peer_group
));
2250 static void peer_group_free(struct peer_group
*group
)
2252 XFREE(MTYPE_PEER_GROUP
, group
);
2255 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2257 struct peer_group
*group
;
2258 struct listnode
*node
, *nnode
;
2260 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2261 if (strcmp(group
->name
, name
) == 0)
2267 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2269 struct peer_group
*group
;
2272 group
= peer_group_lookup(bgp
, name
);
2276 group
= peer_group_new();
2279 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2280 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2281 group
->peer
= list_new();
2282 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2283 group
->listen_range
[afi
] = list_new();
2284 group
->conf
= peer_new(bgp
);
2285 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2286 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2287 if (group
->conf
->host
)
2288 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2289 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2290 group
->conf
->group
= group
;
2291 group
->conf
->as
= 0;
2292 group
->conf
->ttl
= 1;
2293 group
->conf
->gtsm_hops
= 0;
2294 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2295 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2296 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2297 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2298 group
->conf
->keepalive
= 0;
2299 group
->conf
->holdtime
= 0;
2300 group
->conf
->connect
= 0;
2301 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2302 listnode_add_sort(bgp
->group
, group
);
2307 static void peer_group2peer_config_copy(struct peer_group
*group
,
2317 peer
->as
= conf
->as
;
2320 if (conf
->change_local_as
)
2321 peer
->change_local_as
= conf
->change_local_as
;
2324 peer
->ttl
= conf
->ttl
;
2327 peer
->gtsm_hops
= conf
->gtsm_hops
;
2329 /* this flag is per-neighbor and so has to be preserved */
2330 v6only
= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2332 /* peer flags apply */
2333 peer
->flags
= conf
->flags
;
2336 SET_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2338 /* peer config apply */
2339 peer
->config
= conf
->config
;
2341 /* peer timers apply */
2342 peer
->holdtime
= conf
->holdtime
;
2343 peer
->keepalive
= conf
->keepalive
;
2344 peer
->connect
= conf
->connect
;
2345 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2346 peer
->v_connect
= conf
->connect
;
2348 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2350 /* advertisement-interval reset */
2351 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2352 peer
->v_routeadv
= conf
->routeadv
;
2353 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2354 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2356 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2358 /* password apply */
2359 if (conf
->password
&& !peer
->password
)
2360 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2362 if (!BGP_PEER_SU_UNSPEC(peer
))
2365 /* update-source apply */
2366 if (conf
->update_source
) {
2367 if (peer
->update_source
)
2368 sockunion_free(peer
->update_source
);
2369 if (peer
->update_if
) {
2370 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2371 peer
->update_if
= NULL
;
2373 peer
->update_source
= sockunion_dup(conf
->update_source
);
2374 } else if (conf
->update_if
) {
2375 if (peer
->update_if
)
2376 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2377 if (peer
->update_source
) {
2378 sockunion_free(peer
->update_source
);
2379 peer
->update_source
= NULL
;
2382 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2385 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2388 /* Peer group's remote AS configuration. */
2389 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2392 struct peer_group
*group
;
2394 struct listnode
*node
, *nnode
;
2396 group
= peer_group_lookup(bgp
, group_name
);
2400 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2404 /* When we setup peer-group AS number all peer group member's AS
2405 number must be updated to same number. */
2406 peer_as_change(group
->conf
, *as
, as_type
);
2408 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2409 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2410 || (peer
->as_type
!= as_type
))
2411 peer_as_change(peer
, *as
, as_type
);
2417 int peer_group_delete(struct peer_group
*group
)
2421 struct prefix
*prefix
;
2423 struct listnode
*node
, *nnode
;
2428 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2429 other
= peer
->doppelganger
;
2431 if (other
&& other
->status
!= Deleted
) {
2432 other
->group
= NULL
;
2436 list_delete_and_null(&group
->peer
);
2438 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2439 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2441 prefix_free(prefix
);
2443 list_delete_and_null(&group
->listen_range
[afi
]);
2446 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2449 bfd_info_free(&(group
->conf
->bfd_info
));
2451 group
->conf
->group
= NULL
;
2452 peer_delete(group
->conf
);
2454 /* Delete from all peer_group list. */
2455 listnode_delete(bgp
->group
, group
);
2457 peer_group_free(group
);
2462 int peer_group_remote_as_delete(struct peer_group
*group
)
2464 struct peer
*peer
, *other
;
2465 struct listnode
*node
, *nnode
;
2467 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2468 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2471 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2472 other
= peer
->doppelganger
;
2476 if (other
&& other
->status
!= Deleted
) {
2477 other
->group
= NULL
;
2481 list_delete_all_node(group
->peer
);
2483 group
->conf
->as
= 0;
2484 group
->conf
->as_type
= AS_UNSPECIFIED
;
2489 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2491 struct prefix
*prefix
;
2492 struct listnode
*node
, *nnode
;
2495 afi
= family2afi(range
->family
);
2497 /* Group needs remote AS configured. */
2498 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2499 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2501 /* Ensure no duplicates. Currently we don't care about overlaps. */
2502 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2503 if (prefix_same(range
, prefix
))
2507 prefix
= prefix_new();
2508 prefix_copy(prefix
, range
);
2509 listnode_add(group
->listen_range
[afi
], prefix
);
2513 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2515 struct prefix
*prefix
, prefix2
;
2516 struct listnode
*node
, *nnode
;
2519 char buf
[PREFIX2STR_BUFFER
];
2521 afi
= family2afi(range
->family
);
2523 /* Identify the listen range. */
2524 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2525 if (prefix_same(range
, prefix
))
2530 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2532 prefix2str(prefix
, buf
, sizeof(buf
));
2534 /* Dispose off any dynamic neighbors that exist due to this listen range
2536 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2537 if (!peer_dynamic_neighbor(peer
))
2540 sockunion2hostprefix(&peer
->su
, &prefix2
);
2541 if (prefix_match(prefix
, &prefix2
)) {
2542 if (bgp_debug_neighbor_events(peer
))
2544 "Deleting dynamic neighbor %s group %s upon "
2545 "delete of listen range %s",
2546 peer
->host
, group
->name
, buf
);
2551 /* Get rid of the listen range */
2552 listnode_delete(group
->listen_range
[afi
], prefix
);
2557 /* Bind specified peer to peer group. */
2558 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2559 struct peer_group
*group
, as_t
*as
)
2561 int first_member
= 0;
2564 int cap_enhe_preset
= 0;
2566 /* Lookup the peer. */
2568 peer
= peer_lookup(bgp
, su
);
2570 /* The peer exist, bind it to the peer-group */
2572 /* When the peer already belongs to a peer-group, check the
2574 if (peer_group_active(peer
)) {
2576 /* The peer is already bound to the peer-group,
2579 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2582 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2585 /* The peer has not specified a remote-as, inherit it from the
2587 if (peer
->as_type
== AS_UNSPECIFIED
) {
2588 peer
->as_type
= group
->conf
->as_type
;
2589 peer
->as
= group
->conf
->as
;
2592 if (!group
->conf
->as
) {
2593 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2594 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2597 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2600 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2604 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2605 cap_enhe_preset
= 1;
2607 peer_group2peer_config_copy(group
, peer
);
2610 * Capability extended-nexthop is enabled for an interface
2612 * default. So, fix that up here.
2614 if (peer
->conf_if
&& cap_enhe_preset
)
2615 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2617 FOREACH_AFI_SAFI (afi
, safi
) {
2618 if (group
->conf
->afc
[afi
][safi
]) {
2619 peer
->afc
[afi
][safi
] = 1;
2621 if (peer_af_find(peer
, afi
, safi
)
2622 || peer_af_create(peer
, afi
, safi
)) {
2623 peer_group2peer_config_copy_af(
2624 group
, peer
, afi
, safi
);
2626 } else if (peer
->afc
[afi
][safi
])
2627 peer_deactivate(peer
, afi
, safi
);
2631 assert(group
&& peer
->group
== group
);
2633 struct listnode
*pn
;
2634 pn
= listnode_lookup(bgp
->peer
, peer
);
2635 list_delete_node(bgp
->peer
, pn
);
2636 peer
->group
= group
;
2637 listnode_add_sort(bgp
->peer
, peer
);
2639 peer
= peer_lock(peer
); /* group->peer list reference */
2640 listnode_add(group
->peer
, peer
);
2644 /* Advertisement-interval reset */
2645 if (!CHECK_FLAG(group
->conf
->config
,
2646 PEER_CONFIG_ROUTEADV
)) {
2647 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2648 group
->conf
->v_routeadv
=
2649 BGP_DEFAULT_IBGP_ROUTEADV
;
2651 group
->conf
->v_routeadv
=
2652 BGP_DEFAULT_EBGP_ROUTEADV
;
2655 /* ebgp-multihop reset */
2656 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2657 group
->conf
->ttl
= MAXTTL
;
2659 /* local-as reset */
2660 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2661 group
->conf
->change_local_as
= 0;
2662 UNSET_FLAG(peer
->flags
,
2663 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2664 UNSET_FLAG(peer
->flags
,
2665 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2669 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2671 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2672 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2673 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2674 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2676 bgp_session_reset(peer
);
2680 /* Create a new peer. */
2682 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2683 && (!group
->conf
->as
)) {
2684 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2687 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2688 group
->conf
->as_type
, 0, 0, group
);
2690 peer
= peer_lock(peer
); /* group->peer list reference */
2691 listnode_add(group
->peer
, peer
);
2693 peer_group2peer_config_copy(group
, peer
);
2695 /* If the peer-group is active for this afi/safi then activate
2697 FOREACH_AFI_SAFI (afi
, safi
) {
2698 if (group
->conf
->afc
[afi
][safi
]) {
2699 peer
->afc
[afi
][safi
] = 1;
2700 peer_af_create(peer
, afi
, safi
);
2701 peer_group2peer_config_copy_af(group
, peer
, afi
,
2703 } else if (peer
->afc
[afi
][safi
])
2704 peer_deactivate(peer
, afi
, safi
);
2707 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2709 /* Set up peer's events and timers. */
2710 if (peer_active(peer
))
2711 bgp_timer_set(peer
);
2717 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2718 struct peer_group
*group
)
2724 if (group
!= peer
->group
)
2725 return BGP_ERR_PEER_GROUP_MISMATCH
;
2727 FOREACH_AFI_SAFI (afi
, safi
) {
2728 if (peer
->afc
[afi
][safi
]) {
2729 peer
->afc
[afi
][safi
] = 0;
2730 peer_af_flag_reset(peer
, afi
, safi
);
2732 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2734 "couldn't delete af structure for peer %s",
2740 assert(listnode_lookup(group
->peer
, peer
));
2741 peer_unlock(peer
); /* peer group list reference */
2742 listnode_delete(group
->peer
, peer
);
2744 other
= peer
->doppelganger
;
2746 if (group
->conf
->as
) {
2748 if (other
&& other
->status
!= Deleted
) {
2751 listnode_delete(group
->peer
, other
);
2753 other
->group
= NULL
;
2759 bgp_bfd_deregister_peer(peer
);
2760 peer_global_config_reset(peer
);
2762 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2763 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2764 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2765 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2767 bgp_session_reset(peer
);
2772 static int bgp_startup_timer_expire(struct thread
*thread
)
2776 bgp
= THREAD_ARG(thread
);
2777 bgp
->t_startup
= NULL
;
2782 /* BGP instance creation by `router bgp' commands. */
2783 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2784 enum bgp_instance_type inst_type
)
2790 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2793 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2794 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2795 zlog_debug("Creating Default VRF, AS %u", *as
);
2797 zlog_debug("Creating %s %s, AS %u",
2798 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2805 bgp
->inst_type
= inst_type
;
2806 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2808 bgp
->peer_self
= peer_new(bgp
);
2809 if (bgp
->peer_self
->host
)
2810 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2811 bgp
->peer_self
->host
=
2812 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2813 if (bgp
->peer_self
->hostname
!= NULL
) {
2814 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2815 bgp
->peer_self
->hostname
= NULL
;
2817 if (cmd_hostname_get())
2818 bgp
->peer_self
->hostname
=
2819 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2821 if (bgp
->peer_self
->domainname
!= NULL
) {
2822 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2823 bgp
->peer_self
->domainname
= NULL
;
2825 if (cmd_domainname_get())
2826 bgp
->peer_self
->domainname
=
2827 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2828 bgp
->peer
= list_new();
2829 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2830 bgp
->peerhash
= hash_create(peer_hash_key_make
,
2833 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2835 bgp
->group
= list_new();
2836 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2838 FOREACH_AFI_SAFI (afi
, safi
) {
2839 bgp
->route
[afi
][safi
] = bgp_table_init(afi
, safi
);
2840 bgp
->aggregate
[afi
][safi
] = bgp_table_init(afi
, safi
);
2841 bgp
->rib
[afi
][safi
] = bgp_table_init(afi
, safi
);
2843 /* Enable maximum-paths */
2844 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2846 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2850 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2851 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2852 bgp
->default_subgroup_pkt_queue_max
=
2853 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2854 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2855 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2856 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2857 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2858 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2859 bgp
->dynamic_neighbors_count
= 0;
2860 #if DFLT_BGP_IMPORT_CHECK
2861 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2863 #if DFLT_BGP_SHOW_HOSTNAME
2864 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2866 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2867 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2869 #if DFLT_BGP_DETERMINISTIC_MED
2870 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2872 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2877 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2878 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2880 assert(bgp
->rfapi_cfg
);
2882 #endif /* ENABLE_BGP_VNC */
2885 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2887 /* TODO - The startup timer needs to be run for the whole of BGP
2889 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2890 bgp
->restart_time
, &bgp
->t_startup
);
2893 bgp
->wpkt_quanta
= BGP_WRITE_PACKET_MAX
;
2894 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2898 update_bgp_group_init(bgp
);
2903 /* Return the "default VRF" instance of BGP. */
2904 struct bgp
*bgp_get_default(void)
2907 struct listnode
*node
, *nnode
;
2909 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2910 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2915 /* Lookup BGP entry. */
2916 struct bgp
*bgp_lookup(as_t as
, const char *name
)
2919 struct listnode
*node
, *nnode
;
2921 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2923 && ((bgp
->name
== NULL
&& name
== NULL
)
2924 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
2929 /* Lookup BGP structure by view name. */
2930 struct bgp
*bgp_lookup_by_name(const char *name
)
2933 struct listnode
*node
, *nnode
;
2935 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
2936 if ((bgp
->name
== NULL
&& name
== NULL
)
2937 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
2942 /* Lookup BGP instance based on VRF id. */
2943 /* Note: Only to be used for incoming messages from Zebra. */
2944 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
2948 /* Lookup VRF (in tree) and follow link. */
2949 vrf
= vrf_lookup_by_id(vrf_id
);
2952 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
2955 /* Called from VTY commands. */
2956 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
2957 enum bgp_instance_type inst_type
)
2961 /* Multiple instance check. */
2962 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
2964 bgp
= bgp_lookup_by_name(name
);
2966 bgp
= bgp_get_default();
2968 /* Already exists. */
2970 if (bgp
->as
!= *as
) {
2972 return BGP_ERR_INSTANCE_MISMATCH
;
2974 if (bgp
->inst_type
!= inst_type
)
2975 return BGP_ERR_INSTANCE_MISMATCH
;
2980 /* BGP instance name can not be specified for single instance.
2983 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
2985 /* Get default BGP structure if exists. */
2986 bgp
= bgp_get_default();
2989 if (bgp
->as
!= *as
) {
2991 return BGP_ERR_AS_MISMATCH
;
2998 bgp
= bgp_create(as
, name
, inst_type
);
2999 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3000 bgp_address_init(bgp
);
3001 bgp_tip_hash_init(bgp
);
3005 bgp
->t_rmap_def_originate_eval
= NULL
;
3007 /* Create BGP server socket, if first instance. */
3008 if (list_isempty(bm
->bgp
) && !bgp_option_check(BGP_OPT_NO_LISTEN
)) {
3009 if (bgp_socket(bm
->port
, bm
->address
) < 0)
3010 return BGP_ERR_INVALID_VALUE
;
3013 listnode_add(bm
->bgp
, bgp
);
3015 /* If Default instance or VRF, link to the VRF structure, if present. */
3016 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3017 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3020 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3022 bgp_vrf_link(bgp
, vrf
);
3025 /* Register with Zebra, if needed */
3026 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3027 bgp_zebra_instance_register(bgp
);
3034 * Make BGP instance "up". Applies only to VRFs (non-default) and
3035 * implies the VRF has been learnt from Zebra.
3037 void bgp_instance_up(struct bgp
*bgp
)
3040 struct listnode
*node
, *next
;
3042 /* Register with zebra. */
3043 bgp_zebra_instance_register(bgp
);
3045 /* Kick off any peers that may have been configured. */
3046 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3047 if (!BGP_PEER_START_SUPPRESSED(peer
))
3048 BGP_EVENT_ADD(peer
, BGP_Start
);
3051 /* Process any networks that have been configured. */
3052 bgp_static_add(bgp
);
3056 * Make BGP instance "down". Applies only to VRFs (non-default) and
3057 * implies the VRF has been deleted by Zebra.
3059 void bgp_instance_down(struct bgp
*bgp
)
3062 struct listnode
*node
;
3063 struct listnode
*next
;
3066 if (bgp
->t_rmap_def_originate_eval
) {
3067 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3068 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3072 /* Bring down peers, so corresponding routes are purged. */
3073 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3074 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3075 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3076 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3078 bgp_session_reset(peer
);
3081 /* Purge network and redistributed routes. */
3082 bgp_purge_static_redist_routes(bgp
);
3084 /* Cleanup registered nexthops (flags) */
3085 bgp_cleanup_nexthops(bgp
);
3088 /* Delete BGP instance. */
3089 int bgp_delete(struct bgp
*bgp
)
3092 struct peer_group
*group
;
3093 struct listnode
*node
, *next
;
3098 THREAD_OFF(bgp
->t_startup
);
3100 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3101 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3102 zlog_debug("Deleting Default VRF");
3104 zlog_debug("Deleting %s %s",
3105 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3112 if (bgp
->t_rmap_def_originate_eval
) {
3113 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3114 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3118 /* Inform peers we're going down. */
3119 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3120 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3121 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3122 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3125 /* Delete static routes (networks). */
3126 bgp_static_delete(bgp
);
3128 /* Unset redistribution. */
3129 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3130 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3131 if (i
!= ZEBRA_ROUTE_BGP
)
3132 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3134 /* Free peers and peer-groups. */
3135 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3136 peer_group_delete(group
);
3138 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3141 if (bgp
->peer_self
) {
3142 peer_delete(bgp
->peer_self
);
3143 bgp
->peer_self
= NULL
;
3146 update_bgp_group_free(bgp
);
3148 /* TODO - Other memory may need to be freed - e.g., NHT */
3153 bgp_cleanup_routes(bgp
);
3155 /* Remove visibility via the master list - there may however still be
3156 * routes to be processed still referencing the struct bgp.
3158 listnode_delete(bm
->bgp
, bgp
);
3159 if (list_isempty(bm
->bgp
))
3162 /* Deregister from Zebra, if needed */
3163 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3164 bgp_zebra_instance_deregister(bgp
);
3166 /* Free interfaces in this instance. */
3169 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3171 bgp_vrf_unlink(bgp
, vrf
);
3173 thread_master_free_unused(bm
->master
);
3174 bgp_unlock(bgp
); /* initial reference */
3179 void bgp_free(struct bgp
*bgp
)
3183 struct bgp_table
*table
;
3184 struct bgp_node
*rn
;
3185 struct bgp_rmap
*rmap
;
3189 list_delete_and_null(&bgp
->group
);
3190 list_delete_and_null(&bgp
->peer
);
3192 if (bgp
->peerhash
) {
3193 hash_free(bgp
->peerhash
);
3194 bgp
->peerhash
= NULL
;
3197 FOREACH_AFI_SAFI (afi
, safi
) {
3198 /* Special handling for 2-level routing tables. */
3199 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3200 || safi
== SAFI_EVPN
) {
3201 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3202 rn
= bgp_route_next(rn
)) {
3203 table
= (struct bgp_table
*)rn
->info
;
3204 bgp_table_finish(&table
);
3207 if (bgp
->route
[afi
][safi
])
3208 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3209 if (bgp
->aggregate
[afi
][safi
])
3210 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3211 if (bgp
->rib
[afi
][safi
])
3212 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3213 rmap
= &bgp
->table_map
[afi
][safi
];
3215 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3218 bgp_scan_finish(bgp
);
3219 bgp_address_destroy(bgp
);
3220 bgp_tip_hash_destroy(bgp
);
3222 bgp_evpn_cleanup(bgp
);
3225 XFREE(MTYPE_BGP
, bgp
->name
);
3227 XFREE(MTYPE_BGP
, bgp
);
3230 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3233 struct listnode
*node
, *nnode
;
3239 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3240 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3241 && !CHECK_FLAG(peer
->sflags
,
3242 PEER_STATUS_ACCEPT_PEER
))
3244 } else if (bm
->bgp
!= NULL
) {
3245 struct listnode
*bgpnode
, *nbgpnode
;
3247 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3248 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3250 && !strcmp(peer
->conf_if
, conf_if
)
3251 && !CHECK_FLAG(peer
->sflags
,
3252 PEER_STATUS_ACCEPT_PEER
))
3258 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3261 struct listnode
*node
, *nnode
;
3267 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3268 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3269 && !CHECK_FLAG(peer
->sflags
,
3270 PEER_STATUS_ACCEPT_PEER
))
3272 } else if (bm
->bgp
!= NULL
) {
3273 struct listnode
*bgpnode
, *nbgpnode
;
3275 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3276 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3278 && !strcmp(peer
->hostname
, hostname
)
3279 && !CHECK_FLAG(peer
->sflags
,
3280 PEER_STATUS_ACCEPT_PEER
))
3286 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3288 struct peer
*peer
= NULL
;
3289 struct peer tmp_peer
;
3291 memset(&tmp_peer
, 0, sizeof(struct peer
));
3294 * We do not want to find the doppelganger peer so search for the peer
3296 * the hash that has PEER_FLAG_CONFIG_NODE
3298 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3303 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3304 } else if (bm
->bgp
!= NULL
) {
3305 struct listnode
*bgpnode
, *nbgpnode
;
3307 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3308 /* Skip VRFs, this function will not be invoked without
3310 * when examining VRFs.
3312 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3315 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3325 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3326 union sockunion
*su
,
3327 struct peer_group
*group
)
3333 /* Create peer first; we've already checked group config is valid. */
3334 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3335 group
->conf
->as_type
, 0, 0, group
);
3340 peer
= peer_lock(peer
);
3341 listnode_add(group
->peer
, peer
);
3343 peer_group2peer_config_copy(group
, peer
);
3346 * Bind peer for all AFs configured for the group. We don't call
3347 * peer_group_bind as that is sub-optimal and does some stuff we don't
3350 FOREACH_AFI_SAFI (afi
, safi
) {
3351 if (!group
->conf
->afc
[afi
][safi
])
3353 peer
->afc
[afi
][safi
] = 1;
3355 if (!peer_af_find(peer
, afi
, safi
))
3356 peer_af_create(peer
, afi
, safi
);
3358 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3361 /* Mark as dynamic, but also as a "config node" for other things to
3363 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3364 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3370 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3371 struct prefix
*prefix
)
3373 struct listnode
*node
, *nnode
;
3374 struct prefix
*range
;
3377 afi
= family2afi(prefix
->family
);
3379 if (group
->listen_range
[afi
])
3380 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3382 if (prefix_match(range
, prefix
))
3389 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3390 struct prefix
**listen_range
)
3392 struct prefix
*range
= NULL
;
3393 struct peer_group
*group
= NULL
;
3394 struct listnode
*node
, *nnode
;
3396 *listen_range
= NULL
;
3398 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3399 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3402 } else if (bm
->bgp
!= NULL
) {
3403 struct listnode
*bgpnode
, *nbgpnode
;
3405 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3406 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3407 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3413 *listen_range
= range
;
3414 return (group
&& range
) ? group
: NULL
;
3417 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3419 struct peer_group
*group
;
3422 struct prefix prefix
;
3423 struct prefix
*listen_range
;
3425 char buf
[PREFIX2STR_BUFFER
];
3426 char buf1
[PREFIX2STR_BUFFER
];
3428 sockunion2hostprefix(su
, &prefix
);
3430 /* See if incoming connection matches a configured listen range. */
3431 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3442 prefix2str(&prefix
, buf
, sizeof(buf
));
3443 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3445 if (bgp_debug_neighbor_events(NULL
))
3447 "Dynamic Neighbor %s matches group %s listen range %s",
3448 buf
, group
->name
, buf1
);
3450 /* Are we within the listen limit? */
3451 dncount
= gbgp
->dynamic_neighbors_count
;
3453 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3454 if (bgp_debug_neighbor_events(NULL
))
3455 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3456 inet_sutop(su
, buf
),
3457 gbgp
->dynamic_neighbors_limit
);
3461 /* Ensure group is not disabled. */
3462 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3463 if (bgp_debug_neighbor_events(NULL
))
3465 "Dynamic Neighbor %s rejected - group %s disabled",
3470 /* Check that at least one AF is activated for the group. */
3471 if (!peer_group_af_configured(group
)) {
3472 if (bgp_debug_neighbor_events(NULL
))
3474 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3479 /* Create dynamic peer and bind to associated group. */
3480 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3483 gbgp
->dynamic_neighbors_count
= ++dncount
;
3485 if (bgp_debug_neighbor_events(peer
))
3486 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3487 peer
->host
, group
->name
, dncount
);
3492 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3495 if (peer
->group
&& peer
->group
->bgp
) {
3496 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3498 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3500 if (bgp_debug_neighbor_events(peer
))
3501 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3502 peer
->group
->name
, dncount
);
3506 /* If peer is configured at least one address family return 1. */
3507 int peer_active(struct peer
*peer
)
3509 if (BGP_PEER_SU_UNSPEC(peer
))
3511 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3512 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3513 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3514 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3515 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3516 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3517 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3518 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3519 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3524 /* If peer is negotiated at least one address family return 1. */
3525 int peer_active_nego(struct peer
*peer
)
3527 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3528 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3529 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3530 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3531 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3532 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3533 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3534 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3535 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3536 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3537 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3542 /* peer_flag_change_type. */
3543 enum peer_change_type
{
3546 peer_change_reset_in
,
3547 peer_change_reset_out
,
3550 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3551 enum peer_change_type type
)
3553 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3556 if (peer
->status
!= Established
)
3559 if (type
== peer_change_reset
) {
3560 /* If we're resetting session, we've to delete both peer struct
3562 if ((peer
->doppelganger
)
3563 && (peer
->doppelganger
->status
!= Deleted
)
3564 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3565 PEER_FLAG_CONFIG_NODE
)))
3566 peer_delete(peer
->doppelganger
);
3568 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3569 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3570 } else if (type
== peer_change_reset_in
) {
3571 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3572 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3573 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3575 if ((peer
->doppelganger
)
3576 && (peer
->doppelganger
->status
!= Deleted
)
3577 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3578 PEER_FLAG_CONFIG_NODE
)))
3579 peer_delete(peer
->doppelganger
);
3581 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3582 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3584 } else if (type
== peer_change_reset_out
) {
3585 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3586 bgp_announce_route(peer
, afi
, safi
);
3590 struct peer_flag_action
{
3594 /* This flag can be set for peer-group member. */
3595 u_char not_for_member
;
3597 /* Action when the flag is changed. */
3598 enum peer_change_type type
;
3600 /* Peer down cause */
3604 static const struct peer_flag_action peer_flag_action_list
[] = {
3605 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3606 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3607 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3608 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3609 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3610 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3611 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3612 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3615 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3616 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3617 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3618 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3619 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3620 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3621 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3622 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3623 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3624 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3625 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3626 // PEER_FLAG_DEFAULT_ORIGINATE
3627 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3628 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3629 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3630 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3631 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3632 // PEER_FLAG_MAX_PREFIX
3633 // PEER_FLAG_MAX_PREFIX_WARNING
3634 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3635 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3636 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3637 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3638 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3639 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3640 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3641 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3642 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3645 /* Proper action set. */
3646 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3647 int size
, struct peer_flag_action
*action
,
3654 const struct peer_flag_action
*match
= NULL
;
3656 /* Check peer's frag action. */
3657 for (i
= 0; i
< size
; i
++) {
3658 match
= &action_list
[i
];
3660 if (match
->flag
== 0)
3663 if (match
->flag
& flag
) {
3666 if (match
->type
== peer_change_reset_in
)
3668 if (match
->type
== peer_change_reset_out
)
3670 if (match
->type
== peer_change_reset
) {
3674 if (match
->not_for_member
)
3675 action
->not_for_member
= 1;
3679 /* Set peer clear type. */
3680 if (reset_in
&& reset_out
)
3681 action
->type
= peer_change_reset
;
3683 action
->type
= peer_change_reset_in
;
3685 action
->type
= peer_change_reset_out
;
3687 action
->type
= peer_change_none
;
3692 static void peer_flag_modify_action(struct peer
*peer
, u_int32_t flag
)
3694 if (flag
== PEER_FLAG_SHUTDOWN
) {
3695 if (CHECK_FLAG(peer
->flags
, flag
)) {
3696 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3697 peer_nsf_stop(peer
);
3699 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3700 if (peer
->t_pmax_restart
) {
3701 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3702 if (bgp_debug_neighbor_events(peer
))
3704 "%s Maximum-prefix restart timer canceled",
3708 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3709 peer_nsf_stop(peer
);
3711 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3712 char *msg
= peer
->tx_shutdown_message
;
3715 if (!msg
&& peer_group_active(peer
))
3716 msg
= peer
->group
->conf
3717 ->tx_shutdown_message
;
3718 msglen
= msg
? strlen(msg
) : 0;
3726 memcpy(msgbuf
+ 1, msg
, msglen
);
3728 bgp_notify_send_with_data(
3729 peer
, BGP_NOTIFY_CEASE
,
3730 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3731 msgbuf
, msglen
+ 1);
3734 peer
, BGP_NOTIFY_CEASE
,
3735 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3737 bgp_session_reset(peer
);
3739 peer
->v_start
= BGP_INIT_START_TIMER
;
3740 BGP_EVENT_ADD(peer
, BGP_Stop
);
3742 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3743 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3744 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3745 else if (flag
== PEER_FLAG_PASSIVE
)
3746 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3747 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3748 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3750 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3751 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3753 bgp_session_reset(peer
);
3756 /* Change specified peer flag. */
3757 static int peer_flag_modify(struct peer
*peer
, u_int32_t flag
, int set
)
3761 struct peer_group
*group
;
3762 struct peer
*tmp_peer
;
3763 struct listnode
*node
, *nnode
;
3764 struct peer_flag_action action
;
3766 memset(&action
, 0, sizeof(struct peer_flag_action
));
3767 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3769 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3772 /* No flag action is found. */
3774 return BGP_ERR_INVALID_FLAG
;
3776 /* When unset the peer-group member's flag we have to check
3777 peer-group configuration. */
3778 if (!set
&& peer_group_active(peer
))
3779 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3780 if (flag
== PEER_FLAG_SHUTDOWN
)
3781 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3784 /* Flag conflict check. */
3785 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3786 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3787 return BGP_ERR_PEER_FLAG_CONFLICT
;
3789 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3790 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3792 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3797 SET_FLAG(peer
->flags
, flag
);
3799 UNSET_FLAG(peer
->flags
, flag
);
3801 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3802 if (action
.type
== peer_change_reset
)
3803 peer_flag_modify_action(peer
, flag
);
3808 /* peer-group member updates. */
3809 group
= peer
->group
;
3811 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3813 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
3816 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
3820 SET_FLAG(tmp_peer
->flags
, flag
);
3822 UNSET_FLAG(tmp_peer
->flags
, flag
);
3824 if (action
.type
== peer_change_reset
)
3825 peer_flag_modify_action(tmp_peer
, flag
);
3830 int peer_flag_set(struct peer
*peer
, u_int32_t flag
)
3832 return peer_flag_modify(peer
, flag
, 1);
3835 int peer_flag_unset(struct peer
*peer
, u_int32_t flag
)
3837 return peer_flag_modify(peer
, flag
, 0);
3840 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
3841 u_int32_t flag
, int set
)
3845 struct listnode
*node
, *nnode
;
3846 struct peer_group
*group
;
3847 struct peer_flag_action action
;
3848 struct peer
*tmp_peer
;
3850 int addpath_tx_used
;
3852 memset(&action
, 0, sizeof(struct peer_flag_action
));
3853 size
= sizeof peer_af_flag_action_list
3854 / sizeof(struct peer_flag_action
);
3856 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
3859 /* No flag action is found. */
3861 return BGP_ERR_INVALID_FLAG
;
3863 /* Special check for reflector client. */
3864 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
3865 && peer_sort(peer
) != BGP_PEER_IBGP
)
3866 return BGP_ERR_NOT_INTERNAL_PEER
;
3868 /* Special check for remove-private-AS. */
3869 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
3870 && peer_sort(peer
) == BGP_PEER_IBGP
)
3871 return BGP_ERR_REMOVE_PRIVATE_AS
;
3873 /* as-override is not allowed for IBGP peers */
3874 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
3875 return BGP_ERR_AS_OVERRIDE
;
3877 /* When current flag configuration is same as requested one. */
3878 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3879 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
3881 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
3886 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3888 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
3890 /* Execute action when peer is established. */
3891 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
3892 && peer
->status
== Established
) {
3893 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3894 bgp_clear_adj_in(peer
, afi
, safi
);
3896 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3897 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
3898 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
3899 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
3900 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
3901 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3902 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
3903 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3905 peer_change_action(peer
, afi
, safi
, action
.type
);
3909 /* Peer group member updates. */
3910 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3911 group
= peer
->group
;
3913 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3915 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
3920 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
3924 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3926 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
3928 if (tmp_peer
->status
== Established
) {
3929 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
3930 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
3932 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
3933 tmp_peer
->last_reset
=
3934 PEER_DOWN_RR_CLIENT_CHANGE
;
3936 == PEER_FLAG_RSERVER_CLIENT
)
3937 tmp_peer
->last_reset
=
3938 PEER_DOWN_RS_CLIENT_CHANGE
;
3940 == PEER_FLAG_ORF_PREFIX_SM
)
3941 tmp_peer
->last_reset
=
3942 PEER_DOWN_CAPABILITY_CHANGE
;
3944 == PEER_FLAG_ORF_PREFIX_RM
)
3945 tmp_peer
->last_reset
=
3946 PEER_DOWN_CAPABILITY_CHANGE
;
3948 peer_change_action(tmp_peer
, afi
, safi
,
3955 /* Track if addpath TX is in use */
3956 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
3957 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
3959 addpath_tx_used
= 0;
3962 addpath_tx_used
= 1;
3964 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
3965 if (!bgp_flag_check(
3966 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
3968 "%s: enabling bgp deterministic-med, this is required"
3969 " for addpath-tx-bestpath-per-AS",
3973 BGP_FLAG_DETERMINISTIC_MED
);
3974 bgp_recalculate_all_bestpaths(bgp
);
3978 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
3980 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
3981 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
3983 tmp_peer
->af_flags
[afi
][safi
],
3984 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
3985 addpath_tx_used
= 1;
3991 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
3997 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int32_t flag
)
3999 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4002 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
4005 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4009 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4011 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4012 peer
->tx_shutdown_message
=
4013 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4017 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4019 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4024 /* EBGP multihop configuration. */
4025 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4027 struct peer_group
*group
;
4028 struct listnode
*node
, *nnode
;
4031 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4034 /* see comment in peer_ttl_security_hops_set() */
4035 if (ttl
!= MAXTTL
) {
4036 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4037 group
= peer
->group
;
4038 if (group
->conf
->gtsm_hops
!= 0)
4039 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4041 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4043 if (peer1
->sort
== BGP_PEER_IBGP
)
4046 if (peer1
->gtsm_hops
!= 0)
4047 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4050 if (peer
->gtsm_hops
!= 0)
4051 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4057 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4058 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4059 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4060 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4061 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4063 bgp_session_reset(peer
);
4066 group
= peer
->group
;
4067 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4068 if (peer
->sort
== BGP_PEER_IBGP
)
4071 peer
->ttl
= group
->conf
->ttl
;
4073 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4074 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4075 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4077 bgp_session_reset(peer
);
4083 int peer_ebgp_multihop_unset(struct peer
*peer
)
4085 struct peer_group
*group
;
4086 struct listnode
*node
, *nnode
;
4088 if (peer
->sort
== BGP_PEER_IBGP
)
4091 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4092 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4094 if (peer_group_active(peer
))
4095 peer
->ttl
= peer
->group
->conf
->ttl
;
4099 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4100 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4101 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4102 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4104 bgp_session_reset(peer
);
4106 group
= peer
->group
;
4107 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4108 if (peer
->sort
== BGP_PEER_IBGP
)
4113 if (peer
->fd
>= 0) {
4114 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4116 peer
, BGP_NOTIFY_CEASE
,
4117 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4119 bgp_session_reset(peer
);
4126 /* Neighbor description. */
4127 int peer_description_set(struct peer
*peer
, const char *desc
)
4130 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4132 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4137 int peer_description_unset(struct peer
*peer
)
4140 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4147 /* Neighbor update-source. */
4148 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4150 struct peer_group
*group
;
4151 struct listnode
*node
, *nnode
;
4153 if (peer
->update_if
) {
4154 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4155 && strcmp(peer
->update_if
, ifname
) == 0)
4158 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4159 peer
->update_if
= NULL
;
4162 if (peer
->update_source
) {
4163 sockunion_free(peer
->update_source
);
4164 peer
->update_source
= NULL
;
4167 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4169 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4170 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4171 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4172 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4173 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4175 bgp_session_reset(peer
);
4179 /* peer-group member updates. */
4180 group
= peer
->group
;
4181 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4182 if (peer
->update_if
) {
4183 if (strcmp(peer
->update_if
, ifname
) == 0)
4186 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4187 peer
->update_if
= NULL
;
4190 if (peer
->update_source
) {
4191 sockunion_free(peer
->update_source
);
4192 peer
->update_source
= NULL
;
4195 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4197 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4198 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4199 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4200 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4202 bgp_session_reset(peer
);
4207 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4209 struct peer_group
*group
;
4210 struct listnode
*node
, *nnode
;
4212 if (peer
->update_source
) {
4213 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4214 && sockunion_cmp(peer
->update_source
, su
) == 0)
4216 sockunion_free(peer
->update_source
);
4217 peer
->update_source
= NULL
;
4220 if (peer
->update_if
) {
4221 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4222 peer
->update_if
= NULL
;
4225 peer
->update_source
= sockunion_dup(su
);
4227 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4228 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4229 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4230 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4231 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4233 bgp_session_reset(peer
);
4237 /* peer-group member updates. */
4238 group
= peer
->group
;
4239 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4240 if (peer
->update_source
) {
4241 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4243 sockunion_free(peer
->update_source
);
4244 peer
->update_source
= NULL
;
4247 if (peer
->update_if
) {
4248 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4249 peer
->update_if
= NULL
;
4252 peer
->update_source
= sockunion_dup(su
);
4254 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4255 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4256 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4257 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4259 bgp_session_reset(peer
);
4264 int peer_update_source_unset(struct peer
*peer
)
4266 union sockunion
*su
;
4267 struct peer_group
*group
;
4268 struct listnode
*node
, *nnode
;
4270 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4271 && !peer
->update_if
)
4274 if (peer
->update_source
) {
4275 sockunion_free(peer
->update_source
);
4276 peer
->update_source
= NULL
;
4278 if (peer
->update_if
) {
4279 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4280 peer
->update_if
= NULL
;
4283 if (peer_group_active(peer
)) {
4284 group
= peer
->group
;
4286 if (group
->conf
->update_source
) {
4287 su
= sockunion_dup(group
->conf
->update_source
);
4288 peer
->update_source
= su
;
4289 } else if (group
->conf
->update_if
)
4290 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4291 group
->conf
->update_if
);
4294 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4295 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4296 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4297 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4298 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4300 bgp_session_reset(peer
);
4304 /* peer-group member updates. */
4305 group
= peer
->group
;
4306 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4307 if (!peer
->update_source
&& !peer
->update_if
)
4310 if (peer
->update_source
) {
4311 sockunion_free(peer
->update_source
);
4312 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 (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4321 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4322 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4323 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4325 bgp_session_reset(peer
);
4330 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4333 struct peer_group
*group
;
4334 struct listnode
*node
, *nnode
;
4336 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4337 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4339 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4340 SET_FLAG(peer
->af_flags
[afi
][safi
],
4341 PEER_FLAG_DEFAULT_ORIGINATE
);
4344 if (peer
->default_rmap
[afi
][safi
].name
)
4345 XFREE(MTYPE_ROUTE_MAP_NAME
,
4346 peer
->default_rmap
[afi
][safi
].name
);
4347 peer
->default_rmap
[afi
][safi
].name
=
4348 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4349 peer
->default_rmap
[afi
][safi
].map
=
4350 route_map_lookup_by_name(rmap
);
4354 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4355 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4356 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4357 bgp_default_originate(peer
, afi
, safi
, 0);
4358 bgp_announce_route(peer
, afi
, safi
);
4363 /* peer-group member updates. */
4364 group
= peer
->group
;
4365 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4366 SET_FLAG(peer
->af_flags
[afi
][safi
],
4367 PEER_FLAG_DEFAULT_ORIGINATE
);
4370 if (peer
->default_rmap
[afi
][safi
].name
)
4371 XFREE(MTYPE_ROUTE_MAP_NAME
,
4372 peer
->default_rmap
[afi
][safi
].name
);
4373 peer
->default_rmap
[afi
][safi
].name
=
4374 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4375 peer
->default_rmap
[afi
][safi
].map
=
4376 route_map_lookup_by_name(rmap
);
4379 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4380 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4381 bgp_default_originate(peer
, afi
, safi
, 0);
4382 bgp_announce_route(peer
, afi
, safi
);
4388 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4390 struct peer_group
*group
;
4391 struct listnode
*node
, *nnode
;
4393 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4394 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4395 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4396 PEER_FLAG_DEFAULT_ORIGINATE
);
4398 if (peer
->default_rmap
[afi
][safi
].name
)
4399 XFREE(MTYPE_ROUTE_MAP_NAME
,
4400 peer
->default_rmap
[afi
][safi
].name
);
4401 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4402 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4405 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4406 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4407 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4408 bgp_default_originate(peer
, afi
, safi
, 1);
4409 bgp_announce_route(peer
, afi
, safi
);
4414 /* peer-group member updates. */
4415 group
= peer
->group
;
4416 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4417 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4418 PEER_FLAG_DEFAULT_ORIGINATE
);
4420 if (peer
->default_rmap
[afi
][safi
].name
)
4421 XFREE(MTYPE_ROUTE_MAP_NAME
,
4422 peer
->default_rmap
[afi
][safi
].name
);
4423 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4424 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4426 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4427 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4428 bgp_default_originate(peer
, afi
, safi
, 1);
4429 bgp_announce_route(peer
, afi
, safi
);
4435 int peer_port_set(struct peer
*peer
, u_int16_t port
)
4441 int peer_port_unset(struct peer
*peer
)
4443 peer
->port
= BGP_PORT_DEFAULT
;
4448 * Helper function that is called after the name of the policy
4449 * being used by a peer has changed (AF specific). Automatically
4450 * initiates inbound or outbound processing as needed.
4452 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4456 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4457 if (peer
->status
== Established
)
4458 bgp_announce_route(peer
, afi
, safi
);
4460 if (peer
->status
!= Established
)
4463 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4464 PEER_FLAG_SOFT_RECONFIG
))
4465 bgp_soft_reconfig_in(peer
, afi
, safi
);
4466 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4467 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4468 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4473 /* neighbor weight. */
4474 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, u_int16_t weight
)
4476 struct peer_group
*group
;
4477 struct listnode
*node
, *nnode
;
4479 if (peer
->weight
[afi
][safi
] != weight
) {
4480 peer
->weight
[afi
][safi
] = weight
;
4481 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4482 peer_on_policy_change(peer
, afi
, safi
, 0);
4485 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4488 /* peer-group member updates. */
4489 group
= peer
->group
;
4490 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4491 if (peer
->weight
[afi
][safi
] != weight
) {
4492 peer
->weight
[afi
][safi
] = weight
;
4493 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4494 peer_on_policy_change(peer
, afi
, safi
, 0);
4500 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4502 struct peer_group
*group
;
4503 struct listnode
*node
, *nnode
;
4505 /* not the peer-group itself but a peer in a peer-group */
4506 if (peer_group_active(peer
)) {
4507 group
= peer
->group
;
4509 /* inherit weight from the peer-group */
4510 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4511 PEER_FLAG_WEIGHT
)) {
4512 peer
->weight
[afi
][safi
] =
4513 group
->conf
->weight
[afi
][safi
];
4514 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4515 peer_on_policy_change(peer
, afi
, safi
, 0);
4517 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4518 PEER_FLAG_WEIGHT
)) {
4519 peer
->weight
[afi
][safi
] = 0;
4520 peer_af_flag_unset(peer
, afi
, safi
,
4522 peer_on_policy_change(peer
, afi
, safi
, 0);
4528 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4529 peer
->weight
[afi
][safi
] = 0;
4530 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4531 peer_on_policy_change(peer
, afi
, safi
, 0);
4534 /* peer-group member updates. */
4535 group
= peer
->group
;
4538 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4540 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4541 PEER_FLAG_WEIGHT
)) {
4542 peer
->weight
[afi
][safi
] = 0;
4543 peer_af_flag_unset(peer
, afi
, safi
,
4545 peer_on_policy_change(peer
, afi
, safi
,
4554 int peer_timers_set(struct peer
*peer
, u_int32_t keepalive
, u_int32_t holdtime
)
4556 struct peer_group
*group
;
4557 struct listnode
*node
, *nnode
;
4559 /* keepalive value check. */
4560 if (keepalive
> 65535)
4561 return BGP_ERR_INVALID_VALUE
;
4563 /* Holdtime value check. */
4564 if (holdtime
> 65535)
4565 return BGP_ERR_INVALID_VALUE
;
4567 /* Holdtime value must be either 0 or greater than 3. */
4568 if (holdtime
< 3 && holdtime
!= 0)
4569 return BGP_ERR_INVALID_VALUE
;
4571 /* Set value to the configuration. */
4572 peer
->holdtime
= holdtime
;
4573 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4575 /* First work on real peers with timers */
4576 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4577 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4578 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4580 /* Now work on the peer-group timers */
4581 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4583 /* peer-group member updates. */
4584 group
= peer
->group
;
4585 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4586 /* Skip peers that have their own timers */
4587 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4590 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4591 peer
->holdtime
= group
->conf
->holdtime
;
4592 peer
->keepalive
= group
->conf
->keepalive
;
4599 int peer_timers_unset(struct peer
*peer
)
4601 struct peer_group
*group
;
4602 struct listnode
*node
, *nnode
;
4604 /* First work on real peers vs the peer-group */
4605 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4606 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4607 peer
->keepalive
= 0;
4610 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4611 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4612 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4613 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4616 /* peer-group member updates. */
4617 group
= peer
->group
;
4618 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4619 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4620 UNSET_FLAG(peer
->config
,
4621 PEER_GROUP_CONFIG_TIMER
);
4623 peer
->keepalive
= 0;
4627 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4628 group
->conf
->holdtime
= 0;
4629 group
->conf
->keepalive
= 0;
4635 int peer_timers_connect_set(struct peer
*peer
, u_int32_t connect
)
4637 struct peer_group
*group
;
4638 struct listnode
*node
, *nnode
;
4640 if (connect
> 65535)
4641 return BGP_ERR_INVALID_VALUE
;
4643 /* Set value to the configuration. */
4644 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4645 peer
->connect
= connect
;
4647 /* Set value to timer setting. */
4648 peer
->v_connect
= connect
;
4650 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4653 /* peer-group member updates. */
4654 group
= peer
->group
;
4655 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4656 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4657 peer
->connect
= connect
;
4658 peer
->v_connect
= connect
;
4663 int peer_timers_connect_unset(struct peer
*peer
)
4665 struct peer_group
*group
;
4666 struct listnode
*node
, *nnode
;
4668 /* Clear configuration. */
4669 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4672 /* Set timer setting to default value. */
4673 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4675 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4678 /* peer-group member updates. */
4679 group
= peer
->group
;
4680 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4681 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4683 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4688 int peer_advertise_interval_set(struct peer
*peer
, u_int32_t routeadv
)
4690 struct peer_group
*group
;
4691 struct listnode
*node
, *nnode
;
4694 return BGP_ERR_INVALID_VALUE
;
4696 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4697 peer
->routeadv
= routeadv
;
4698 peer
->v_routeadv
= routeadv
;
4700 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4701 update_group_adjust_peer_afs(peer
);
4702 if (peer
->status
== Established
)
4703 bgp_announce_route_all(peer
);
4707 /* peer-group member updates. */
4708 group
= peer
->group
;
4709 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4710 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4711 peer
->routeadv
= routeadv
;
4712 peer
->v_routeadv
= routeadv
;
4713 update_group_adjust_peer_afs(peer
);
4714 if (peer
->status
== Established
)
4715 bgp_announce_route_all(peer
);
4721 int peer_advertise_interval_unset(struct peer
*peer
)
4723 struct peer_group
*group
;
4724 struct listnode
*node
, *nnode
;
4726 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4729 if (peer
->sort
== BGP_PEER_IBGP
)
4730 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4732 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4734 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4735 update_group_adjust_peer_afs(peer
);
4736 if (peer
->status
== Established
)
4737 bgp_announce_route_all(peer
);
4741 /* peer-group member updates. */
4742 group
= peer
->group
;
4743 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4744 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4747 if (peer
->sort
== BGP_PEER_IBGP
)
4748 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4750 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4752 update_group_adjust_peer_afs(peer
);
4753 if (peer
->status
== Established
)
4754 bgp_announce_route_all(peer
);
4760 /* neighbor interface */
4761 void peer_interface_set(struct peer
*peer
, const char *str
)
4764 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4765 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4768 void peer_interface_unset(struct peer
*peer
)
4771 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4772 peer
->ifname
= NULL
;
4776 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4777 int allow_num
, int origin
)
4779 struct peer_group
*group
;
4780 struct listnode
*node
, *nnode
;
4783 if (peer
->allowas_in
[afi
][safi
]
4784 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4785 PEER_FLAG_ALLOWAS_IN
)
4786 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4787 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4788 peer
->allowas_in
[afi
][safi
] = 0;
4789 peer_af_flag_unset(peer
, afi
, safi
,
4790 PEER_FLAG_ALLOWAS_IN
);
4791 peer_af_flag_set(peer
, afi
, safi
,
4792 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4793 peer_on_policy_change(peer
, afi
, safi
, 0);
4796 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4799 group
= peer
->group
;
4800 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4801 if (peer
->allowas_in
[afi
][safi
]
4802 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4803 PEER_FLAG_ALLOWAS_IN
)
4804 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4805 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4806 peer
->allowas_in
[afi
][safi
] = 0;
4807 peer_af_flag_unset(peer
, afi
, safi
,
4808 PEER_FLAG_ALLOWAS_IN
);
4809 peer_af_flag_set(peer
, afi
, safi
,
4810 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4811 peer_on_policy_change(peer
, afi
, safi
, 0);
4815 if (allow_num
< 1 || allow_num
> 10)
4816 return BGP_ERR_INVALID_VALUE
;
4818 if (peer
->allowas_in
[afi
][safi
] != allow_num
4819 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4820 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4821 peer
->allowas_in
[afi
][safi
] = allow_num
;
4822 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4823 peer_af_flag_unset(peer
, afi
, safi
,
4824 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4825 peer_on_policy_change(peer
, afi
, safi
, 0);
4828 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4831 group
= peer
->group
;
4832 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4833 if (peer
->allowas_in
[afi
][safi
] != allow_num
4834 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4835 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4836 peer
->allowas_in
[afi
][safi
] = allow_num
;
4837 peer_af_flag_set(peer
, afi
, safi
,
4838 PEER_FLAG_ALLOWAS_IN
);
4839 peer_af_flag_unset(peer
, afi
, safi
,
4840 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4841 peer_on_policy_change(peer
, afi
, safi
, 0);
4849 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4851 struct peer_group
*group
;
4852 struct peer
*tmp_peer
;
4853 struct listnode
*node
, *nnode
;
4855 /* If this is a peer-group we must first clear the flags for all of the
4856 * peer-group members
4858 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4859 group
= peer
->group
;
4860 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4861 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4862 PEER_FLAG_ALLOWAS_IN
)
4863 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4864 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4865 tmp_peer
->allowas_in
[afi
][safi
] = 0;
4866 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4867 PEER_FLAG_ALLOWAS_IN
);
4868 peer_af_flag_unset(tmp_peer
, afi
, safi
,
4869 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4870 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
4875 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
4876 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4877 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4878 peer
->allowas_in
[afi
][safi
] = 0;
4879 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4880 peer_af_flag_unset(peer
, afi
, safi
,
4881 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4882 peer_on_policy_change(peer
, afi
, safi
, 0);
4888 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
4891 struct bgp
*bgp
= peer
->bgp
;
4892 struct peer_group
*group
;
4893 struct listnode
*node
, *nnode
;
4895 if (peer_sort(peer
) != BGP_PEER_EBGP
4896 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
4897 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
4900 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
4903 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
4905 if (peer
->change_local_as
== as
4906 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4908 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
4910 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4912 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
4916 peer
->change_local_as
= as
;
4918 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4920 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4923 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4925 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4927 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4928 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4929 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4930 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4931 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4933 bgp_session_reset(peer
);
4937 group
= peer
->group
;
4938 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4939 peer
->change_local_as
= as
;
4941 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4943 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4946 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4948 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4950 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4951 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4952 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4953 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4955 BGP_EVENT_ADD(peer
, BGP_Stop
);
4961 int peer_local_as_unset(struct peer
*peer
)
4963 struct peer_group
*group
;
4964 struct listnode
*node
, *nnode
;
4966 if (!peer
->change_local_as
)
4969 peer
->change_local_as
= 0;
4970 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4971 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4973 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4974 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4975 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4976 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4977 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4979 BGP_EVENT_ADD(peer
, BGP_Stop
);
4984 group
= peer
->group
;
4985 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4986 peer
->change_local_as
= 0;
4987 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
4988 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
4990 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4991 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
4992 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4993 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4995 bgp_session_reset(peer
);
5000 /* Set password for authenticating with the peer. */
5001 int peer_password_set(struct peer
*peer
, const char *password
)
5003 struct listnode
*nn
, *nnode
;
5004 int len
= password
? strlen(password
) : 0;
5005 int ret
= BGP_SUCCESS
;
5007 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5008 return BGP_ERR_INVALID_VALUE
;
5010 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5011 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5015 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5017 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5019 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5020 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5021 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5022 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5024 bgp_session_reset(peer
);
5026 if (BGP_PEER_SU_UNSPEC(peer
))
5029 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5030 : BGP_ERR_TCPSIG_FAILED
;
5033 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5034 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5038 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5040 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5042 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5043 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5044 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5046 bgp_session_reset(peer
);
5048 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5049 if (bgp_md5_set(peer
) < 0)
5050 ret
= BGP_ERR_TCPSIG_FAILED
;
5057 int peer_password_unset(struct peer
*peer
)
5059 struct listnode
*nn
, *nnode
;
5061 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5064 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5065 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5066 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5067 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5069 bgp_session_reset(peer
);
5072 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5074 peer
->password
= NULL
;
5076 if (!BGP_PEER_SU_UNSPEC(peer
))
5077 bgp_md5_unset(peer
);
5082 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5083 peer
->password
= NULL
;
5085 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5086 if (!peer
->password
)
5089 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5090 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5091 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5093 bgp_session_reset(peer
);
5095 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5096 peer
->password
= NULL
;
5098 if (!BGP_PEER_SU_UNSPEC(peer
))
5099 bgp_md5_unset(peer
);
5106 /* Set distribute list to the peer. */
5107 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5110 struct bgp_filter
*filter
;
5111 struct peer_group
*group
;
5112 struct listnode
*node
, *nnode
;
5114 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5115 return BGP_ERR_INVALID_VALUE
;
5117 filter
= &peer
->filter
[afi
][safi
];
5119 if (filter
->plist
[direct
].name
)
5120 return BGP_ERR_PEER_FILTER_CONFLICT
;
5122 if (filter
->dlist
[direct
].name
)
5123 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5124 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5125 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5127 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5128 peer_on_policy_change(peer
, afi
, safi
,
5129 (direct
== FILTER_OUT
) ? 1 : 0);
5133 group
= peer
->group
;
5134 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5135 filter
= &peer
->filter
[afi
][safi
];
5137 if (filter
->dlist
[direct
].name
)
5138 XFREE(MTYPE_BGP_FILTER_NAME
,
5139 filter
->dlist
[direct
].name
);
5140 filter
->dlist
[direct
].name
=
5141 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5142 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5143 peer_on_policy_change(peer
, afi
, safi
,
5144 (direct
== FILTER_OUT
) ? 1 : 0);
5150 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5152 struct bgp_filter
*filter
;
5153 struct bgp_filter
*gfilter
;
5154 struct peer_group
*group
;
5155 struct listnode
*node
, *nnode
;
5157 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5158 return BGP_ERR_INVALID_VALUE
;
5160 filter
= &peer
->filter
[afi
][safi
];
5162 /* apply peer-group filter */
5163 if (peer_group_active(peer
)) {
5164 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5166 if (gfilter
->dlist
[direct
].name
) {
5167 if (filter
->dlist
[direct
].name
)
5168 XFREE(MTYPE_BGP_FILTER_NAME
,
5169 filter
->dlist
[direct
].name
);
5170 filter
->dlist
[direct
].name
=
5171 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5172 gfilter
->dlist
[direct
].name
);
5173 filter
->dlist
[direct
].alist
=
5174 gfilter
->dlist
[direct
].alist
;
5175 peer_on_policy_change(peer
, afi
, safi
,
5176 (direct
== FILTER_OUT
) ? 1 : 0);
5181 if (filter
->dlist
[direct
].name
)
5182 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5183 filter
->dlist
[direct
].name
= NULL
;
5184 filter
->dlist
[direct
].alist
= NULL
;
5186 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5187 peer_on_policy_change(peer
, afi
, safi
,
5188 (direct
== FILTER_OUT
) ? 1 : 0);
5192 group
= peer
->group
;
5193 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5194 filter
= &peer
->filter
[afi
][safi
];
5196 if (filter
->dlist
[direct
].name
)
5197 XFREE(MTYPE_BGP_FILTER_NAME
,
5198 filter
->dlist
[direct
].name
);
5199 filter
->dlist
[direct
].name
= NULL
;
5200 filter
->dlist
[direct
].alist
= NULL
;
5201 peer_on_policy_change(peer
, afi
, safi
,
5202 (direct
== FILTER_OUT
) ? 1 : 0);
5208 /* Update distribute list. */
5209 static void peer_distribute_update(struct access_list
*access
)
5214 struct listnode
*mnode
, *mnnode
;
5215 struct listnode
*node
, *nnode
;
5218 struct peer_group
*group
;
5219 struct bgp_filter
*filter
;
5221 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5223 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5224 access
->name
, 0, 0);
5225 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5226 FOREACH_AFI_SAFI (afi
, safi
) {
5227 filter
= &peer
->filter
[afi
][safi
];
5229 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5231 if (filter
->dlist
[direct
].name
)
5232 filter
->dlist
[direct
]
5233 .alist
= access_list_lookup(
5235 filter
->dlist
[direct
]
5238 filter
->dlist
[direct
].alist
=
5243 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5244 FOREACH_AFI_SAFI (afi
, safi
) {
5245 filter
= &group
->conf
->filter
[afi
][safi
];
5247 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5249 if (filter
->dlist
[direct
].name
)
5250 filter
->dlist
[direct
]
5251 .alist
= access_list_lookup(
5253 filter
->dlist
[direct
]
5256 filter
->dlist
[direct
].alist
=
5262 vnc_prefix_list_update(bgp
);
5267 /* Set prefix list to the peer. */
5268 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5271 struct bgp_filter
*filter
;
5272 struct peer_group
*group
;
5273 struct listnode
*node
, *nnode
;
5275 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5276 return BGP_ERR_INVALID_VALUE
;
5278 filter
= &peer
->filter
[afi
][safi
];
5280 if (filter
->dlist
[direct
].name
)
5281 return BGP_ERR_PEER_FILTER_CONFLICT
;
5283 if (filter
->plist
[direct
].name
)
5284 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5285 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5286 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5288 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5289 peer_on_policy_change(peer
, afi
, safi
,
5290 (direct
== FILTER_OUT
) ? 1 : 0);
5294 group
= peer
->group
;
5295 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5296 filter
= &peer
->filter
[afi
][safi
];
5298 if (filter
->plist
[direct
].name
)
5299 XFREE(MTYPE_BGP_FILTER_NAME
,
5300 filter
->plist
[direct
].name
);
5301 filter
->plist
[direct
].name
=
5302 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5303 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5304 peer_on_policy_change(peer
, afi
, safi
,
5305 (direct
== FILTER_OUT
) ? 1 : 0);
5310 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5313 struct bgp_filter
*filter
;
5314 struct bgp_filter
*gfilter
;
5315 struct peer_group
*group
;
5316 struct listnode
*node
, *nnode
;
5318 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5319 return BGP_ERR_INVALID_VALUE
;
5321 filter
= &peer
->filter
[afi
][safi
];
5323 /* apply peer-group filter */
5324 if (peer_group_active(peer
)) {
5325 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5327 if (gfilter
->plist
[direct
].name
) {
5328 if (filter
->plist
[direct
].name
)
5329 XFREE(MTYPE_BGP_FILTER_NAME
,
5330 filter
->plist
[direct
].name
);
5331 filter
->plist
[direct
].name
=
5332 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5333 gfilter
->plist
[direct
].name
);
5334 filter
->plist
[direct
].plist
=
5335 gfilter
->plist
[direct
].plist
;
5336 peer_on_policy_change(peer
, afi
, safi
,
5337 (direct
== FILTER_OUT
) ? 1 : 0);
5342 if (filter
->plist
[direct
].name
)
5343 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5344 filter
->plist
[direct
].name
= NULL
;
5345 filter
->plist
[direct
].plist
= NULL
;
5347 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5348 peer_on_policy_change(peer
, afi
, safi
,
5349 (direct
== FILTER_OUT
) ? 1 : 0);
5353 group
= peer
->group
;
5354 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5355 filter
= &peer
->filter
[afi
][safi
];
5357 if (filter
->plist
[direct
].name
)
5358 XFREE(MTYPE_BGP_FILTER_NAME
,
5359 filter
->plist
[direct
].name
);
5360 filter
->plist
[direct
].name
= NULL
;
5361 filter
->plist
[direct
].plist
= NULL
;
5362 peer_on_policy_change(peer
, afi
, safi
,
5363 (direct
== FILTER_OUT
) ? 1 : 0);
5369 /* Update prefix-list list. */
5370 static void peer_prefix_list_update(struct prefix_list
*plist
)
5372 struct listnode
*mnode
, *mnnode
;
5373 struct listnode
*node
, *nnode
;
5376 struct peer_group
*group
;
5377 struct bgp_filter
*filter
;
5382 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5385 * Update the prefix-list on update groups.
5387 update_group_policy_update(
5388 bgp
, BGP_POLICY_PREFIX_LIST
,
5389 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5391 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5392 FOREACH_AFI_SAFI (afi
, safi
) {
5393 filter
= &peer
->filter
[afi
][safi
];
5395 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5397 if (filter
->plist
[direct
].name
)
5398 filter
->plist
[direct
]
5399 .plist
= prefix_list_lookup(
5401 filter
->plist
[direct
]
5404 filter
->plist
[direct
].plist
=
5409 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5410 FOREACH_AFI_SAFI (afi
, safi
) {
5411 filter
= &group
->conf
->filter
[afi
][safi
];
5413 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5415 if (filter
->plist
[direct
].name
)
5416 filter
->plist
[direct
]
5417 .plist
= prefix_list_lookup(
5419 filter
->plist
[direct
]
5422 filter
->plist
[direct
].plist
=
5430 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5433 struct bgp_filter
*filter
;
5434 struct peer_group
*group
;
5435 struct listnode
*node
, *nnode
;
5437 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5438 return BGP_ERR_INVALID_VALUE
;
5440 filter
= &peer
->filter
[afi
][safi
];
5442 if (filter
->aslist
[direct
].name
)
5443 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5444 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5445 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5447 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5448 peer_on_policy_change(peer
, afi
, safi
,
5449 (direct
== FILTER_OUT
) ? 1 : 0);
5453 group
= peer
->group
;
5454 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5455 filter
= &peer
->filter
[afi
][safi
];
5457 if (filter
->aslist
[direct
].name
)
5458 XFREE(MTYPE_BGP_FILTER_NAME
,
5459 filter
->aslist
[direct
].name
);
5460 filter
->aslist
[direct
].name
=
5461 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5462 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5463 peer_on_policy_change(peer
, afi
, safi
,
5464 (direct
== FILTER_OUT
) ? 1 : 0);
5469 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5471 struct bgp_filter
*filter
;
5472 struct bgp_filter
*gfilter
;
5473 struct peer_group
*group
;
5474 struct listnode
*node
, *nnode
;
5476 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5477 return BGP_ERR_INVALID_VALUE
;
5479 filter
= &peer
->filter
[afi
][safi
];
5481 /* apply peer-group filter */
5482 if (peer_group_active(peer
)) {
5483 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5485 if (gfilter
->aslist
[direct
].name
) {
5486 if (filter
->aslist
[direct
].name
)
5487 XFREE(MTYPE_BGP_FILTER_NAME
,
5488 filter
->aslist
[direct
].name
);
5489 filter
->aslist
[direct
].name
=
5490 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5491 gfilter
->aslist
[direct
].name
);
5492 filter
->aslist
[direct
].aslist
=
5493 gfilter
->aslist
[direct
].aslist
;
5494 peer_on_policy_change(peer
, afi
, safi
,
5495 (direct
== FILTER_OUT
) ? 1 : 0);
5500 if (filter
->aslist
[direct
].name
)
5501 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5502 filter
->aslist
[direct
].name
= NULL
;
5503 filter
->aslist
[direct
].aslist
= NULL
;
5505 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5506 peer_on_policy_change(peer
, afi
, safi
,
5507 (direct
== FILTER_OUT
) ? 1 : 0);
5511 group
= peer
->group
;
5512 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5513 filter
= &peer
->filter
[afi
][safi
];
5515 if (filter
->aslist
[direct
].name
)
5516 XFREE(MTYPE_BGP_FILTER_NAME
,
5517 filter
->aslist
[direct
].name
);
5518 filter
->aslist
[direct
].name
= NULL
;
5519 filter
->aslist
[direct
].aslist
= NULL
;
5520 peer_on_policy_change(peer
, afi
, safi
,
5521 (direct
== FILTER_OUT
) ? 1 : 0);
5527 static void peer_aslist_update(const char *aslist_name
)
5532 struct listnode
*mnode
, *mnnode
;
5533 struct listnode
*node
, *nnode
;
5536 struct peer_group
*group
;
5537 struct bgp_filter
*filter
;
5539 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5540 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5543 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5544 FOREACH_AFI_SAFI (afi
, safi
) {
5545 filter
= &peer
->filter
[afi
][safi
];
5547 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5549 if (filter
->aslist
[direct
].name
)
5550 filter
->aslist
[direct
]
5551 .aslist
= as_list_lookup(
5552 filter
->aslist
[direct
]
5555 filter
->aslist
[direct
].aslist
=
5560 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5561 FOREACH_AFI_SAFI (afi
, safi
) {
5562 filter
= &group
->conf
->filter
[afi
][safi
];
5564 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5566 if (filter
->aslist
[direct
].name
)
5567 filter
->aslist
[direct
]
5568 .aslist
= as_list_lookup(
5569 filter
->aslist
[direct
]
5572 filter
->aslist
[direct
].aslist
=
5580 static void peer_aslist_add(char *aslist_name
)
5582 peer_aslist_update(aslist_name
);
5583 route_map_notify_dependencies((char *)aslist_name
,
5584 RMAP_EVENT_ASLIST_ADDED
);
5587 static void peer_aslist_del(const char *aslist_name
)
5589 peer_aslist_update(aslist_name
);
5590 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5594 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5597 struct bgp_filter
*filter
;
5598 struct peer_group
*group
;
5599 struct listnode
*node
, *nnode
;
5601 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5602 return BGP_ERR_INVALID_VALUE
;
5604 filter
= &peer
->filter
[afi
][safi
];
5606 if (filter
->map
[direct
].name
)
5607 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5609 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5610 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5612 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5613 peer_on_policy_change(peer
, afi
, safi
,
5614 (direct
== RMAP_OUT
) ? 1 : 0);
5618 group
= peer
->group
;
5619 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5620 filter
= &peer
->filter
[afi
][safi
];
5622 if (filter
->map
[direct
].name
)
5623 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5624 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5625 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5626 peer_on_policy_change(peer
, afi
, safi
,
5627 (direct
== RMAP_OUT
) ? 1 : 0);
5632 /* Unset route-map from the peer. */
5633 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5635 struct bgp_filter
*filter
;
5636 struct bgp_filter
*gfilter
;
5637 struct peer_group
*group
;
5638 struct listnode
*node
, *nnode
;
5640 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5641 return BGP_ERR_INVALID_VALUE
;
5643 filter
= &peer
->filter
[afi
][safi
];
5645 /* apply peer-group filter */
5646 if (peer_group_active(peer
)) {
5647 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5649 if (gfilter
->map
[direct
].name
) {
5650 if (filter
->map
[direct
].name
)
5651 XFREE(MTYPE_BGP_FILTER_NAME
,
5652 filter
->map
[direct
].name
);
5653 filter
->map
[direct
].name
=
5654 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5655 gfilter
->map
[direct
].name
);
5656 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5657 peer_on_policy_change(peer
, afi
, safi
,
5658 (direct
== RMAP_OUT
) ? 1 : 0);
5663 if (filter
->map
[direct
].name
)
5664 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5665 filter
->map
[direct
].name
= NULL
;
5666 filter
->map
[direct
].map
= NULL
;
5668 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5669 peer_on_policy_change(peer
, afi
, safi
,
5670 (direct
== RMAP_OUT
) ? 1 : 0);
5674 group
= peer
->group
;
5675 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5676 filter
= &peer
->filter
[afi
][safi
];
5678 if (filter
->map
[direct
].name
)
5679 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5680 filter
->map
[direct
].name
= NULL
;
5681 filter
->map
[direct
].map
= NULL
;
5682 peer_on_policy_change(peer
, afi
, safi
,
5683 (direct
== RMAP_OUT
) ? 1 : 0);
5688 /* Set unsuppress-map to the peer. */
5689 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5692 struct bgp_filter
*filter
;
5693 struct peer_group
*group
;
5694 struct listnode
*node
, *nnode
;
5696 filter
= &peer
->filter
[afi
][safi
];
5698 if (filter
->usmap
.name
)
5699 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5701 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5702 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5704 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5705 peer_on_policy_change(peer
, afi
, safi
, 1);
5709 group
= peer
->group
;
5710 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5711 filter
= &peer
->filter
[afi
][safi
];
5713 if (filter
->usmap
.name
)
5714 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5715 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5716 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5717 peer_on_policy_change(peer
, afi
, safi
, 1);
5722 /* Unset route-map from the peer. */
5723 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5725 struct bgp_filter
*filter
;
5726 struct peer_group
*group
;
5727 struct listnode
*node
, *nnode
;
5729 filter
= &peer
->filter
[afi
][safi
];
5731 if (filter
->usmap
.name
)
5732 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5733 filter
->usmap
.name
= NULL
;
5734 filter
->usmap
.map
= NULL
;
5736 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5737 peer_on_policy_change(peer
, afi
, safi
, 1);
5741 group
= peer
->group
;
5742 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5743 filter
= &peer
->filter
[afi
][safi
];
5745 if (filter
->usmap
.name
)
5746 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5747 filter
->usmap
.name
= NULL
;
5748 filter
->usmap
.map
= NULL
;
5749 peer_on_policy_change(peer
, afi
, safi
, 1);
5754 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5755 u_int32_t max
, u_char threshold
, int warning
,
5758 struct peer_group
*group
;
5759 struct listnode
*node
, *nnode
;
5761 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5762 peer
->pmax
[afi
][safi
] = max
;
5763 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5764 peer
->pmax_restart
[afi
][safi
] = restart
;
5766 SET_FLAG(peer
->af_flags
[afi
][safi
],
5767 PEER_FLAG_MAX_PREFIX_WARNING
);
5769 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5770 PEER_FLAG_MAX_PREFIX_WARNING
);
5772 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5773 group
= peer
->group
;
5774 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5775 SET_FLAG(peer
->af_flags
[afi
][safi
],
5776 PEER_FLAG_MAX_PREFIX
);
5777 peer
->pmax
[afi
][safi
] = max
;
5778 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5779 peer
->pmax_restart
[afi
][safi
] = restart
;
5781 SET_FLAG(peer
->af_flags
[afi
][safi
],
5782 PEER_FLAG_MAX_PREFIX_WARNING
);
5784 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5785 PEER_FLAG_MAX_PREFIX_WARNING
);
5787 if ((peer
->status
== Established
)
5788 && (peer
->afc
[afi
][safi
]))
5789 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5792 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5793 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5799 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5801 struct peer_group
*group
;
5802 struct listnode
*node
, *nnode
;
5804 /* apply peer-group config */
5805 if (peer_group_active(peer
)) {
5806 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5807 PEER_FLAG_MAX_PREFIX
))
5808 SET_FLAG(peer
->af_flags
[afi
][safi
],
5809 PEER_FLAG_MAX_PREFIX
);
5811 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5812 PEER_FLAG_MAX_PREFIX
);
5814 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5815 PEER_FLAG_MAX_PREFIX_WARNING
))
5816 SET_FLAG(peer
->af_flags
[afi
][safi
],
5817 PEER_FLAG_MAX_PREFIX_WARNING
);
5819 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5820 PEER_FLAG_MAX_PREFIX_WARNING
);
5822 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
5823 peer
->pmax_threshold
[afi
][safi
] =
5824 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
5825 peer
->pmax_restart
[afi
][safi
] =
5826 peer
->group
->conf
->pmax_restart
[afi
][safi
];
5830 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5831 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
5832 peer
->pmax
[afi
][safi
] = 0;
5833 peer
->pmax_threshold
[afi
][safi
] = 0;
5834 peer
->pmax_restart
[afi
][safi
] = 0;
5836 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5839 group
= peer
->group
;
5840 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5841 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5842 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5843 PEER_FLAG_MAX_PREFIX_WARNING
);
5844 peer
->pmax
[afi
][safi
] = 0;
5845 peer
->pmax_threshold
[afi
][safi
] = 0;
5846 peer
->pmax_restart
[afi
][safi
] = 0;
5851 int is_ebgp_multihop_configured(struct peer
*peer
)
5853 struct peer_group
*group
;
5854 struct listnode
*node
, *nnode
;
5857 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5858 group
= peer
->group
;
5859 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
5860 && (group
->conf
->ttl
!= 1))
5863 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
5864 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
5865 && (peer1
->ttl
!= 1))
5869 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
5875 /* Set # of hops between us and BGP peer. */
5876 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
5878 struct peer_group
*group
;
5879 struct listnode
*node
, *nnode
;
5882 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
5883 gtsm_hops
, peer
->host
);
5885 /* We cannot configure ttl-security hops when ebgp-multihop is already
5886 set. For non peer-groups, the check is simple. For peer-groups,
5888 slightly messy, because we need to check both the peer-group
5890 and all peer-group members for any trace of ebgp-multihop
5892 before actually applying the ttl-security rules. Cisco really made a
5893 mess of this configuration parameter, and OpenBGPD got it right.
5896 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
5897 if (is_ebgp_multihop_configured(peer
))
5898 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
5900 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5901 peer
->gtsm_hops
= gtsm_hops
;
5903 /* Calling ebgp multihop also resets the session.
5904 * On restart, NHT will get setup correctly as will the
5905 * min & max ttls on the socket. The return value is
5908 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
5913 group
= peer
->group
;
5914 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5916 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5918 /* Calling ebgp multihop also resets the
5920 * On restart, NHT will get setup correctly as
5922 * min & max ttls on the socket. The return
5926 peer_ebgp_multihop_set(peer
, MAXTTL
);
5930 /* Post the first gtsm setup or if its ibgp, maxttl setting
5932 * necessary, just set the minttl.
5934 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5935 peer
->gtsm_hops
= gtsm_hops
;
5938 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
5939 MAXTTL
+ 1 - gtsm_hops
);
5940 if ((peer
->status
< Established
) && peer
->doppelganger
5941 && (peer
->doppelganger
->fd
>= 0))
5942 sockopt_minttl(peer
->su
.sa
.sa_family
,
5943 peer
->doppelganger
->fd
,
5944 MAXTTL
+ 1 - gtsm_hops
);
5946 group
= peer
->group
;
5947 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
5949 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
5951 /* Change setting of existing peer
5952 * established then change value (may break
5954 * not established yet (teardown session and
5956 * no session then do nothing (will get
5957 * handled by next connection)
5959 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
5961 peer
->su
.sa
.sa_family
, peer
->fd
,
5962 MAXTTL
+ 1 - peer
->gtsm_hops
);
5963 if ((peer
->status
< Established
)
5964 && peer
->doppelganger
5965 && (peer
->doppelganger
->fd
>= 0))
5966 sockopt_minttl(peer
->su
.sa
.sa_family
,
5967 peer
->doppelganger
->fd
,
5968 MAXTTL
+ 1 - gtsm_hops
);
5976 int peer_ttl_security_hops_unset(struct peer
*peer
)
5978 struct peer_group
*group
;
5979 struct listnode
*node
, *nnode
;
5982 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
5985 /* if a peer-group member, then reset to peer-group default rather than
5987 if (peer_group_active(peer
))
5988 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
5990 peer
->gtsm_hops
= 0;
5992 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5993 /* Invoking ebgp_multihop_set will set the TTL back to the
5995 * value as well as restting the NHT and such. The session is
5998 if (peer
->sort
== BGP_PEER_EBGP
)
5999 ret
= peer_ebgp_multihop_unset(peer
);
6002 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6005 if ((peer
->status
< Established
) && peer
->doppelganger
6006 && (peer
->doppelganger
->fd
>= 0))
6007 sockopt_minttl(peer
->su
.sa
.sa_family
,
6008 peer
->doppelganger
->fd
, 0);
6011 group
= peer
->group
;
6012 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6013 peer
->gtsm_hops
= 0;
6014 if (peer
->sort
== BGP_PEER_EBGP
)
6015 ret
= peer_ebgp_multihop_unset(peer
);
6018 sockopt_minttl(peer
->su
.sa
.sa_family
,
6021 if ((peer
->status
< Established
)
6022 && peer
->doppelganger
6023 && (peer
->doppelganger
->fd
>= 0))
6024 sockopt_minttl(peer
->su
.sa
.sa_family
,
6025 peer
->doppelganger
->fd
,
6035 * If peer clear is invoked in a loop for all peers on the BGP instance,
6036 * it may end up freeing the doppelganger, and if this was the next node
6037 * to the current node, we would end up accessing the freed next node.
6038 * Pass along additional parameter which can be updated if next node
6039 * is freed; only required when walking the peer list on BGP instance.
6041 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6043 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6044 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6045 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6046 if (peer
->t_pmax_restart
) {
6047 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6048 if (bgp_debug_neighbor_events(peer
))
6050 "%s Maximum-prefix restart timer canceled",
6053 BGP_EVENT_ADD(peer
, BGP_Start
);
6057 peer
->v_start
= BGP_INIT_START_TIMER
;
6058 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6059 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6060 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6062 bgp_session_reset_safe(peer
, nnode
);
6067 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6068 enum bgp_clear_type stype
)
6070 struct peer_af
*paf
;
6072 if (peer
->status
!= Established
)
6075 if (!peer
->afc
[afi
][safi
])
6076 return BGP_ERR_AF_UNCONFIGURED
;
6078 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6080 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6081 /* Clear the "neighbor x.x.x.x default-originate" flag */
6082 paf
= peer_af_find(peer
, afi
, safi
);
6083 if (paf
&& paf
->subgroup
6084 && CHECK_FLAG(paf
->subgroup
->sflags
,
6085 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6086 UNSET_FLAG(paf
->subgroup
->sflags
,
6087 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6089 bgp_announce_route(peer
, afi
, safi
);
6092 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6093 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6094 PEER_CAP_ORF_PREFIX_SM_ADV
)
6095 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6096 PEER_CAP_ORF_PREFIX_RM_RCV
)
6097 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6098 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6099 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6102 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6103 PEER_CAP_ORF_PREFIX_RM_RCV
))
6104 prefix_type
= ORF_TYPE_PREFIX
;
6106 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6108 if (filter
->plist
[FILTER_IN
].plist
) {
6109 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6110 PEER_STATUS_ORF_PREFIX_SEND
))
6111 bgp_route_refresh_send(
6112 peer
, afi
, safi
, prefix_type
,
6114 bgp_route_refresh_send(peer
, afi
, safi
,
6116 REFRESH_IMMEDIATE
, 0);
6118 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6119 PEER_STATUS_ORF_PREFIX_SEND
))
6120 bgp_route_refresh_send(
6121 peer
, afi
, safi
, prefix_type
,
6122 REFRESH_IMMEDIATE
, 1);
6124 bgp_route_refresh_send(peer
, afi
, safi
,
6131 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6132 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6133 /* If neighbor has soft reconfiguration inbound flag.
6134 Use Adj-RIB-In database. */
6135 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6136 PEER_FLAG_SOFT_RECONFIG
))
6137 bgp_soft_reconfig_in(peer
, afi
, safi
);
6139 /* If neighbor has route refresh capability, send route
6141 message to the peer. */
6142 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6143 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6144 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6147 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6153 /* Display peer uptime.*/
6154 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, u_char use_json
,
6157 time_t uptime1
, epoch_tbuf
;
6160 /* Check buffer length. */
6161 if (len
< BGP_UPTIME_LEN
) {
6163 zlog_warn("peer_uptime (): buffer shortage %lu",
6165 /* XXX: should return status instead of buf... */
6166 snprintf(buf
, len
, "<error> ");
6171 /* If there is no connection has been done before print `never'. */
6174 json_object_string_add(json
, "peerUptime", "never");
6175 json_object_int_add(json
, "peerUptimeMsec", 0);
6177 snprintf(buf
, len
, "never");
6181 /* Get current time. */
6182 uptime1
= bgp_clock();
6184 tm
= gmtime(&uptime1
);
6186 if (uptime1
< ONE_DAY_SECOND
)
6187 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6189 else if (uptime1
< ONE_WEEK_SECOND
)
6190 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6192 else if (uptime1
< ONE_YEAR_SECOND
)
6193 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6194 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6196 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6198 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6201 epoch_tbuf
= time(NULL
) - uptime1
;
6202 json_object_string_add(json
, "peerUptime", buf
);
6203 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6204 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6211 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6212 afi_t afi
, safi_t safi
)
6214 struct bgp_filter
*filter
;
6215 struct bgp_filter
*gfilter
= NULL
;
6218 int out
= FILTER_OUT
;
6221 filter
= &peer
->filter
[afi
][safi
];
6223 if (peer_group_active(peer
))
6224 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6226 /* distribute-list. */
6227 if (filter
->dlist
[in
].name
)
6228 if (!gfilter
|| !gfilter
->dlist
[in
].name
6229 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6231 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6232 addr
, filter
->dlist
[in
].name
);
6235 if (filter
->dlist
[out
].name
&& !gfilter
) {
6236 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6237 filter
->dlist
[out
].name
);
6241 if (filter
->plist
[in
].name
)
6242 if (!gfilter
|| !gfilter
->plist
[in
].name
6243 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6245 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6246 filter
->plist
[in
].name
);
6249 if (filter
->plist
[out
].name
)
6250 if (!gfilter
|| !gfilter
->plist
[out
].name
6251 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6253 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6254 filter
->plist
[out
].name
);
6258 if (filter
->map
[RMAP_IN
].name
)
6259 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6260 || strcmp(filter
->map
[RMAP_IN
].name
,
6261 gfilter
->map
[RMAP_IN
].name
)
6263 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6264 filter
->map
[RMAP_IN
].name
);
6267 if (filter
->map
[RMAP_OUT
].name
)
6268 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6269 || strcmp(filter
->map
[RMAP_OUT
].name
,
6270 gfilter
->map
[RMAP_OUT
].name
)
6272 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6273 filter
->map
[RMAP_OUT
].name
);
6276 /* unsuppress-map */
6277 if (filter
->usmap
.name
&& !gfilter
) {
6278 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6279 filter
->usmap
.name
);
6283 if (filter
->aslist
[in
].name
)
6284 if (!gfilter
|| !gfilter
->aslist
[in
].name
6285 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6287 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6288 filter
->aslist
[in
].name
);
6291 if (filter
->aslist
[out
].name
&& !gfilter
) {
6292 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6293 filter
->aslist
[out
].name
);
6297 /* BGP peer configuration display function. */
6298 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6301 struct peer
*g_peer
= NULL
;
6302 char buf
[SU_ADDRSTRLEN
];
6304 int if_pg_printed
= FALSE
;
6305 int if_ras_printed
= FALSE
;
6307 /* Skip dynamic neighbors. */
6308 if (peer_dynamic_neighbor(peer
))
6312 addr
= peer
->conf_if
;
6316 /************************************
6317 ****** Global to the neighbor ******
6318 ************************************/
6319 if (peer
->conf_if
) {
6320 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6321 vty_out(vty
, " neighbor %s interface v6only", addr
);
6323 vty_out(vty
, " neighbor %s interface", addr
);
6325 if (peer_group_active(peer
)) {
6326 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6327 if_pg_printed
= TRUE
;
6328 } else if (peer
->as_type
== AS_SPECIFIED
) {
6329 vty_out(vty
, " remote-as %u", peer
->as
);
6330 if_ras_printed
= TRUE
;
6331 } else if (peer
->as_type
== AS_INTERNAL
) {
6332 vty_out(vty
, " remote-as internal");
6333 if_ras_printed
= TRUE
;
6334 } else if (peer
->as_type
== AS_EXTERNAL
) {
6335 vty_out(vty
, " remote-as external");
6336 if_ras_printed
= TRUE
;
6342 /* remote-as and peer-group */
6343 /* peer is a member of a peer-group */
6344 if (peer_group_active(peer
)) {
6345 g_peer
= peer
->group
->conf
;
6347 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6348 if (peer
->as_type
== AS_SPECIFIED
) {
6349 vty_out(vty
, " neighbor %s remote-as %u\n",
6351 } else if (peer
->as_type
== AS_INTERNAL
) {
6353 " neighbor %s remote-as internal\n",
6355 } else if (peer
->as_type
== AS_EXTERNAL
) {
6357 " neighbor %s remote-as external\n",
6362 /* For swpX peers we displayed the peer-group
6363 * via 'neighbor swpX interface peer-group WORD' */
6365 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6369 /* peer is NOT a member of a peer-group */
6371 /* peer is a peer-group, declare the peer-group */
6372 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6373 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6376 if (!if_ras_printed
) {
6377 if (peer
->as_type
== AS_SPECIFIED
) {
6378 vty_out(vty
, " neighbor %s remote-as %u\n",
6380 } else if (peer
->as_type
== AS_INTERNAL
) {
6382 " neighbor %s remote-as internal\n",
6384 } else if (peer
->as_type
== AS_EXTERNAL
) {
6386 " neighbor %s remote-as external\n",
6393 if (peer
->change_local_as
) {
6394 if (!peer_group_active(peer
)
6395 || peer
->change_local_as
!= g_peer
->change_local_as
6396 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6397 != CHECK_FLAG(g_peer
->flags
,
6398 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6399 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6400 != CHECK_FLAG(g_peer
->flags
,
6401 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6402 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6403 peer
->change_local_as
,
6404 CHECK_FLAG(peer
->flags
,
6405 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6408 CHECK_FLAG(peer
->flags
,
6409 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6417 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6421 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6422 if (!peer_group_active(peer
)
6423 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6424 || peer
->tx_shutdown_message
) {
6425 if (peer
->tx_shutdown_message
)
6427 " neighbor %s shutdown message %s\n",
6428 addr
, peer
->tx_shutdown_message
);
6430 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6435 if (peer
->bfd_info
) {
6436 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6437 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6442 if (peer
->password
) {
6443 if (!peer_group_active(peer
) || !g_peer
->password
6444 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6445 vty_out(vty
, " neighbor %s password %s\n", addr
,
6451 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6452 if (!peer_group_active(peer
)) {
6453 vty_out(vty
, " neighbor %s solo\n", addr
);
6458 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6459 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6462 /* Local interface name */
6464 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6468 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6469 if (!peer_group_active(peer
)
6470 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6471 vty_out(vty
, " neighbor %s passive\n", addr
);
6476 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6477 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6478 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6479 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6484 /* ttl-security hops */
6485 if (peer
->gtsm_hops
!= 0) {
6486 if (!peer_group_active(peer
)
6487 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6488 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6489 addr
, peer
->gtsm_hops
);
6493 /* disable-connected-check */
6494 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6495 if (!peer_group_active(peer
)
6496 || !CHECK_FLAG(g_peer
->flags
,
6497 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6498 vty_out(vty
, " neighbor %s disable-connected-check\n",
6504 if (peer
->update_if
) {
6505 if (!peer_group_active(peer
) || !g_peer
->update_if
6506 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6507 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6511 if (peer
->update_source
) {
6512 if (!peer_group_active(peer
) || !g_peer
->update_source
6513 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6515 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6516 sockunion2str(peer
->update_source
, buf
,
6521 /* advertisement-interval */
6522 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6523 && ((!peer_group_active(peer
)
6524 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6525 || (peer_group_active(peer
)
6526 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6527 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6532 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6533 && ((!peer_group_active(peer
)
6534 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6535 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6536 || (peer_group_active(peer
)
6537 && (peer
->keepalive
!= g_peer
->keepalive
6538 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6539 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6540 peer
->keepalive
, peer
->holdtime
);
6543 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6544 && ((!peer_group_active(peer
)
6545 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6546 || (peer_group_active(peer
)
6547 && peer
->connect
!= g_peer
->connect
)))
6550 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6554 /* capability dynamic */
6555 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6556 if (!peer_group_active(peer
)
6557 || !CHECK_FLAG(g_peer
->flags
,
6558 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6559 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6563 /* capability extended-nexthop */
6564 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6565 if (!peer_group_active(peer
)
6566 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6568 " no neighbor %s capability extended-nexthop\n",
6573 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6574 if (!peer_group_active(peer
)
6575 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6577 " neighbor %s capability extended-nexthop\n",
6582 /* dont-capability-negotiation */
6583 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6584 if (!peer_group_active(peer
)
6585 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6586 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6591 /* override-capability */
6592 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6593 if (!peer_group_active(peer
)
6594 || !CHECK_FLAG(g_peer
->flags
,
6595 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6596 vty_out(vty
, " neighbor %s override-capability\n",
6601 /* strict-capability-match */
6602 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6603 if (!peer_group_active(peer
)
6604 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6605 vty_out(vty
, " neighbor %s strict-capability-match\n",
6611 /* BGP peer configuration display function. */
6612 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6613 struct peer
*peer
, afi_t afi
, safi_t safi
)
6615 struct peer
*g_peer
= NULL
;
6618 /* Skip dynamic neighbors. */
6619 if (peer_dynamic_neighbor(peer
))
6623 addr
= peer
->conf_if
;
6627 /************************************
6628 ****** Per AF to the neighbor ******
6629 ************************************/
6630 if (peer_group_active(peer
)) {
6631 g_peer
= peer
->group
->conf
;
6633 /* If the peer-group is active but peer is not, print a 'no
6635 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6636 vty_out(vty
, " no neighbor %s activate\n", addr
);
6639 /* If the peer-group is not active but peer is, print an
6641 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6642 vty_out(vty
, " neighbor %s activate\n", addr
);
6645 if (peer
->afc
[afi
][safi
]) {
6646 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6647 if (bgp_flag_check(bgp
,
6648 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6649 vty_out(vty
, " neighbor %s activate\n",
6653 vty_out(vty
, " neighbor %s activate\n", addr
);
6655 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6656 if (!bgp_flag_check(bgp
,
6657 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6659 " no neighbor %s activate\n",
6666 /* addpath TX knobs */
6667 if (peergroup_af_flag_check(peer
, afi
, safi
,
6668 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6669 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6672 if (peergroup_af_flag_check(peer
, afi
, safi
,
6673 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6674 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6678 /* ORF capability. */
6679 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6680 || peergroup_af_flag_check(peer
, afi
, safi
,
6681 PEER_FLAG_ORF_PREFIX_RM
)) {
6682 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6684 if (peergroup_af_flag_check(peer
, afi
, safi
,
6685 PEER_FLAG_ORF_PREFIX_SM
)
6686 && peergroup_af_flag_check(peer
, afi
, safi
,
6687 PEER_FLAG_ORF_PREFIX_RM
))
6688 vty_out(vty
, " both");
6689 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6690 PEER_FLAG_ORF_PREFIX_SM
))
6691 vty_out(vty
, " send");
6693 vty_out(vty
, " receive");
6697 /* Route reflector client. */
6698 if (peergroup_af_flag_check(peer
, afi
, safi
,
6699 PEER_FLAG_REFLECTOR_CLIENT
)) {
6700 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6703 /* next-hop-self force */
6704 if (peergroup_af_flag_check(peer
, afi
, safi
,
6705 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6706 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6710 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6711 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6714 /* remove-private-AS */
6715 if (peergroup_af_flag_check(peer
, afi
, safi
,
6716 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6717 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6721 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6722 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6723 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6727 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6728 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6729 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6732 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6733 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6734 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6738 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6739 vty_out(vty
, " neighbor %s as-override\n", addr
);
6742 /* send-community print. */
6743 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6744 if (peergroup_af_flag_check(peer
, afi
, safi
,
6745 PEER_FLAG_SEND_COMMUNITY
)
6746 && peergroup_af_flag_check(peer
, afi
, safi
,
6747 PEER_FLAG_SEND_EXT_COMMUNITY
)
6748 && peergroup_af_flag_check(
6750 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6751 vty_out(vty
, " neighbor %s send-community all\n",
6753 } else if (peergroup_af_flag_check(
6755 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6756 vty_out(vty
, " neighbor %s send-community large\n",
6758 } else if (peergroup_af_flag_check(
6760 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6761 vty_out(vty
, " neighbor %s send-community extended\n",
6763 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6764 PEER_FLAG_SEND_COMMUNITY
)) {
6765 vty_out(vty
, " neighbor %s send-community\n", addr
);
6768 if (!peer_af_flag_check(peer
, afi
, safi
,
6769 PEER_FLAG_SEND_COMMUNITY
)
6770 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6771 PEER_FLAG_SEND_COMMUNITY
))
6772 && !peer_af_flag_check(peer
, afi
, safi
,
6773 PEER_FLAG_SEND_EXT_COMMUNITY
)
6775 || peer_af_flag_check(g_peer
, afi
, safi
,
6776 PEER_FLAG_SEND_EXT_COMMUNITY
))
6777 && !peer_af_flag_check(peer
, afi
, safi
,
6778 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6779 && (!g_peer
|| peer_af_flag_check(
6781 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6782 vty_out(vty
, " no neighbor %s send-community all\n",
6785 if (!peer_af_flag_check(peer
, afi
, safi
,
6786 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6788 || peer_af_flag_check(
6790 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6792 " no neighbor %s send-community large\n",
6796 if (!peer_af_flag_check(peer
, afi
, safi
,
6797 PEER_FLAG_SEND_EXT_COMMUNITY
)
6799 || peer_af_flag_check(
6801 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6803 " no neighbor %s send-community extended\n",
6807 if (!peer_af_flag_check(peer
, afi
, safi
,
6808 PEER_FLAG_SEND_COMMUNITY
)
6809 && (!g_peer
|| peer_af_flag_check(
6811 PEER_FLAG_SEND_COMMUNITY
))) {
6813 " no neighbor %s send-community\n",
6819 /* Default information */
6820 if (peergroup_af_flag_check(peer
, afi
, safi
,
6821 PEER_FLAG_DEFAULT_ORIGINATE
)
6823 && ((peer
->default_rmap
[afi
][safi
].name
6824 && !g_peer
->default_rmap
[afi
][safi
].name
)
6825 || (!peer
->default_rmap
[afi
][safi
].name
6826 && g_peer
->default_rmap
[afi
][safi
].name
)
6827 || (peer
->default_rmap
[afi
][safi
].name
6828 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
6829 g_peer
->default_rmap
[afi
][safi
].name
))))) {
6830 vty_out(vty
, " neighbor %s default-originate", addr
);
6831 if (peer
->default_rmap
[afi
][safi
].name
)
6832 vty_out(vty
, " route-map %s",
6833 peer
->default_rmap
[afi
][safi
].name
);
6837 /* Soft reconfiguration inbound. */
6838 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
6839 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
6843 /* maximum-prefix. */
6844 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
6845 if (!peer_group_active(peer
)
6846 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
6847 || g_peer
->pmax_threshold
[afi
][safi
]
6848 != peer
->pmax_threshold
[afi
][safi
]
6849 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
6850 PEER_FLAG_MAX_PREFIX_WARNING
)
6851 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6852 PEER_FLAG_MAX_PREFIX_WARNING
)) {
6853 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
6854 peer
->pmax
[afi
][safi
]);
6855 if (peer
->pmax_threshold
[afi
][safi
]
6856 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
6858 peer
->pmax_threshold
[afi
][safi
]);
6859 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6860 PEER_FLAG_MAX_PREFIX_WARNING
))
6861 vty_out(vty
, " warning-only");
6862 if (peer
->pmax_restart
[afi
][safi
])
6863 vty_out(vty
, " restart %u",
6864 peer
->pmax_restart
[afi
][safi
]);
6868 /* Route server client. */
6869 if (peergroup_af_flag_check(peer
, afi
, safi
,
6870 PEER_FLAG_RSERVER_CLIENT
)) {
6871 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
6874 /* Nexthop-local unchanged. */
6875 if (peergroup_af_flag_check(peer
, afi
, safi
,
6876 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
6877 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
6880 /* allowas-in <1-10> */
6881 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
6882 if (!peer_group_active(peer
)
6883 || !peer_af_flag_check(g_peer
, afi
, safi
,
6884 PEER_FLAG_ALLOWAS_IN
)
6885 || peer
->allowas_in
[afi
][safi
]
6886 != g_peer
->allowas_in
[afi
][safi
]) {
6887 if (peer
->allowas_in
[afi
][safi
] == 3) {
6888 vty_out(vty
, " neighbor %s allowas-in\n",
6891 vty_out(vty
, " neighbor %s allowas-in %d\n",
6892 addr
, peer
->allowas_in
[afi
][safi
]);
6897 /* allowas-in origin */
6898 else if (peer_af_flag_check(peer
, afi
, safi
,
6899 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6900 if (!peer_group_active(peer
)
6901 || !peer_af_flag_check(g_peer
, afi
, safi
,
6902 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
6903 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
6908 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
6909 if (!peer_group_active(peer
)
6910 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
6911 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
6912 if (peer
->weight
[afi
][safi
]) {
6913 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
6914 peer
->weight
[afi
][safi
]);
6919 bgp_config_write_filter(vty
, peer
, afi
, safi
);
6921 /* atribute-unchanged. */
6922 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
) ||
6923 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6924 peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
6926 if (!peer_group_active(peer
) ||
6927 peergroup_af_flag_check(peer
, afi
, safi
,
6928 PEER_FLAG_AS_PATH_UNCHANGED
) ||
6929 peergroup_af_flag_check(peer
, afi
, safi
,
6930 PEER_FLAG_NEXTHOP_UNCHANGED
) ||
6931 peergroup_af_flag_check(peer
, afi
, safi
,
6932 PEER_FLAG_MED_UNCHANGED
)) {
6935 " neighbor %s attribute-unchanged%s%s%s\n",
6937 peer_af_flag_check(peer
, afi
, safi
,
6938 PEER_FLAG_AS_PATH_UNCHANGED
)
6941 peer_af_flag_check(peer
, afi
, safi
,
6942 PEER_FLAG_NEXTHOP_UNCHANGED
)
6945 peer_af_flag_check(peer
, afi
, safi
,
6946 PEER_FLAG_MED_UNCHANGED
)
6953 /* Address family based peer configuration display. */
6954 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
6958 struct peer_group
*group
;
6959 struct listnode
*node
, *nnode
;
6962 vty_frame(vty
, " !\n address-family ");
6963 if (afi
== AFI_IP
) {
6964 if (safi
== SAFI_UNICAST
)
6965 vty_frame(vty
, "ipv4 unicast");
6966 else if (safi
== SAFI_LABELED_UNICAST
)
6967 vty_frame(vty
, "ipv4 labeled-unicast");
6968 else if (safi
== SAFI_MULTICAST
)
6969 vty_frame(vty
, "ipv4 multicast");
6970 else if (safi
== SAFI_MPLS_VPN
)
6971 vty_frame(vty
, "ipv4 vpn");
6972 else if (safi
== SAFI_ENCAP
)
6973 vty_frame(vty
, "ipv4 encap");
6974 } else if (afi
== AFI_IP6
) {
6975 if (safi
== SAFI_UNICAST
)
6976 vty_frame(vty
, "ipv6 unicast");
6977 else if (safi
== SAFI_LABELED_UNICAST
)
6978 vty_frame(vty
, "ipv6 labeled-unicast");
6979 else if (safi
== SAFI_MULTICAST
)
6980 vty_frame(vty
, "ipv6 multicast");
6981 else if (safi
== SAFI_MPLS_VPN
)
6982 vty_frame(vty
, "ipv6 vpn");
6983 else if (safi
== SAFI_ENCAP
)
6984 vty_frame(vty
, "ipv6 encap");
6985 } else if (afi
== AFI_L2VPN
) {
6986 if (safi
== SAFI_EVPN
)
6987 vty_frame(vty
, "l2vpn evpn");
6989 vty_frame(vty
, "\n");
6991 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
6993 bgp_config_write_network(vty
, bgp
, afi
, safi
);
6995 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
6997 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
6998 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7000 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7001 /* Skip dynamic neighbors. */
7002 if (peer_dynamic_neighbor(peer
))
7005 /* Do not display doppelganger peers */
7006 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7007 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7010 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7011 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7013 if (safi
== SAFI_EVPN
)
7014 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7016 vty_endframe(vty
, " exit-address-family\n");
7019 int bgp_config_write(struct vty
*vty
)
7023 struct peer_group
*group
;
7025 struct listnode
*node
, *nnode
;
7026 struct listnode
*mnode
, *mnnode
;
7028 /* BGP Multiple instance. */
7029 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7030 vty_out(vty
, "no bgp multiple-instance\n");
7034 /* BGP Config type. */
7035 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7036 vty_out(vty
, "bgp config-type cisco\n");
7040 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7041 vty_out(vty
, "bgp route-map delay-timer %u\n",
7042 bm
->rmap_update_timer
);
7045 vty_out(vty
, "!\n");
7047 /* BGP configuration. */
7048 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7049 /* Router bgp ASN */
7050 vty_out(vty
, "router bgp %u", bgp
->as
);
7052 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7054 vty_out(vty
, " %s %s",
7056 == BGP_INSTANCE_TYPE_VIEW
)
7063 /* No Synchronization */
7064 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7065 vty_out(vty
, " no synchronization\n");
7067 /* BGP fast-external-failover. */
7068 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7069 vty_out(vty
, " no bgp fast-external-failover\n");
7071 /* BGP router ID. */
7072 if (bgp
->router_id_static
.s_addr
!= 0)
7073 vty_out(vty
, " bgp router-id %s\n",
7074 inet_ntoa(bgp
->router_id_static
));
7076 /* BGP log-neighbor-changes. */
7077 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7078 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7079 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7081 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7085 /* BGP configuration. */
7086 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7087 vty_out(vty
, " bgp always-compare-med\n");
7089 /* BGP default ipv4-unicast. */
7090 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7091 vty_out(vty
, " no bgp default ipv4-unicast\n");
7093 /* BGP default local-preference. */
7094 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7095 vty_out(vty
, " bgp default local-preference %u\n",
7096 bgp
->default_local_pref
);
7098 /* BGP default show-hostname */
7099 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7100 != DFLT_BGP_SHOW_HOSTNAME
)
7101 vty_out(vty
, " %sbgp default show-hostname\n",
7102 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7106 /* BGP default subgroup-pkt-queue-max. */
7107 if (bgp
->default_subgroup_pkt_queue_max
7108 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7109 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7110 bgp
->default_subgroup_pkt_queue_max
);
7112 /* BGP client-to-client reflection. */
7113 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7114 vty_out(vty
, " no bgp client-to-client reflection\n");
7116 /* BGP cluster ID. */
7117 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7118 vty_out(vty
, " bgp cluster-id %s\n",
7119 inet_ntoa(bgp
->cluster_id
));
7121 /* Disable ebgp connected nexthop check */
7122 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7124 " bgp disable-ebgp-connected-route-check\n");
7126 /* Confederation identifier*/
7127 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7128 vty_out(vty
, " bgp confederation identifier %i\n",
7131 /* Confederation peer */
7132 if (bgp
->confed_peers_cnt
> 0) {
7135 vty_out(vty
, " bgp confederation peers");
7137 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7138 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7143 /* BGP enforce-first-as. */
7144 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7145 vty_out(vty
, " bgp enforce-first-as\n");
7147 /* BGP deterministic-med. */
7148 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7149 != DFLT_BGP_DETERMINISTIC_MED
)
7150 vty_out(vty
, " %sbgp deterministic-med\n",
7151 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7155 /* BGP update-delay. */
7156 bgp_config_write_update_delay(vty
, bgp
);
7158 if (bgp
->v_maxmed_onstartup
7159 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7160 vty_out(vty
, " bgp max-med on-startup %u",
7161 bgp
->v_maxmed_onstartup
);
7162 if (bgp
->maxmed_onstartup_value
7163 != BGP_MAXMED_VALUE_DEFAULT
)
7165 bgp
->maxmed_onstartup_value
);
7168 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7169 vty_out(vty
, " bgp max-med administrative");
7170 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7171 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7176 bgp_config_write_wpkt_quanta(vty
, bgp
);
7179 bgp_config_write_coalesce_time(vty
, bgp
);
7181 /* BGP graceful-restart. */
7182 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7184 " bgp graceful-restart stalepath-time %u\n",
7185 bgp
->stalepath_time
);
7186 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7187 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7189 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7190 vty_out(vty
, " bgp graceful-restart\n");
7192 /* BGP graceful-shutdown */
7193 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7194 vty_out(vty
, " bgp graceful-shutdown\n");
7196 /* BGP graceful-restart Preserve State F bit. */
7197 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7199 " bgp graceful-restart preserve-fw-state\n");
7201 /* BGP bestpath method. */
7202 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7203 vty_out(vty
, " bgp bestpath as-path ignore\n");
7204 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7205 vty_out(vty
, " bgp bestpath as-path confed\n");
7207 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7208 if (bgp_flag_check(bgp
,
7209 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7211 " bgp bestpath as-path multipath-relax as-set\n");
7214 " bgp bestpath as-path multipath-relax\n");
7218 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7220 " bgp route-reflector allow-outbound-policy\n");
7222 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7223 vty_out(vty
, " bgp bestpath compare-routerid\n");
7224 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7225 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7226 vty_out(vty
, " bgp bestpath med");
7227 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7228 vty_out(vty
, " confed");
7229 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7230 vty_out(vty
, " missing-as-worst");
7234 /* BGP network import check. */
7235 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7236 != DFLT_BGP_IMPORT_CHECK
)
7237 vty_out(vty
, " %sbgp network import-check\n",
7238 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7242 /* BGP flag dampening. */
7243 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7244 BGP_CONFIG_DAMPENING
))
7245 bgp_config_write_damp(vty
);
7247 /* BGP timers configuration. */
7248 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7249 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7250 vty_out(vty
, " timers bgp %u %u\n",
7251 bgp
->default_keepalive
, bgp
->default_holdtime
);
7254 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7255 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7258 /* Normal neighbor configuration. */
7259 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7260 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7261 bgp_config_write_peer_global(vty
, bgp
, peer
);
7264 /* listen range and limit for dynamic BGP neighbors */
7265 bgp_config_write_listen(vty
, bgp
);
7267 /* No auto-summary */
7268 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7269 vty_out(vty
, " no auto-summary\n");
7271 /* IPv4 unicast configuration. */
7272 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7274 /* IPv4 multicast configuration. */
7275 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7277 /* IPv4 labeled-unicast configuration. */
7278 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7280 /* IPv4 VPN configuration. */
7281 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7283 /* ENCAPv4 configuration. */
7284 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7286 /* IPv6 unicast configuration. */
7287 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7289 /* IPv6 multicast configuration. */
7290 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7292 /* IPv6 labeled-unicast configuration. */
7293 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7294 SAFI_LABELED_UNICAST
);
7296 /* IPv6 VPN configuration. */
7297 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7299 /* ENCAPv6 configuration. */
7300 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7302 /* EVPN configuration. */
7303 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7306 bgp_rfapi_cfg_write(vty
, bgp
);
7309 vty_out(vty
, "!\n");
7314 void bgp_master_init(struct thread_master
*master
)
7318 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7321 bm
->bgp
= list_new();
7322 bm
->listen_sockets
= list_new();
7323 bm
->port
= BGP_PORT_DEFAULT
;
7324 bm
->master
= master
;
7325 bm
->start_time
= bgp_clock();
7326 bm
->t_rmap_update
= NULL
;
7327 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7329 bgp_process_queue_init();
7331 /* Enable multiple instances by default. */
7332 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7334 QOBJ_REG(bm
, bgp_master
);
7338 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7339 * instance delete (non-default only) or BGP exit.
7341 static void bgp_if_finish(struct bgp
*bgp
)
7343 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7344 struct interface
*ifp
;
7346 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7349 FOR_ALL_INTERFACES (vrf
, ifp
) {
7350 struct listnode
*c_node
, *c_nnode
;
7351 struct connected
*c
;
7353 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7354 bgp_connected_delete(bgp
, c
);
7358 extern void bgp_snmp_init(void);
7360 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7362 struct vrf
*vrf
= NULL
;
7363 struct listnode
*next
;
7366 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7367 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7368 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7371 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7372 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7375 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7379 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7380 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7381 {.completions
= NULL
},
7387 /* allocates some vital data structures used by peer commands in
7391 bgp_zebra_init(bm
->master
);
7394 vnc_zebra_init(bm
->master
);
7397 /* BGP VTY commands installation. */
7405 bgp_route_map_init();
7406 bgp_scan_vty_init();
7411 bgp_ethernetvpn_init();
7413 /* Access list initialize. */
7415 access_list_add_hook(peer_distribute_update
);
7416 access_list_delete_hook(peer_distribute_update
);
7418 /* Filter list initialize. */
7420 as_list_add_hook(peer_aslist_add
);
7421 as_list_delete_hook(peer_aslist_del
);
7423 /* Prefix list initialize.*/
7425 prefix_list_add_hook(peer_prefix_list_update
);
7426 prefix_list_delete_hook(peer_prefix_list_update
);
7428 /* Community list initialize. */
7429 bgp_clist
= community_list_init();
7434 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7437 void bgp_terminate(void)
7441 struct listnode
*node
, *nnode
;
7442 struct listnode
*mnode
, *mnnode
;
7446 /* Close the listener sockets first as this prevents peers from
7448 * to reconnect on receiving the peer unconfig message. In the presence
7449 * of a large number of peers this will ensure that no peer is left with
7450 * a dangling connection
7452 /* reverse bgp_master_init */
7454 if (bm
->listen_sockets
)
7455 list_delete_and_null(&bm
->listen_sockets
);
7457 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7458 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7459 if (peer
->status
== Established
7460 || peer
->status
== OpenSent
7461 || peer
->status
== OpenConfirm
)
7462 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7463 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7465 if (bm
->process_main_queue
) {
7466 work_queue_free(bm
->process_main_queue
);
7467 bm
->process_main_queue
= NULL
;
7470 if (bm
->t_rmap_update
)
7471 BGP_TIMER_OFF(bm
->t_rmap_update
);