1 /* BGP-4, BGP-4+ daemon program
2 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "sockunion.h"
38 #include "workqueue.h"
46 #include "frr_pthread.h"
48 #include "bgpd/bgpd.h"
49 #include "bgpd/bgp_table.h"
50 #include "bgpd/bgp_aspath.h"
51 #include "bgpd/bgp_route.h"
52 #include "bgpd/bgp_dump.h"
53 #include "bgpd/bgp_debug.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_attr.h"
56 #include "bgpd/bgp_regex.h"
57 #include "bgpd/bgp_clist.h"
58 #include "bgpd/bgp_fsm.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_zebra.h"
61 #include "bgpd/bgp_open.h"
62 #include "bgpd/bgp_filter.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_mplsvpn.h"
67 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
68 #include "bgpd/rfapi/rfapi_backend.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_advertise.h"
72 #include "bgpd/bgp_network.h"
73 #include "bgpd/bgp_vty.h"
74 #include "bgpd/bgp_mpath.h"
75 #include "bgpd/bgp_nht.h"
76 #include "bgpd/bgp_updgrp.h"
77 #include "bgpd/bgp_bfd.h"
78 #include "bgpd/bgp_memory.h"
79 #include "bgpd/bgp_evpn_vty.h"
80 #include "bgpd/bgp_keepalives.h"
81 #include "bgpd/bgp_io.h"
82 #include "bgpd/bgp_ecommunity.h"
83 #include "bgpd/bgp_flowspec.h"
86 DEFINE_MTYPE_STATIC(BGPD
, PEER_TX_SHUTDOWN_MSG
, "Peer shutdown message (TX)");
87 DEFINE_QOBJ_TYPE(bgp_master
)
89 DEFINE_QOBJ_TYPE(peer
)
91 /* BGP process wide configuration. */
92 static struct bgp_master bgp_master
;
94 /* BGP process wide configuration pointer to export. */
95 struct bgp_master
*bm
;
97 /* BGP community-list. */
98 struct community_list_handler
*bgp_clist
;
100 unsigned int multipath_num
= MULTIPATH_NUM
;
102 static void bgp_if_finish(struct bgp
*bgp
);
104 extern struct zclient
*zclient
;
106 /* handle main socket creation or deletion */
107 static int bgp_check_main_socket(bool create
, struct bgp
*bgp
)
109 static int bgp_server_main_created
;
110 struct listnode
*bgpnode
, *nbgpnode
;
111 struct bgp
*bgp_temp
;
113 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
&&
114 vrf_is_mapped_on_netns(bgp
->vrf_id
))
116 if (create
== true) {
117 if (bgp_server_main_created
)
119 if (bgp_socket(bgp
, bm
->port
, bm
->address
) < 0)
120 return BGP_ERR_INVALID_VALUE
;
121 bgp_server_main_created
= 1;
124 if (!bgp_server_main_created
)
126 /* only delete socket on some cases */
127 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp_temp
)) {
128 /* do not count with current bgp */
131 /* if other instance non VRF, do not delete socket */
132 if (bgp_temp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
134 /* vrf lite, do not delete socket */
135 if (!vrf_is_mapped_on_netns(bgp_temp
->vrf_id
))
139 bgp_server_main_created
= 0;
143 void bgp_session_reset(struct peer
*peer
)
145 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
146 && !(CHECK_FLAG(peer
->doppelganger
->flags
, PEER_FLAG_CONFIG_NODE
)))
147 peer_delete(peer
->doppelganger
);
149 BGP_EVENT_ADD(peer
, BGP_Stop
);
153 * During session reset, we may delete the doppelganger peer, which would
154 * be the next node to the current node. If the session reset was invoked
155 * during walk of peer list, we would end up accessing the freed next
156 * node. This function moves the next node along.
158 static void bgp_session_reset_safe(struct peer
*peer
, struct listnode
**nnode
)
163 n
= (nnode
) ? *nnode
: NULL
;
164 npeer
= (n
) ? listgetdata(n
) : NULL
;
166 if (peer
->doppelganger
&& (peer
->doppelganger
->status
!= Deleted
)
167 && !(CHECK_FLAG(peer
->doppelganger
->flags
,
168 PEER_FLAG_CONFIG_NODE
))) {
169 if (peer
->doppelganger
== npeer
)
170 /* nnode and *nnode are confirmed to be non-NULL here */
171 *nnode
= (*nnode
)->next
;
172 peer_delete(peer
->doppelganger
);
175 BGP_EVENT_ADD(peer
, BGP_Stop
);
178 /* BGP global flag manipulation. */
179 int bgp_option_set(int flag
)
183 case BGP_OPT_MULTIPLE_INSTANCE
:
184 case BGP_OPT_CONFIG_CISCO
:
185 case BGP_OPT_NO_LISTEN
:
186 SET_FLAG(bm
->options
, flag
);
189 return BGP_ERR_INVALID_FLAG
;
194 int bgp_option_unset(int flag
)
197 case BGP_OPT_MULTIPLE_INSTANCE
:
198 if (listcount(bm
->bgp
) > 1)
199 return BGP_ERR_MULTIPLE_INSTANCE_USED
;
202 case BGP_OPT_CONFIG_CISCO
:
203 UNSET_FLAG(bm
->options
, flag
);
206 return BGP_ERR_INVALID_FLAG
;
211 int bgp_option_check(int flag
)
213 return CHECK_FLAG(bm
->options
, flag
);
216 /* BGP flag manipulation. */
217 int bgp_flag_set(struct bgp
*bgp
, int flag
)
219 SET_FLAG(bgp
->flags
, flag
);
223 int bgp_flag_unset(struct bgp
*bgp
, int flag
)
225 UNSET_FLAG(bgp
->flags
, flag
);
229 int bgp_flag_check(struct bgp
*bgp
, int flag
)
231 return CHECK_FLAG(bgp
->flags
, flag
);
234 /* Internal function to set BGP structure configureation flag. */
235 static void bgp_config_set(struct bgp
*bgp
, int config
)
237 SET_FLAG(bgp
->config
, config
);
240 static void bgp_config_unset(struct bgp
*bgp
, int config
)
242 UNSET_FLAG(bgp
->config
, config
);
245 static int bgp_config_check(struct bgp
*bgp
, int config
)
247 return CHECK_FLAG(bgp
->config
, config
);
250 /* Set BGP router identifier. */
251 static int bgp_router_id_set(struct bgp
*bgp
, const struct in_addr
*id
)
254 struct listnode
*node
, *nnode
;
256 if (IPV4_ADDR_SAME(&bgp
->router_id
, id
))
259 /* EVPN uses router id in RD, withdraw them */
260 if (is_evpn_enabled())
261 bgp_evpn_handle_router_id_update(bgp
, TRUE
);
263 IPV4_ADDR_COPY(&bgp
->router_id
, id
);
265 /* Set all peer's local identifier with this value. */
266 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
267 IPV4_ADDR_COPY(&peer
->local_id
, id
);
269 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
270 peer
->last_reset
= PEER_DOWN_RID_CHANGE
;
271 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
272 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
276 /* EVPN uses router id in RD, update them */
277 if (is_evpn_enabled())
278 bgp_evpn_handle_router_id_update(bgp
, FALSE
);
283 void bgp_router_id_zebra_bump(vrf_id_t vrf_id
, const struct prefix
*router_id
)
285 struct listnode
*node
, *nnode
;
288 if (vrf_id
== VRF_DEFAULT
) {
289 /* Router-id change for default VRF has to also update all
291 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
292 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
295 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
296 if (!bgp
->router_id_static
.s_addr
)
297 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
300 bgp
= bgp_lookup_by_vrf_id(vrf_id
);
302 bgp
->router_id_zebra
= router_id
->u
.prefix4
;
304 if (!bgp
->router_id_static
.s_addr
)
305 bgp_router_id_set(bgp
, &router_id
->u
.prefix4
);
310 int bgp_router_id_static_set(struct bgp
*bgp
, struct in_addr id
)
312 bgp
->router_id_static
= id
;
313 bgp_router_id_set(bgp
, id
.s_addr
? &id
: &bgp
->router_id_zebra
);
317 /* BGP's cluster-id control. */
318 int bgp_cluster_id_set(struct bgp
*bgp
, struct in_addr
*cluster_id
)
321 struct listnode
*node
, *nnode
;
323 if (bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
)
324 && IPV4_ADDR_SAME(&bgp
->cluster_id
, cluster_id
))
327 IPV4_ADDR_COPY(&bgp
->cluster_id
, cluster_id
);
328 bgp_config_set(bgp
, BGP_CONFIG_CLUSTER_ID
);
330 /* Clear all IBGP peer. */
331 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
332 if (peer
->sort
!= BGP_PEER_IBGP
)
335 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
336 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
337 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
338 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
344 int bgp_cluster_id_unset(struct bgp
*bgp
)
347 struct listnode
*node
, *nnode
;
349 if (!bgp_config_check(bgp
, BGP_CONFIG_CLUSTER_ID
))
352 bgp
->cluster_id
.s_addr
= 0;
353 bgp_config_unset(bgp
, BGP_CONFIG_CLUSTER_ID
);
355 /* Clear all IBGP peer. */
356 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
357 if (peer
->sort
!= BGP_PEER_IBGP
)
360 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
361 peer
->last_reset
= PEER_DOWN_CLID_CHANGE
;
362 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
363 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
369 /* time_t value that is monotonicly increasing
370 * and uneffected by adjustments to system clock
372 time_t bgp_clock(void)
380 /* BGP timer configuration. */
381 int bgp_timers_set(struct bgp
*bgp
, uint32_t keepalive
, uint32_t holdtime
)
383 bgp
->default_keepalive
=
384 (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
385 bgp
->default_holdtime
= holdtime
;
390 int bgp_timers_unset(struct bgp
*bgp
)
392 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
393 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
398 /* BGP confederation configuration. */
399 int bgp_confederation_id_set(struct bgp
*bgp
, as_t as
)
402 struct listnode
*node
, *nnode
;
406 return BGP_ERR_INVALID_AS
;
408 /* Remember - were we doing confederation before? */
409 already_confed
= bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
);
411 bgp_config_set(bgp
, BGP_CONFIG_CONFEDERATION
);
413 /* If we were doing confederation already, this is just an external
414 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
415 were not doing confederation before, reset all EBGP sessions. */
416 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
417 /* We're looking for peers who's AS is not local or part of our
419 if (already_confed
) {
420 if (peer_sort(peer
) == BGP_PEER_EBGP
) {
422 if (BGP_IS_VALID_STATE_FOR_NOTIF(
425 PEER_DOWN_CONFED_ID_CHANGE
;
427 peer
, BGP_NOTIFY_CEASE
,
428 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
430 bgp_session_reset_safe(peer
, &nnode
);
433 /* Not doign confederation before, so reset every
436 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
437 /* Reset the local_as to be our EBGP one */
438 if (peer_sort(peer
) == BGP_PEER_EBGP
)
440 if (BGP_IS_VALID_STATE_FOR_NOTIF(
443 PEER_DOWN_CONFED_ID_CHANGE
;
445 peer
, BGP_NOTIFY_CEASE
,
446 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
448 bgp_session_reset_safe(peer
, &nnode
);
455 int bgp_confederation_id_unset(struct bgp
*bgp
)
458 struct listnode
*node
, *nnode
;
461 bgp_config_unset(bgp
, BGP_CONFIG_CONFEDERATION
);
463 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
464 /* We're looking for peers who's AS is not local */
465 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
466 peer
->local_as
= bgp
->as
;
467 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
468 peer
->last_reset
= PEER_DOWN_CONFED_ID_CHANGE
;
469 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
470 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
474 bgp_session_reset_safe(peer
, &nnode
);
480 /* Is an AS part of the confed or not? */
481 int bgp_confederation_peers_check(struct bgp
*bgp
, as_t as
)
488 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
489 if (bgp
->confed_peers
[i
] == as
)
495 /* Add an AS to the confederation set. */
496 int bgp_confederation_peers_add(struct bgp
*bgp
, as_t as
)
499 struct listnode
*node
, *nnode
;
502 return BGP_ERR_INVALID_BGP
;
505 return BGP_ERR_INVALID_AS
;
507 if (bgp_confederation_peers_check(bgp
, as
))
510 if (bgp
->confed_peers
)
512 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
513 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
516 XMALLOC(MTYPE_BGP_CONFED_LIST
,
517 (bgp
->confed_peers_cnt
+ 1) * sizeof(as_t
));
519 bgp
->confed_peers
[bgp
->confed_peers_cnt
] = as
;
520 bgp
->confed_peers_cnt
++;
522 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
523 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
524 if (peer
->as
== as
) {
525 peer
->local_as
= bgp
->as
;
526 if (BGP_IS_VALID_STATE_FOR_NOTIF(
529 PEER_DOWN_CONFED_PEER_CHANGE
;
531 peer
, BGP_NOTIFY_CEASE
,
532 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
534 bgp_session_reset_safe(peer
, &nnode
);
541 /* Delete an AS from the confederation set. */
542 int bgp_confederation_peers_remove(struct bgp
*bgp
, as_t as
)
547 struct listnode
*node
, *nnode
;
552 if (!bgp_confederation_peers_check(bgp
, as
))
555 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
556 if (bgp
->confed_peers
[i
] == as
)
557 for (j
= i
+ 1; j
< bgp
->confed_peers_cnt
; j
++)
558 bgp
->confed_peers
[j
- 1] = bgp
->confed_peers
[j
];
560 bgp
->confed_peers_cnt
--;
562 if (bgp
->confed_peers_cnt
== 0) {
563 if (bgp
->confed_peers
)
564 XFREE(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
);
565 bgp
->confed_peers
= NULL
;
568 XREALLOC(MTYPE_BGP_CONFED_LIST
, bgp
->confed_peers
,
569 bgp
->confed_peers_cnt
* sizeof(as_t
));
571 /* Now reset any peer who's remote AS has just been removed from the
573 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)) {
574 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
575 if (peer
->as
== as
) {
576 peer
->local_as
= bgp
->confed_id
;
577 if (BGP_IS_VALID_STATE_FOR_NOTIF(
580 PEER_DOWN_CONFED_PEER_CHANGE
;
582 peer
, BGP_NOTIFY_CEASE
,
583 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
585 bgp_session_reset_safe(peer
, &nnode
);
593 /* Local preference configuration. */
594 int bgp_default_local_preference_set(struct bgp
*bgp
, uint32_t local_pref
)
599 bgp
->default_local_pref
= local_pref
;
604 int bgp_default_local_preference_unset(struct bgp
*bgp
)
609 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
614 /* Local preference configuration. */
615 int bgp_default_subgroup_pkt_queue_max_set(struct bgp
*bgp
, uint32_t queue_size
)
620 bgp
->default_subgroup_pkt_queue_max
= queue_size
;
625 int bgp_default_subgroup_pkt_queue_max_unset(struct bgp
*bgp
)
629 bgp
->default_subgroup_pkt_queue_max
=
630 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
635 /* Listen limit configuration. */
636 int bgp_listen_limit_set(struct bgp
*bgp
, int listen_limit
)
641 bgp
->dynamic_neighbors_limit
= listen_limit
;
646 int bgp_listen_limit_unset(struct bgp
*bgp
)
651 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
656 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi
, iana_safi_t pkt_safi
,
657 afi_t
*afi
, safi_t
*safi
)
659 /* Map from IANA values to internal values, return error if
660 * values are unrecognized.
662 *afi
= afi_iana2int(pkt_afi
);
663 *safi
= safi_iana2int(pkt_safi
);
664 if (*afi
== AFI_MAX
|| *safi
== SAFI_MAX
)
670 int bgp_map_afi_safi_int2iana(afi_t afi
, safi_t safi
, iana_afi_t
*pkt_afi
,
671 iana_safi_t
*pkt_safi
)
673 /* Map from internal values to IANA values, return error if
674 * internal values are bad (unexpected).
676 if (afi
== AFI_MAX
|| safi
== SAFI_MAX
)
678 *pkt_afi
= afi_int2iana(afi
);
679 *pkt_safi
= safi_int2iana(safi
);
683 struct peer_af
*peer_af_create(struct peer
*peer
, afi_t afi
, safi_t safi
)
691 afid
= afindex(afi
, safi
);
692 if (afid
>= BGP_AF_MAX
)
695 assert(peer
->peer_af_array
[afid
] == NULL
);
697 /* Allocate new peer af */
698 af
= XCALLOC(MTYPE_BGP_PEER_AF
, sizeof(struct peer_af
));
701 zlog_err("Could not create af structure for peer %s",
706 peer
->peer_af_array
[afid
] = af
;
715 struct peer_af
*peer_af_find(struct peer
*peer
, afi_t afi
, safi_t safi
)
722 afid
= afindex(afi
, safi
);
723 if (afid
>= BGP_AF_MAX
)
726 return peer
->peer_af_array
[afid
];
729 int peer_af_delete(struct peer
*peer
, afi_t afi
, safi_t safi
)
737 afid
= afindex(afi
, safi
);
738 if (afid
>= BGP_AF_MAX
)
741 af
= peer
->peer_af_array
[afid
];
745 bgp_stop_announce_route_timer(af
);
747 if (PAF_SUBGRP(af
)) {
748 if (BGP_DEBUG(update_groups
, UPDATE_GROUPS
))
749 zlog_debug("u%" PRIu64
":s%" PRIu64
" remove peer %s",
750 af
->subgroup
->update_group
->id
,
751 af
->subgroup
->id
, peer
->host
);
754 update_subgroup_remove_peer(af
->subgroup
, af
);
756 peer
->peer_af_array
[afid
] = NULL
;
757 XFREE(MTYPE_BGP_PEER_AF
, af
);
761 /* Peer comparison function for sorting. */
762 int peer_cmp(struct peer
*p1
, struct peer
*p2
)
764 if (p1
->group
&& !p2
->group
)
767 if (!p1
->group
&& p2
->group
)
770 if (p1
->group
== p2
->group
) {
771 if (p1
->conf_if
&& !p2
->conf_if
)
774 if (!p1
->conf_if
&& p2
->conf_if
)
777 if (p1
->conf_if
&& p2
->conf_if
)
778 return if_cmp_name_func(p1
->conf_if
, p2
->conf_if
);
780 return strcmp(p1
->group
->name
, p2
->group
->name
);
782 return sockunion_cmp(&p1
->su
, &p2
->su
);
785 static unsigned int peer_hash_key_make(void *p
)
787 struct peer
*peer
= p
;
788 return sockunion_hash(&peer
->su
);
791 static int peer_hash_same(const void *p1
, const void *p2
)
793 const struct peer
*peer1
= p1
;
794 const struct peer
*peer2
= p2
;
795 return (sockunion_same(&peer1
->su
, &peer2
->su
)
796 && CHECK_FLAG(peer1
->flags
, PEER_FLAG_CONFIG_NODE
)
797 == CHECK_FLAG(peer2
->flags
, PEER_FLAG_CONFIG_NODE
));
800 int peer_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
802 return CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
);
805 /* Return true if flag is set for the peer but not the peer-group */
806 static int peergroup_af_flag_check(struct peer
*peer
, afi_t afi
, safi_t safi
,
809 struct peer
*g_peer
= NULL
;
811 if (peer_af_flag_check(peer
, afi
, safi
, flag
)) {
812 if (peer_group_active(peer
)) {
813 g_peer
= peer
->group
->conf
;
815 /* If this flag is not set for the peer's peer-group
816 * then return true */
817 if (!peer_af_flag_check(g_peer
, afi
, safi
, flag
)) {
822 /* peer is not in a peer-group but the flag is set to return
832 /* Reset all address family specific configuration. */
833 static void peer_af_flag_reset(struct peer
*peer
, afi_t afi
, safi_t safi
)
836 struct bgp_filter
*filter
;
837 char orf_name
[BUFSIZ
];
839 filter
= &peer
->filter
[afi
][safi
];
841 /* Clear neighbor filter and route-map */
842 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
843 if (filter
->dlist
[i
].name
) {
844 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[i
].name
);
845 filter
->dlist
[i
].name
= NULL
;
847 if (filter
->plist
[i
].name
) {
848 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[i
].name
);
849 filter
->plist
[i
].name
= NULL
;
851 if (filter
->aslist
[i
].name
) {
852 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[i
].name
);
853 filter
->aslist
[i
].name
= NULL
;
856 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
857 if (filter
->map
[i
].name
) {
858 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[i
].name
);
859 filter
->map
[i
].name
= NULL
;
863 /* Clear unsuppress map. */
864 if (filter
->usmap
.name
)
865 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
866 filter
->usmap
.name
= NULL
;
867 filter
->usmap
.map
= NULL
;
869 /* Clear neighbor's all address family flags. */
870 peer
->af_flags
[afi
][safi
] = 0;
872 /* Clear neighbor's all address family sflags. */
873 peer
->af_sflags
[afi
][safi
] = 0;
875 /* Clear neighbor's all address family capabilities. */
876 peer
->af_cap
[afi
][safi
] = 0;
879 peer
->orf_plist
[afi
][safi
] = NULL
;
880 sprintf(orf_name
, "%s.%d.%d", peer
->host
, afi
, safi
);
881 prefix_bgp_orf_remove_all(afi
, orf_name
);
883 /* Set default neighbor send-community. */
884 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
885 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SEND_COMMUNITY
);
886 SET_FLAG(peer
->af_flags
[afi
][safi
],
887 PEER_FLAG_SEND_EXT_COMMUNITY
);
888 SET_FLAG(peer
->af_flags
[afi
][safi
],
889 PEER_FLAG_SEND_LARGE_COMMUNITY
);
892 /* Clear neighbor default_originate_rmap */
893 if (peer
->default_rmap
[afi
][safi
].name
)
894 XFREE(MTYPE_ROUTE_MAP_NAME
, peer
->default_rmap
[afi
][safi
].name
);
895 peer
->default_rmap
[afi
][safi
].name
= NULL
;
896 peer
->default_rmap
[afi
][safi
].map
= NULL
;
898 /* Clear neighbor maximum-prefix */
899 peer
->pmax
[afi
][safi
] = 0;
900 peer
->pmax_threshold
[afi
][safi
] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT
;
903 /* peer global config reset */
904 static void peer_global_config_reset(struct peer
*peer
)
908 peer
->change_local_as
= 0;
909 peer
->ttl
= (peer_sort(peer
) == BGP_PEER_IBGP
? MAXTTL
: 1);
910 if (peer
->update_source
) {
911 sockunion_free(peer
->update_source
);
912 peer
->update_source
= NULL
;
914 if (peer
->update_if
) {
915 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
916 peer
->update_if
= NULL
;
919 if (peer_sort(peer
) == BGP_PEER_IBGP
)
920 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
922 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
924 /* These are per-peer specific flags and so we must preserve them */
925 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
926 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
);
928 SET_FLAG(peer
->flags
, saved_flags
);
934 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
936 /* Reset some other configs back to defaults. */
937 peer
->v_start
= BGP_INIT_START_TIMER
;
938 peer
->password
= NULL
;
939 peer
->local_id
= peer
->bgp
->router_id
;
940 peer
->v_holdtime
= peer
->bgp
->default_holdtime
;
941 peer
->v_keepalive
= peer
->bgp
->default_keepalive
;
943 bfd_info_free(&(peer
->bfd_info
));
945 /* Set back the CONFIG_NODE flag. */
946 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
949 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
950 static inline bgp_peer_sort_t
peer_calc_sort(struct peer
*peer
)
957 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
958 if (peer
->as_type
== AS_INTERNAL
)
959 return BGP_PEER_IBGP
;
961 else if (peer
->as_type
== AS_EXTERNAL
)
962 return BGP_PEER_EBGP
;
964 else if (peer
->as_type
== AS_SPECIFIED
&& peer
->as
)
965 return (bgp
->as
== peer
->as
? BGP_PEER_IBGP
970 peer1
= listnode_head(peer
->group
->peer
);
975 return BGP_PEER_INTERNAL
;
979 if (bgp
&& CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
980 if (peer
->local_as
== 0)
981 return BGP_PEER_INTERNAL
;
983 if (peer
->local_as
== peer
->as
) {
984 if (bgp
->as
== bgp
->confed_id
) {
985 if (peer
->local_as
== bgp
->as
)
986 return BGP_PEER_IBGP
;
988 return BGP_PEER_EBGP
;
990 if (peer
->local_as
== bgp
->confed_id
)
991 return BGP_PEER_EBGP
;
993 return BGP_PEER_IBGP
;
997 if (bgp_confederation_peers_check(bgp
, peer
->as
))
998 return BGP_PEER_CONFED
;
1000 return BGP_PEER_EBGP
;
1002 if (peer
->as_type
!= AS_SPECIFIED
)
1003 return (peer
->as_type
== AS_INTERNAL
? BGP_PEER_IBGP
1006 return (peer
->local_as
== 0
1008 : peer
->local_as
== peer
->as
? BGP_PEER_IBGP
1013 /* Calculate and cache the peer "sort" */
1014 bgp_peer_sort_t
peer_sort(struct peer
*peer
)
1016 peer
->sort
= peer_calc_sort(peer
);
1020 static void peer_free(struct peer
*peer
)
1022 assert(peer
->status
== Deleted
);
1026 /* this /ought/ to have been done already through bgp_stop earlier,
1027 * but just to be sure..
1029 bgp_timer_set(peer
);
1030 bgp_reads_off(peer
);
1031 bgp_writes_off(peer
);
1032 assert(!peer
->t_write
);
1033 assert(!peer
->t_read
);
1034 BGP_EVENT_FLUSH(peer
);
1036 pthread_mutex_destroy(&peer
->io_mtx
);
1038 /* Free connected nexthop, if present */
1039 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
)
1040 && !peer_dynamic_neighbor(peer
))
1041 bgp_delete_connected_nexthop(family2afi(peer
->su
.sa
.sa_family
),
1044 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
1047 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
1051 /* Free allocated host character. */
1053 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1057 if (peer
->domainname
) {
1058 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
1059 peer
->domainname
= NULL
;
1063 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
1064 peer
->ifname
= NULL
;
1067 /* Update source configuration. */
1068 if (peer
->update_source
) {
1069 sockunion_free(peer
->update_source
);
1070 peer
->update_source
= NULL
;
1073 if (peer
->update_if
) {
1074 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
1075 peer
->update_if
= NULL
;
1078 if (peer
->notify
.data
)
1079 XFREE(MTYPE_TMP
, peer
->notify
.data
);
1080 memset(&peer
->notify
, 0, sizeof(struct bgp_notify
));
1082 if (peer
->clear_node_queue
)
1083 work_queue_free_and_null(&peer
->clear_node_queue
);
1085 bgp_sync_delete(peer
);
1087 if (peer
->conf_if
) {
1088 XFREE(MTYPE_PEER_CONF_IF
, peer
->conf_if
);
1089 peer
->conf_if
= NULL
;
1092 bfd_info_free(&(peer
->bfd_info
));
1094 bgp_unlock(peer
->bgp
);
1096 memset(peer
, 0, sizeof(struct peer
));
1098 XFREE(MTYPE_BGP_PEER
, peer
);
1101 /* increase reference count on a struct peer */
1102 struct peer
*peer_lock_with_caller(const char *name
, struct peer
*peer
)
1104 assert(peer
&& (peer
->lock
>= 0));
1107 zlog_debug("%s peer_lock %p %d", name
, peer
, peer
->lock
);
1115 /* decrease reference count on a struct peer
1116 * struct peer is freed and NULL returned if last reference
1118 struct peer
*peer_unlock_with_caller(const char *name
, struct peer
*peer
)
1120 assert(peer
&& (peer
->lock
> 0));
1123 zlog_debug("%s peer_unlock %p %d", name
, peer
, peer
->lock
);
1128 if (peer
->lock
== 0) {
1136 /* Allocate new peer object, implicitely locked. */
1137 struct peer
*peer_new(struct bgp
*bgp
)
1144 /* bgp argument is absolutely required */
1149 /* Allocate new peer. */
1150 peer
= XCALLOC(MTYPE_BGP_PEER
, sizeof(struct peer
));
1152 /* Set default value. */
1154 peer
->v_start
= BGP_INIT_START_TIMER
;
1155 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
1156 peer
->status
= Idle
;
1157 peer
->ostatus
= Idle
;
1158 peer
->cur_event
= peer
->last_event
= peer
->last_major_event
= 0;
1159 peer
->bgp
= bgp_lock(bgp
);
1160 peer
= peer_lock(peer
); /* initial reference */
1161 peer
->password
= NULL
;
1163 /* Set default flags. */
1164 FOREACH_AFI_SAFI (afi
, safi
) {
1165 if (!bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
1166 SET_FLAG(peer
->af_flags
[afi
][safi
],
1167 PEER_FLAG_SEND_COMMUNITY
);
1168 SET_FLAG(peer
->af_flags
[afi
][safi
],
1169 PEER_FLAG_SEND_EXT_COMMUNITY
);
1170 SET_FLAG(peer
->af_flags
[afi
][safi
],
1171 PEER_FLAG_SEND_LARGE_COMMUNITY
);
1173 peer
->orf_plist
[afi
][safi
] = NULL
;
1175 SET_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
);
1177 /* Create buffers. */
1178 peer
->ibuf
= stream_fifo_new();
1179 peer
->obuf
= stream_fifo_new();
1180 pthread_mutex_init(&peer
->io_mtx
, NULL
);
1182 /* We use a larger buffer for peer->obuf_work in the event that:
1183 * - We RX a BGP_UPDATE where the attributes alone are just
1184 * under BGP_MAX_PACKET_SIZE
1185 * - The user configures an outbound route-map that does many as-path
1186 * prepends or adds many communities. At most they can have
1187 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1188 * large they can make the attributes.
1190 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1191 * bounds checking for every single attribute as we construct an
1195 stream_new(BGP_MAX_PACKET_SIZE
+ BGP_MAX_PACKET_SIZE_OVERFLOW
);
1197 ringbuf_new(BGP_MAX_PACKET_SIZE
* BGP_READ_PACKET_MAX
);
1199 peer
->scratch
= stream_new(BGP_MAX_PACKET_SIZE
);
1201 bgp_sync_init(peer
);
1203 /* Get service port number. */
1204 sp
= getservbyname("bgp", "tcp");
1205 peer
->port
= (sp
== NULL
) ? BGP_PORT_DEFAULT
: ntohs(sp
->s_port
);
1207 QOBJ_REG(peer
, peer
);
1212 * This function is invoked when a duplicate peer structure associated with
1213 * a neighbor is being deleted. If this about-to-be-deleted structure is
1214 * the one with all the config, then we have to copy over the info.
1216 void peer_xfer_config(struct peer
*peer_dst
, struct peer
*peer_src
)
1218 struct peer_af
*paf
;
1226 /* The following function is used by both peer group config copy to
1227 * individual peer and when we transfer config
1229 if (peer_src
->change_local_as
)
1230 peer_dst
->change_local_as
= peer_src
->change_local_as
;
1232 /* peer flags apply */
1233 peer_dst
->flags
= peer_src
->flags
;
1234 peer_dst
->cap
= peer_src
->cap
;
1235 peer_dst
->config
= peer_src
->config
;
1237 peer_dst
->local_as
= peer_src
->local_as
;
1238 peer_dst
->port
= peer_src
->port
;
1239 (void)peer_sort(peer_dst
);
1240 peer_dst
->rmap_type
= peer_src
->rmap_type
;
1243 peer_dst
->holdtime
= peer_src
->holdtime
;
1244 peer_dst
->keepalive
= peer_src
->keepalive
;
1245 peer_dst
->connect
= peer_src
->connect
;
1246 peer_dst
->v_holdtime
= peer_src
->v_holdtime
;
1247 peer_dst
->v_keepalive
= peer_src
->v_keepalive
;
1248 peer_dst
->routeadv
= peer_src
->routeadv
;
1249 peer_dst
->v_routeadv
= peer_src
->v_routeadv
;
1251 /* password apply */
1252 if (peer_src
->password
&& !peer_dst
->password
)
1253 peer_dst
->password
=
1254 XSTRDUP(MTYPE_PEER_PASSWORD
, peer_src
->password
);
1256 FOREACH_AFI_SAFI (afi
, safi
) {
1257 peer_dst
->afc
[afi
][safi
] = peer_src
->afc
[afi
][safi
];
1258 peer_dst
->af_flags
[afi
][safi
] = peer_src
->af_flags
[afi
][safi
];
1259 peer_dst
->allowas_in
[afi
][safi
] =
1260 peer_src
->allowas_in
[afi
][safi
];
1261 peer_dst
->weight
[afi
][safi
] = peer_src
->weight
[afi
][safi
];
1264 for (afidx
= BGP_AF_START
; afidx
< BGP_AF_MAX
; afidx
++) {
1265 paf
= peer_src
->peer_af_array
[afidx
];
1267 peer_af_create(peer_dst
, paf
->afi
, paf
->safi
);
1270 /* update-source apply */
1271 if (peer_src
->update_source
) {
1272 if (peer_dst
->update_source
)
1273 sockunion_free(peer_dst
->update_source
);
1274 if (peer_dst
->update_if
) {
1275 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1276 peer_dst
->update_if
= NULL
;
1278 peer_dst
->update_source
=
1279 sockunion_dup(peer_src
->update_source
);
1280 } else if (peer_src
->update_if
) {
1281 if (peer_dst
->update_if
)
1282 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer_dst
->update_if
);
1283 if (peer_dst
->update_source
) {
1284 sockunion_free(peer_dst
->update_source
);
1285 peer_dst
->update_source
= NULL
;
1287 peer_dst
->update_if
=
1288 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, peer_src
->update_if
);
1291 if (peer_src
->ifname
) {
1292 if (peer_dst
->ifname
)
1293 XFREE(MTYPE_BGP_PEER_IFNAME
, peer_dst
->ifname
);
1296 XSTRDUP(MTYPE_BGP_PEER_IFNAME
, peer_src
->ifname
);
1300 static int bgp_peer_conf_if_to_su_update_v4(struct peer
*peer
,
1301 struct interface
*ifp
)
1303 struct connected
*ifc
;
1306 struct listnode
*node
;
1308 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1309 * IPv4 address of the other end.
1311 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
1312 if (ifc
->address
&& (ifc
->address
->family
== AF_INET
)) {
1313 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
1314 if (p
.prefixlen
== 30) {
1315 peer
->su
.sa
.sa_family
= AF_INET
;
1316 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1318 peer
->su
.sin
.sin_addr
.s_addr
=
1320 else if (addr
% 4 == 2)
1321 peer
->su
.sin
.sin_addr
.s_addr
=
1323 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1324 peer
->su
.sin
.sin_len
=
1325 sizeof(struct sockaddr_in
);
1326 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1328 } else if (p
.prefixlen
== 31) {
1329 peer
->su
.sa
.sa_family
= AF_INET
;
1330 addr
= ntohl(p
.u
.prefix4
.s_addr
);
1332 peer
->su
.sin
.sin_addr
.s_addr
=
1335 peer
->su
.sin
.sin_addr
.s_addr
=
1337 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1338 peer
->su
.sin
.sin_len
=
1339 sizeof(struct sockaddr_in
);
1340 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1342 } else if (bgp_debug_neighbor_events(peer
))
1344 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1352 static int bgp_peer_conf_if_to_su_update_v6(struct peer
*peer
,
1353 struct interface
*ifp
)
1355 struct nbr_connected
*ifc_nbr
;
1357 /* Have we learnt the peer's IPv6 link-local address? */
1358 if (ifp
->nbr_connected
1359 && (ifc_nbr
= listnode_head(ifp
->nbr_connected
))) {
1360 peer
->su
.sa
.sa_family
= AF_INET6
;
1361 memcpy(&peer
->su
.sin6
.sin6_addr
, &ifc_nbr
->address
->u
.prefix
,
1362 sizeof(struct in6_addr
));
1364 peer
->su
.sin6
.sin6_len
= sizeof(struct sockaddr_in6
);
1366 peer
->su
.sin6
.sin6_scope_id
= ifp
->ifindex
;
1374 * Set or reset the peer address socketunion structure based on the
1375 * learnt/derived peer address. If the address has changed, update the
1376 * password on the listen socket, if needed.
1378 void bgp_peer_conf_if_to_su_update(struct peer
*peer
)
1380 struct interface
*ifp
;
1382 int peer_addr_updated
= 0;
1387 prev_family
= peer
->su
.sa
.sa_family
;
1388 if ((ifp
= if_lookup_by_name(peer
->conf_if
, peer
->bgp
->vrf_id
))) {
1390 /* If BGP unnumbered is not "v6only", we first see if we can
1392 * peer's IPv4 address.
1394 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
1396 bgp_peer_conf_if_to_su_update_v4(peer
, ifp
);
1398 /* If "v6only" or we can't derive peer's IPv4 address, see if
1400 * learnt the peer's IPv6 link-local address. This is from the
1402 * IPv6 address in router advertisement.
1404 if (!peer_addr_updated
)
1406 bgp_peer_conf_if_to_su_update_v6(peer
, ifp
);
1408 /* If we could derive the peer address, we may need to install the
1410 * configured for the peer, if any, on the listen socket. Otherwise,
1412 * that peer's address is not available and uninstall the password, if
1415 if (peer_addr_updated
) {
1416 if (peer
->password
&& prev_family
== AF_UNSPEC
)
1419 if (peer
->password
&& prev_family
!= AF_UNSPEC
)
1420 bgp_md5_unset(peer
);
1421 peer
->su
.sa
.sa_family
= AF_UNSPEC
;
1422 memset(&peer
->su
.sin6
.sin6_addr
, 0, sizeof(struct in6_addr
));
1425 /* Since our su changed we need to del/add peer to the peerhash */
1426 hash_release(peer
->bgp
->peerhash
, peer
);
1427 hash_get(peer
->bgp
->peerhash
, peer
, hash_alloc_intern
);
1430 static void bgp_recalculate_afi_safi_bestpaths(struct bgp
*bgp
, afi_t afi
,
1433 struct bgp_node
*rn
, *nrn
;
1435 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
1436 rn
= bgp_route_next(rn
)) {
1437 if (rn
->info
!= NULL
) {
1438 /* Special handling for 2-level routing
1440 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
1441 || safi
== SAFI_EVPN
) {
1442 for (nrn
= bgp_table_top(
1443 (struct bgp_table
*)(rn
->info
));
1444 nrn
; nrn
= bgp_route_next(nrn
))
1445 bgp_process(bgp
, nrn
, afi
, safi
);
1447 bgp_process(bgp
, rn
, afi
, safi
);
1452 /* Force a bestpath recalculation for all prefixes. This is used
1453 * when 'bgp bestpath' commands are entered.
1455 void bgp_recalculate_all_bestpaths(struct bgp
*bgp
)
1460 FOREACH_AFI_SAFI (afi
, safi
) {
1461 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, safi
);
1465 /* Create new BGP peer. */
1466 struct peer
*peer_create(union sockunion
*su
, const char *conf_if
,
1467 struct bgp
*bgp
, as_t local_as
, as_t remote_as
,
1468 int as_type
, afi_t afi
, safi_t safi
,
1469 struct peer_group
*group
)
1473 char buf
[SU_ADDRSTRLEN
];
1475 peer
= peer_new(bgp
);
1477 peer
->conf_if
= XSTRDUP(MTYPE_PEER_CONF_IF
, conf_if
);
1478 bgp_peer_conf_if_to_su_update(peer
);
1480 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1481 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, conf_if
);
1484 sockunion2str(su
, buf
, SU_ADDRSTRLEN
);
1486 XFREE(MTYPE_BGP_PEER_HOST
, peer
->host
);
1487 peer
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, buf
);
1489 peer
->local_as
= local_as
;
1490 peer
->as
= remote_as
;
1491 peer
->as_type
= as_type
;
1492 peer
->local_id
= bgp
->router_id
;
1493 peer
->v_holdtime
= bgp
->default_holdtime
;
1494 peer
->v_keepalive
= bgp
->default_keepalive
;
1495 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1496 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1498 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1500 peer
= peer_lock(peer
); /* bgp peer list reference */
1501 peer
->group
= group
;
1502 listnode_add_sort(bgp
->peer
, peer
);
1503 hash_get(bgp
->peerhash
, peer
, hash_alloc_intern
);
1505 /* Adjust update-group coalesce timer heuristics for # peers. */
1506 if (bgp
->heuristic_coalesce
) {
1507 long ct
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1509 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME
);
1510 bgp
->coalesce_time
= MIN(BGP_MAX_SUBGROUP_COALESCE_TIME
, ct
);
1513 active
= peer_active(peer
);
1515 /* Last read and reset time set */
1516 peer
->readtime
= peer
->resettime
= bgp_clock();
1518 /* Default TTL set. */
1519 peer
->ttl
= (peer
->sort
== BGP_PEER_IBGP
) ? MAXTTL
: 1;
1521 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
1524 peer
->afc
[afi
][safi
] = 1;
1525 peer_af_create(peer
, afi
, safi
);
1528 /* auto shutdown if configured */
1529 if (bgp
->autoshutdown
)
1530 peer_flag_set(peer
, PEER_FLAG_SHUTDOWN
);
1531 /* Set up peer's events and timers. */
1532 else if (!active
&& peer_active(peer
))
1533 bgp_timer_set(peer
);
1538 /* Make accept BGP peer. This function is only called from the test code */
1539 struct peer
*peer_create_accept(struct bgp
*bgp
)
1543 peer
= peer_new(bgp
);
1545 peer
= peer_lock(peer
); /* bgp peer list reference */
1546 listnode_add_sort(bgp
->peer
, peer
);
1552 * Return true if we have a peer configured to use this afi/safi
1554 int bgp_afi_safi_peer_exists(struct bgp
*bgp
, afi_t afi
, safi_t safi
)
1556 struct listnode
*node
;
1559 for (ALL_LIST_ELEMENTS_RO(bgp
->peer
, node
, peer
)) {
1560 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
1563 if (peer
->afc
[afi
][safi
])
1570 /* Change peer's AS number. */
1571 void peer_as_change(struct peer
*peer
, as_t as
, int as_specified
)
1573 bgp_peer_sort_t type
;
1577 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1578 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
1579 peer
->last_reset
= PEER_DOWN_REMOTE_AS_CHANGE
;
1580 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1581 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1583 bgp_session_reset(peer
);
1585 type
= peer_sort(peer
);
1587 peer
->as_type
= as_specified
;
1589 if (bgp_config_check(peer
->bgp
, BGP_CONFIG_CONFEDERATION
)
1590 && !bgp_confederation_peers_check(peer
->bgp
, as
)
1591 && peer
->bgp
->as
!= as
)
1592 peer
->local_as
= peer
->bgp
->confed_id
;
1594 peer
->local_as
= peer
->bgp
->as
;
1596 /* Advertisement-interval reset */
1599 conf
= peer
->group
->conf
;
1601 if (conf
&& CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
)) {
1602 peer
->v_routeadv
= conf
->routeadv
;
1604 /* Only go back to the default advertisement-interval if the user had
1606 * already configured it */
1607 else if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)) {
1608 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1609 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
1611 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
1614 if (peer_sort(peer
) == BGP_PEER_IBGP
)
1616 else if (type
== BGP_PEER_IBGP
)
1619 /* reflector-client reset */
1620 if (peer_sort(peer
) != BGP_PEER_IBGP
) {
1621 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_UNICAST
],
1622 PEER_FLAG_REFLECTOR_CLIENT
);
1623 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MULTICAST
],
1624 PEER_FLAG_REFLECTOR_CLIENT
);
1625 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_LABELED_UNICAST
],
1626 PEER_FLAG_REFLECTOR_CLIENT
);
1627 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_MPLS_VPN
],
1628 PEER_FLAG_REFLECTOR_CLIENT
);
1629 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_ENCAP
],
1630 PEER_FLAG_REFLECTOR_CLIENT
);
1631 UNSET_FLAG(peer
->af_flags
[AFI_IP
][SAFI_FLOWSPEC
],
1632 PEER_FLAG_REFLECTOR_CLIENT
);
1633 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_UNICAST
],
1634 PEER_FLAG_REFLECTOR_CLIENT
);
1635 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MULTICAST
],
1636 PEER_FLAG_REFLECTOR_CLIENT
);
1637 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_LABELED_UNICAST
],
1638 PEER_FLAG_REFLECTOR_CLIENT
);
1639 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_MPLS_VPN
],
1640 PEER_FLAG_REFLECTOR_CLIENT
);
1641 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_ENCAP
],
1642 PEER_FLAG_REFLECTOR_CLIENT
);
1643 UNSET_FLAG(peer
->af_flags
[AFI_IP6
][SAFI_FLOWSPEC
],
1644 PEER_FLAG_REFLECTOR_CLIENT
);
1645 UNSET_FLAG(peer
->af_flags
[AFI_L2VPN
][SAFI_EVPN
],
1646 PEER_FLAG_REFLECTOR_CLIENT
);
1649 /* local-as reset */
1650 if (peer_sort(peer
) != BGP_PEER_EBGP
) {
1651 peer
->change_local_as
= 0;
1652 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
1653 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
1657 /* If peer does not exist, create new one. If peer already exists,
1658 set AS number to the peer. */
1659 int peer_remote_as(struct bgp
*bgp
, union sockunion
*su
, const char *conf_if
,
1660 as_t
*as
, int as_type
, afi_t afi
, safi_t safi
)
1666 peer
= peer_lookup_by_conf_if(bgp
, conf_if
);
1668 peer
= peer_lookup(bgp
, su
);
1671 /* Not allowed for a dynamic peer. */
1672 if (peer_dynamic_neighbor(peer
)) {
1674 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER
;
1677 /* When this peer is a member of peer-group. */
1679 if (peer
->group
->conf
->as
) {
1680 /* Return peer group's AS number. */
1681 *as
= peer
->group
->conf
->as
;
1682 return BGP_ERR_PEER_GROUP_MEMBER
;
1684 if (peer_sort(peer
->group
->conf
) == BGP_PEER_IBGP
) {
1685 if ((as_type
!= AS_INTERNAL
)
1686 && (bgp
->as
!= *as
)) {
1688 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1691 if ((as_type
!= AS_EXTERNAL
)
1692 && (bgp
->as
== *as
)) {
1694 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
1699 /* Existing peer's AS number change. */
1700 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
1701 || (peer
->as_type
!= as_type
))
1702 peer_as_change(peer
, *as
, as_type
);
1705 return BGP_ERR_NO_INTERFACE_CONFIG
;
1707 /* If the peer is not part of our confederation, and its not an
1708 iBGP peer then spoof the source AS */
1709 if (bgp_config_check(bgp
, BGP_CONFIG_CONFEDERATION
)
1710 && !bgp_confederation_peers_check(bgp
, *as
)
1712 local_as
= bgp
->confed_id
;
1716 /* If this is IPv4 unicast configuration and "no bgp default
1717 ipv4-unicast" is specified. */
1719 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
)
1720 && afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
1721 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
, 0,
1724 peer_create(su
, conf_if
, bgp
, local_as
, *as
, as_type
,
1731 static void peer_group2peer_config_copy_af(struct peer_group
*group
,
1732 struct peer
*peer
, afi_t afi
,
1736 int out
= FILTER_OUT
;
1738 struct bgp_filter
*pfilter
;
1739 struct bgp_filter
*gfilter
;
1742 pfilter
= &peer
->filter
[afi
][safi
];
1743 gfilter
= &conf
->filter
[afi
][safi
];
1745 /* peer af_flags apply */
1746 peer
->af_flags
[afi
][safi
] = conf
->af_flags
[afi
][safi
];
1748 /* maximum-prefix */
1749 peer
->pmax
[afi
][safi
] = conf
->pmax
[afi
][safi
];
1750 peer
->pmax_threshold
[afi
][safi
] = conf
->pmax_threshold
[afi
][safi
];
1751 peer
->pmax_restart
[afi
][safi
] = conf
->pmax_restart
[afi
][safi
];
1754 peer
->allowas_in
[afi
][safi
] = conf
->allowas_in
[afi
][safi
];
1757 peer
->weight
[afi
][safi
] = conf
->weight
[afi
][safi
];
1759 /* default-originate route-map */
1760 if (conf
->default_rmap
[afi
][safi
].name
) {
1761 if (peer
->default_rmap
[afi
][safi
].name
)
1762 XFREE(MTYPE_BGP_FILTER_NAME
,
1763 peer
->default_rmap
[afi
][safi
].name
);
1764 peer
->default_rmap
[afi
][safi
].name
=
1765 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1766 conf
->default_rmap
[afi
][safi
].name
);
1767 peer
->default_rmap
[afi
][safi
].map
=
1768 conf
->default_rmap
[afi
][safi
].map
;
1771 /* inbound filter apply */
1772 if (gfilter
->dlist
[in
].name
&& !pfilter
->dlist
[in
].name
) {
1773 if (pfilter
->dlist
[in
].name
)
1774 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[in
].name
);
1775 pfilter
->dlist
[in
].name
=
1776 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->dlist
[in
].name
);
1777 pfilter
->dlist
[in
].alist
= gfilter
->dlist
[in
].alist
;
1780 if (gfilter
->plist
[in
].name
&& !pfilter
->plist
[in
].name
) {
1781 if (pfilter
->plist
[in
].name
)
1782 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[in
].name
);
1783 pfilter
->plist
[in
].name
=
1784 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->plist
[in
].name
);
1785 pfilter
->plist
[in
].plist
= gfilter
->plist
[in
].plist
;
1788 if (gfilter
->aslist
[in
].name
&& !pfilter
->aslist
[in
].name
) {
1789 if (pfilter
->aslist
[in
].name
)
1790 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[in
].name
);
1791 pfilter
->aslist
[in
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1792 gfilter
->aslist
[in
].name
);
1793 pfilter
->aslist
[in
].aslist
= gfilter
->aslist
[in
].aslist
;
1796 if (gfilter
->map
[RMAP_IN
].name
&& !pfilter
->map
[RMAP_IN
].name
) {
1797 if (pfilter
->map
[RMAP_IN
].name
)
1798 XFREE(MTYPE_BGP_FILTER_NAME
,
1799 pfilter
->map
[RMAP_IN
].name
);
1800 pfilter
->map
[RMAP_IN
].name
= XSTRDUP(
1801 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_IN
].name
);
1802 pfilter
->map
[RMAP_IN
].map
= gfilter
->map
[RMAP_IN
].map
;
1805 /* outbound filter apply */
1806 if (gfilter
->dlist
[out
].name
) {
1807 if (pfilter
->dlist
[out
].name
)
1808 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1809 pfilter
->dlist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1810 gfilter
->dlist
[out
].name
);
1811 pfilter
->dlist
[out
].alist
= gfilter
->dlist
[out
].alist
;
1813 if (pfilter
->dlist
[out
].name
)
1814 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->dlist
[out
].name
);
1815 pfilter
->dlist
[out
].name
= NULL
;
1816 pfilter
->dlist
[out
].alist
= NULL
;
1819 if (gfilter
->plist
[out
].name
) {
1820 if (pfilter
->plist
[out
].name
)
1821 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1822 pfilter
->plist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1823 gfilter
->plist
[out
].name
);
1824 pfilter
->plist
[out
].plist
= gfilter
->plist
[out
].plist
;
1826 if (pfilter
->plist
[out
].name
)
1827 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->plist
[out
].name
);
1828 pfilter
->plist
[out
].name
= NULL
;
1829 pfilter
->plist
[out
].plist
= NULL
;
1832 if (gfilter
->aslist
[out
].name
) {
1833 if (pfilter
->aslist
[out
].name
)
1834 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1835 pfilter
->aslist
[out
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
,
1836 gfilter
->aslist
[out
].name
);
1837 pfilter
->aslist
[out
].aslist
= gfilter
->aslist
[out
].aslist
;
1839 if (pfilter
->aslist
[out
].name
)
1840 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->aslist
[out
].name
);
1841 pfilter
->aslist
[out
].name
= NULL
;
1842 pfilter
->aslist
[out
].aslist
= NULL
;
1845 if (gfilter
->map
[RMAP_OUT
].name
) {
1846 if (pfilter
->map
[RMAP_OUT
].name
)
1847 XFREE(MTYPE_BGP_FILTER_NAME
,
1848 pfilter
->map
[RMAP_OUT
].name
);
1849 pfilter
->map
[RMAP_OUT
].name
= XSTRDUP(
1850 MTYPE_BGP_FILTER_NAME
, gfilter
->map
[RMAP_OUT
].name
);
1851 pfilter
->map
[RMAP_OUT
].map
= gfilter
->map
[RMAP_OUT
].map
;
1853 if (pfilter
->map
[RMAP_OUT
].name
)
1854 XFREE(MTYPE_BGP_FILTER_NAME
,
1855 pfilter
->map
[RMAP_OUT
].name
);
1856 pfilter
->map
[RMAP_OUT
].name
= NULL
;
1857 pfilter
->map
[RMAP_OUT
].map
= NULL
;
1860 if (gfilter
->usmap
.name
) {
1861 if (pfilter
->usmap
.name
)
1862 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1863 pfilter
->usmap
.name
=
1864 XSTRDUP(MTYPE_BGP_FILTER_NAME
, gfilter
->usmap
.name
);
1865 pfilter
->usmap
.map
= gfilter
->usmap
.map
;
1867 if (pfilter
->usmap
.name
)
1868 XFREE(MTYPE_BGP_FILTER_NAME
, pfilter
->usmap
.name
);
1869 pfilter
->usmap
.name
= NULL
;
1870 pfilter
->usmap
.map
= NULL
;
1874 static int peer_activate_af(struct peer
*peer
, afi_t afi
, safi_t safi
)
1878 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1879 zlog_err("%s was called for peer-group %s", __func__
,
1884 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
1886 if ((safi
== SAFI_UNICAST
&& peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1887 || (safi
== SAFI_LABELED_UNICAST
&& peer
->afc
[afi
][SAFI_UNICAST
]))
1888 return BGP_ERR_PEER_SAFI_CONFLICT
;
1890 /* Nothing to do if we've already activated this peer */
1891 if (peer
->afc
[afi
][safi
])
1894 if (peer_af_create(peer
, afi
, safi
) == NULL
)
1897 active
= peer_active(peer
);
1898 peer
->afc
[afi
][safi
] = 1;
1901 peer_group2peer_config_copy_af(peer
->group
, peer
, afi
, safi
);
1903 if (!active
&& peer_active(peer
)) {
1904 bgp_timer_set(peer
);
1906 if (peer
->status
== Established
) {
1907 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
1908 peer
->afc_adv
[afi
][safi
] = 1;
1909 bgp_capability_send(peer
, afi
, safi
,
1911 CAPABILITY_ACTION_SET
);
1912 if (peer
->afc_recv
[afi
][safi
]) {
1913 peer
->afc_nego
[afi
][safi
] = 1;
1914 bgp_announce_route(peer
, afi
, safi
);
1917 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1918 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1919 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1922 if (peer
->status
== OpenSent
|| peer
->status
== OpenConfirm
) {
1923 peer
->last_reset
= PEER_DOWN_AF_ACTIVATE
;
1924 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
1925 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
1932 /* Activate the peer or peer group for specified AFI and SAFI. */
1933 int peer_activate(struct peer
*peer
, afi_t afi
, safi_t safi
)
1936 struct peer_group
*group
;
1937 struct listnode
*node
, *nnode
;
1938 struct peer
*tmp_peer
;
1941 /* Nothing to do if we've already activated this peer */
1942 if (peer
->afc
[afi
][safi
])
1947 /* This is a peer-group so activate all of the members of the
1948 * peer-group as well */
1949 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1951 /* Do not activate a peer for both SAFI_UNICAST and
1952 * SAFI_LABELED_UNICAST */
1953 if ((safi
== SAFI_UNICAST
1954 && peer
->afc
[afi
][SAFI_LABELED_UNICAST
])
1955 || (safi
== SAFI_LABELED_UNICAST
1956 && peer
->afc
[afi
][SAFI_UNICAST
]))
1957 return BGP_ERR_PEER_SAFI_CONFLICT
;
1959 peer
->afc
[afi
][safi
] = 1;
1960 group
= peer
->group
;
1962 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
1963 ret
|= peer_activate_af(tmp_peer
, afi
, safi
);
1966 ret
|= peer_activate_af(peer
, afi
, safi
);
1969 /* If this is the first peer to be activated for this
1970 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
1971 if (safi
== SAFI_LABELED_UNICAST
1972 && !bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]) {
1974 if (BGP_DEBUG(zebra
, ZEBRA
))
1976 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
1978 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 1;
1979 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
1982 if (safi
== SAFI_FLOWSPEC
) {
1983 /* connect to table manager */
1984 bgp_zebra_init_tm_connect();
1989 static int non_peergroup_deactivate_af(struct peer
*peer
, afi_t afi
,
1992 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
1993 zlog_err("%s was called for peer-group %s", __func__
,
1998 /* Nothing to do if we've already deactivated this peer */
1999 if (!peer
->afc
[afi
][safi
])
2002 /* De-activate the address family configuration. */
2003 peer
->afc
[afi
][safi
] = 0;
2005 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2006 zlog_err("couldn't delete af structure for peer %s",
2011 if (peer
->status
== Established
) {
2012 if (CHECK_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
)) {
2013 peer
->afc_adv
[afi
][safi
] = 0;
2014 peer
->afc_nego
[afi
][safi
] = 0;
2016 if (peer_active_nego(peer
)) {
2017 bgp_capability_send(peer
, afi
, safi
,
2019 CAPABILITY_ACTION_UNSET
);
2020 bgp_clear_route(peer
, afi
, safi
);
2021 peer
->pcount
[afi
][safi
] = 0;
2023 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2024 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2025 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2028 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2029 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2030 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2037 int peer_deactivate(struct peer
*peer
, afi_t afi
, safi_t safi
)
2040 struct peer_group
*group
;
2041 struct peer
*tmp_peer
;
2042 struct listnode
*node
, *nnode
;
2045 /* Nothing to do if we've already de-activated this peer */
2046 if (!peer
->afc
[afi
][safi
])
2049 /* This is a peer-group so de-activate all of the members of the
2050 * peer-group as well */
2051 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
2052 peer
->afc
[afi
][safi
] = 0;
2053 group
= peer
->group
;
2055 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2056 zlog_err("couldn't delete af structure for peer %s",
2060 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
2061 ret
|= non_peergroup_deactivate_af(tmp_peer
, afi
, safi
);
2064 ret
|= non_peergroup_deactivate_af(peer
, afi
, safi
);
2069 /* If this is the last peer to be deactivated for this
2070 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2071 if (safi
== SAFI_LABELED_UNICAST
2072 && bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
]
2073 && !bgp_afi_safi_peer_exists(bgp
, afi
, safi
)) {
2075 if (BGP_DEBUG(zebra
, ZEBRA
))
2077 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2079 bgp
->allocate_mpls_labels
[afi
][SAFI_UNICAST
] = 0;
2080 bgp_recalculate_afi_safi_bestpaths(bgp
, afi
, SAFI_UNICAST
);
2085 int peer_afc_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int enable
)
2088 return peer_activate(peer
, afi
, safi
);
2090 return peer_deactivate(peer
, afi
, safi
);
2093 static void peer_nsf_stop(struct peer
*peer
)
2098 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
);
2099 UNSET_FLAG(peer
->sflags
, PEER_STATUS_NSF_MODE
);
2101 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2102 for (safi
= SAFI_UNICAST
; safi
<= SAFI_MPLS_VPN
; safi
++)
2103 peer
->nsf
[afi
][safi
] = 0;
2105 if (peer
->t_gr_restart
) {
2106 BGP_TIMER_OFF(peer
->t_gr_restart
);
2107 if (bgp_debug_neighbor_events(peer
))
2108 zlog_debug("%s graceful restart timer stopped",
2111 if (peer
->t_gr_stale
) {
2112 BGP_TIMER_OFF(peer
->t_gr_stale
);
2113 if (bgp_debug_neighbor_events(peer
))
2115 "%s graceful restart stalepath timer stopped",
2118 bgp_clear_route_all(peer
);
2121 /* Delete peer from confguration.
2123 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2124 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2126 * This function /should/ take care to be idempotent, to guard against
2127 * it being called multiple times through stray events that come in
2128 * that happen to result in this function being called again. That
2129 * said, getting here for a "Deleted" peer is a bug in the neighbour
2132 int peer_delete(struct peer
*peer
)
2138 struct bgp_filter
*filter
;
2139 struct listnode
*pn
;
2142 assert(peer
->status
!= Deleted
);
2145 accept_peer
= CHECK_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2147 bgp_reads_off(peer
);
2148 bgp_writes_off(peer
);
2149 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_WRITES_ON
));
2150 assert(!CHECK_FLAG(peer
->thread_flags
, PEER_THREAD_READS_ON
));
2152 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2153 peer_nsf_stop(peer
);
2155 SET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2157 /* If this peer belongs to peer group, clear up the
2160 if (peer_dynamic_neighbor(peer
))
2161 peer_drop_dynamic_neighbor(peer
);
2163 if ((pn
= listnode_lookup(peer
->group
->peer
, peer
))) {
2165 peer
); /* group->peer list reference */
2166 list_delete_node(peer
->group
->peer
, pn
);
2171 /* Withdraw all information from routing table. We can not use
2172 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2173 * executed after peer structure is deleted.
2175 peer
->last_reset
= PEER_DOWN_NEIGHBOR_DELETE
;
2177 UNSET_FLAG(peer
->flags
, PEER_FLAG_DELETE
);
2179 if (peer
->doppelganger
) {
2180 peer
->doppelganger
->doppelganger
= NULL
;
2181 peer
->doppelganger
= NULL
;
2184 UNSET_FLAG(peer
->sflags
, PEER_STATUS_ACCEPT_PEER
);
2185 bgp_fsm_change_status(peer
, Deleted
);
2187 /* Remove from NHT */
2188 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
2189 bgp_unlink_nexthop_by_peer(peer
);
2191 /* Password configuration */
2192 if (peer
->password
) {
2193 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
2194 peer
->password
= NULL
;
2196 if (!accept_peer
&& !BGP_PEER_SU_UNSPEC(peer
)
2197 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
2198 bgp_md5_unset(peer
);
2201 bgp_timer_set(peer
); /* stops all timers for Deleted */
2203 /* Delete from all peer list. */
2204 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
2205 && (pn
= listnode_lookup(bgp
->peer
, peer
))) {
2206 peer_unlock(peer
); /* bgp peer list reference */
2207 list_delete_node(bgp
->peer
, pn
);
2208 hash_release(bgp
->peerhash
, peer
);
2213 stream_fifo_free(peer
->ibuf
);
2218 stream_fifo_free(peer
->obuf
);
2222 if (peer
->ibuf_work
) {
2223 ringbuf_del(peer
->ibuf_work
);
2224 peer
->ibuf_work
= NULL
;
2227 if (peer
->obuf_work
) {
2228 stream_free(peer
->obuf_work
);
2229 peer
->obuf_work
= NULL
;
2232 if (peer
->scratch
) {
2233 stream_free(peer
->scratch
);
2234 peer
->scratch
= NULL
;
2237 /* Local and remote addresses. */
2238 if (peer
->su_local
) {
2239 sockunion_free(peer
->su_local
);
2240 peer
->su_local
= NULL
;
2243 if (peer
->su_remote
) {
2244 sockunion_free(peer
->su_remote
);
2245 peer
->su_remote
= NULL
;
2248 /* Free filter related memory. */
2249 FOREACH_AFI_SAFI (afi
, safi
) {
2250 filter
= &peer
->filter
[afi
][safi
];
2252 for (i
= FILTER_IN
; i
< FILTER_MAX
; i
++) {
2253 if (filter
->dlist
[i
].name
) {
2254 XFREE(MTYPE_BGP_FILTER_NAME
,
2255 filter
->dlist
[i
].name
);
2256 filter
->dlist
[i
].name
= NULL
;
2259 if (filter
->plist
[i
].name
) {
2260 XFREE(MTYPE_BGP_FILTER_NAME
,
2261 filter
->plist
[i
].name
);
2262 filter
->plist
[i
].name
= NULL
;
2265 if (filter
->aslist
[i
].name
) {
2266 XFREE(MTYPE_BGP_FILTER_NAME
,
2267 filter
->aslist
[i
].name
);
2268 filter
->aslist
[i
].name
= NULL
;
2272 for (i
= RMAP_IN
; i
< RMAP_MAX
; i
++) {
2273 if (filter
->map
[i
].name
) {
2274 XFREE(MTYPE_BGP_FILTER_NAME
,
2275 filter
->map
[i
].name
);
2276 filter
->map
[i
].name
= NULL
;
2280 if (filter
->usmap
.name
) {
2281 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
2282 filter
->usmap
.name
= NULL
;
2285 if (peer
->default_rmap
[afi
][safi
].name
) {
2286 XFREE(MTYPE_ROUTE_MAP_NAME
,
2287 peer
->default_rmap
[afi
][safi
].name
);
2288 peer
->default_rmap
[afi
][safi
].name
= NULL
;
2292 FOREACH_AFI_SAFI (afi
, safi
)
2293 peer_af_delete(peer
, afi
, safi
);
2295 if (peer
->hostname
) {
2296 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
2297 peer
->hostname
= NULL
;
2300 if (peer
->domainname
) {
2301 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
2302 peer
->domainname
= NULL
;
2305 peer_unlock(peer
); /* initial reference */
2310 static int peer_group_cmp(struct peer_group
*g1
, struct peer_group
*g2
)
2312 return strcmp(g1
->name
, g2
->name
);
2315 /* Peer group cofiguration. */
2316 static struct peer_group
*peer_group_new(void)
2318 return (struct peer_group
*)XCALLOC(MTYPE_PEER_GROUP
,
2319 sizeof(struct peer_group
));
2322 static void peer_group_free(struct peer_group
*group
)
2324 XFREE(MTYPE_PEER_GROUP
, group
);
2327 struct peer_group
*peer_group_lookup(struct bgp
*bgp
, const char *name
)
2329 struct peer_group
*group
;
2330 struct listnode
*node
, *nnode
;
2332 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
2333 if (strcmp(group
->name
, name
) == 0)
2339 struct peer_group
*peer_group_get(struct bgp
*bgp
, const char *name
)
2341 struct peer_group
*group
;
2344 group
= peer_group_lookup(bgp
, name
);
2348 group
= peer_group_new();
2351 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2352 group
->name
= XSTRDUP(MTYPE_PEER_GROUP_HOST
, name
);
2353 group
->peer
= list_new();
2354 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2355 group
->listen_range
[afi
] = list_new();
2356 group
->conf
= peer_new(bgp
);
2357 if (!bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
2358 group
->conf
->afc
[AFI_IP
][SAFI_UNICAST
] = 1;
2359 if (group
->conf
->host
)
2360 XFREE(MTYPE_BGP_PEER_HOST
, group
->conf
->host
);
2361 group
->conf
->host
= XSTRDUP(MTYPE_BGP_PEER_HOST
, name
);
2362 group
->conf
->group
= group
;
2363 group
->conf
->as
= 0;
2364 group
->conf
->ttl
= 1;
2365 group
->conf
->gtsm_hops
= 0;
2366 group
->conf
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2367 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_TIMER
);
2368 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
2369 UNSET_FLAG(group
->conf
->config
, PEER_CONFIG_CONNECT
);
2370 group
->conf
->keepalive
= 0;
2371 group
->conf
->holdtime
= 0;
2372 group
->conf
->connect
= 0;
2373 SET_FLAG(group
->conf
->sflags
, PEER_STATUS_GROUP
);
2374 listnode_add_sort(bgp
->group
, group
);
2379 static void peer_group2peer_config_copy(struct peer_group
*group
,
2383 int saved_flags
= 0;
2389 peer
->as
= conf
->as
;
2392 if (conf
->change_local_as
)
2393 peer
->change_local_as
= conf
->change_local_as
;
2396 peer
->ttl
= conf
->ttl
;
2399 peer
->gtsm_hops
= conf
->gtsm_hops
;
2401 /* These are per-peer specific flags and so we must preserve them */
2402 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
);
2403 saved_flags
|= CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
);
2404 peer
->flags
= conf
->flags
;
2405 SET_FLAG(peer
->flags
, saved_flags
);
2407 /* peer config apply */
2408 peer
->config
= conf
->config
;
2410 /* peer timers apply */
2411 peer
->holdtime
= conf
->holdtime
;
2412 peer
->keepalive
= conf
->keepalive
;
2413 peer
->connect
= conf
->connect
;
2414 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_CONNECT
))
2415 peer
->v_connect
= conf
->connect
;
2417 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
2419 /* advertisement-interval reset */
2420 if (CHECK_FLAG(conf
->config
, PEER_CONFIG_ROUTEADV
))
2421 peer
->v_routeadv
= conf
->routeadv
;
2422 else if (peer_sort(peer
) == BGP_PEER_IBGP
)
2423 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
2425 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
2427 /* password apply */
2428 if (conf
->password
&& !peer
->password
)
2429 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, conf
->password
);
2431 if (!BGP_PEER_SU_UNSPEC(peer
))
2434 /* update-source apply */
2435 if (conf
->update_source
) {
2436 if (peer
->update_source
)
2437 sockunion_free(peer
->update_source
);
2438 if (peer
->update_if
) {
2439 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2440 peer
->update_if
= NULL
;
2442 peer
->update_source
= sockunion_dup(conf
->update_source
);
2443 } else if (conf
->update_if
) {
2444 if (peer
->update_if
)
2445 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
2446 if (peer
->update_source
) {
2447 sockunion_free(peer
->update_source
);
2448 peer
->update_source
= NULL
;
2451 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, conf
->update_if
);
2454 bgp_bfd_peer_group2peer_copy(conf
, peer
);
2457 /* Peer group's remote AS configuration. */
2458 int peer_group_remote_as(struct bgp
*bgp
, const char *group_name
, as_t
*as
,
2461 struct peer_group
*group
;
2463 struct listnode
*node
, *nnode
;
2465 group
= peer_group_lookup(bgp
, group_name
);
2469 if ((as_type
== group
->conf
->as_type
) && (group
->conf
->as
== *as
))
2473 /* When we setup peer-group AS number all peer group member's AS
2474 number must be updated to same number. */
2475 peer_as_change(group
->conf
, *as
, as_type
);
2477 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2478 if (((peer
->as_type
== AS_SPECIFIED
) && peer
->as
!= *as
)
2479 || (peer
->as_type
!= as_type
))
2480 peer_as_change(peer
, *as
, as_type
);
2486 int peer_group_delete(struct peer_group
*group
)
2490 struct prefix
*prefix
;
2492 struct listnode
*node
, *nnode
;
2497 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2498 other
= peer
->doppelganger
;
2500 if (other
&& other
->status
!= Deleted
) {
2501 other
->group
= NULL
;
2505 list_delete_and_null(&group
->peer
);
2507 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2508 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
2510 prefix_free(prefix
);
2512 list_delete_and_null(&group
->listen_range
[afi
]);
2515 XFREE(MTYPE_PEER_GROUP_HOST
, group
->name
);
2518 bfd_info_free(&(group
->conf
->bfd_info
));
2520 group
->conf
->group
= NULL
;
2521 peer_delete(group
->conf
);
2523 /* Delete from all peer_group list. */
2524 listnode_delete(bgp
->group
, group
);
2526 peer_group_free(group
);
2531 int peer_group_remote_as_delete(struct peer_group
*group
)
2533 struct peer
*peer
, *other
;
2534 struct listnode
*node
, *nnode
;
2536 if ((group
->conf
->as_type
== AS_UNSPECIFIED
)
2537 || ((!group
->conf
->as
) && (group
->conf
->as_type
== AS_SPECIFIED
)))
2540 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2541 other
= peer
->doppelganger
;
2545 if (other
&& other
->status
!= Deleted
) {
2546 other
->group
= NULL
;
2550 list_delete_all_node(group
->peer
);
2552 group
->conf
->as
= 0;
2553 group
->conf
->as_type
= AS_UNSPECIFIED
;
2558 int peer_group_listen_range_add(struct peer_group
*group
, struct prefix
*range
)
2560 struct prefix
*prefix
;
2561 struct listnode
*node
, *nnode
;
2564 afi
= family2afi(range
->family
);
2566 /* Group needs remote AS configured. */
2567 if (group
->conf
->as_type
== AS_UNSPECIFIED
)
2568 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2570 /* Ensure no duplicates. Currently we don't care about overlaps. */
2571 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2572 if (prefix_same(range
, prefix
))
2576 prefix
= prefix_new();
2577 prefix_copy(prefix
, range
);
2578 listnode_add(group
->listen_range
[afi
], prefix
);
2582 int peer_group_listen_range_del(struct peer_group
*group
, struct prefix
*range
)
2584 struct prefix
*prefix
, prefix2
;
2585 struct listnode
*node
, *nnode
;
2588 char buf
[PREFIX2STR_BUFFER
];
2590 afi
= family2afi(range
->family
);
2592 /* Identify the listen range. */
2593 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
, prefix
)) {
2594 if (prefix_same(range
, prefix
))
2599 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND
;
2601 prefix2str(prefix
, buf
, sizeof(buf
));
2603 /* Dispose off any dynamic neighbors that exist due to this listen range
2605 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
2606 if (!peer_dynamic_neighbor(peer
))
2609 sockunion2hostprefix(&peer
->su
, &prefix2
);
2610 if (prefix_match(prefix
, &prefix2
)) {
2611 if (bgp_debug_neighbor_events(peer
))
2613 "Deleting dynamic neighbor %s group %s upon "
2614 "delete of listen range %s",
2615 peer
->host
, group
->name
, buf
);
2620 /* Get rid of the listen range */
2621 listnode_delete(group
->listen_range
[afi
], prefix
);
2626 /* Bind specified peer to peer group. */
2627 int peer_group_bind(struct bgp
*bgp
, union sockunion
*su
, struct peer
*peer
,
2628 struct peer_group
*group
, as_t
*as
)
2630 int first_member
= 0;
2633 int cap_enhe_preset
= 0;
2635 /* Lookup the peer. */
2637 peer
= peer_lookup(bgp
, su
);
2639 /* The peer exist, bind it to the peer-group */
2641 /* When the peer already belongs to a peer-group, check the
2643 if (peer_group_active(peer
)) {
2645 /* The peer is already bound to the peer-group,
2648 if (strcmp(peer
->group
->name
, group
->name
) == 0)
2651 return BGP_ERR_PEER_GROUP_CANT_CHANGE
;
2654 /* The peer has not specified a remote-as, inherit it from the
2656 if (peer
->as_type
== AS_UNSPECIFIED
) {
2657 peer
->as_type
= group
->conf
->as_type
;
2658 peer
->as
= group
->conf
->as
;
2661 if (!group
->conf
->as
) {
2662 if (peer_sort(group
->conf
) != BGP_PEER_INTERNAL
2663 && peer_sort(group
->conf
) != peer_sort(peer
)) {
2666 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT
;
2669 if (peer_sort(group
->conf
) == BGP_PEER_INTERNAL
)
2673 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
))
2674 cap_enhe_preset
= 1;
2676 peer_group2peer_config_copy(group
, peer
);
2679 * Capability extended-nexthop is enabled for an interface
2681 * default. So, fix that up here.
2683 if (peer
->conf_if
&& cap_enhe_preset
)
2684 peer_flag_set(peer
, PEER_FLAG_CAPABILITY_ENHE
);
2686 FOREACH_AFI_SAFI (afi
, safi
) {
2687 if (group
->conf
->afc
[afi
][safi
]) {
2688 peer
->afc
[afi
][safi
] = 1;
2690 if (peer_af_find(peer
, afi
, safi
)
2691 || peer_af_create(peer
, afi
, safi
)) {
2692 peer_group2peer_config_copy_af(
2693 group
, peer
, afi
, safi
);
2695 } else if (peer
->afc
[afi
][safi
])
2696 peer_deactivate(peer
, afi
, safi
);
2700 assert(group
&& peer
->group
== group
);
2702 struct listnode
*pn
;
2703 pn
= listnode_lookup(bgp
->peer
, peer
);
2704 list_delete_node(bgp
->peer
, pn
);
2705 peer
->group
= group
;
2706 listnode_add_sort(bgp
->peer
, peer
);
2708 peer
= peer_lock(peer
); /* group->peer list reference */
2709 listnode_add(group
->peer
, peer
);
2713 /* Advertisement-interval reset */
2714 if (!CHECK_FLAG(group
->conf
->config
,
2715 PEER_CONFIG_ROUTEADV
)) {
2716 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2717 group
->conf
->v_routeadv
=
2718 BGP_DEFAULT_IBGP_ROUTEADV
;
2720 group
->conf
->v_routeadv
=
2721 BGP_DEFAULT_EBGP_ROUTEADV
;
2724 /* ebgp-multihop reset */
2725 if (peer_sort(group
->conf
) == BGP_PEER_IBGP
)
2726 group
->conf
->ttl
= MAXTTL
;
2728 /* local-as reset */
2729 if (peer_sort(group
->conf
) != BGP_PEER_EBGP
) {
2730 group
->conf
->change_local_as
= 0;
2731 UNSET_FLAG(peer
->flags
,
2732 PEER_FLAG_LOCAL_AS_NO_PREPEND
);
2733 UNSET_FLAG(peer
->flags
,
2734 PEER_FLAG_LOCAL_AS_REPLACE_AS
);
2738 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2740 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2741 peer
->last_reset
= PEER_DOWN_RMAP_BIND
;
2742 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2743 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2745 bgp_session_reset(peer
);
2749 /* Create a new peer. */
2751 if ((group
->conf
->as_type
== AS_SPECIFIED
)
2752 && (!group
->conf
->as
)) {
2753 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS
;
2756 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
2757 group
->conf
->as_type
, 0, 0, group
);
2759 peer
= peer_lock(peer
); /* group->peer list reference */
2760 listnode_add(group
->peer
, peer
);
2762 peer_group2peer_config_copy(group
, peer
);
2764 /* If the peer-group is active for this afi/safi then activate
2766 FOREACH_AFI_SAFI (afi
, safi
) {
2767 if (group
->conf
->afc
[afi
][safi
]) {
2768 peer
->afc
[afi
][safi
] = 1;
2769 peer_af_create(peer
, afi
, safi
);
2770 peer_group2peer_config_copy_af(group
, peer
, afi
,
2772 } else if (peer
->afc
[afi
][safi
])
2773 peer_deactivate(peer
, afi
, safi
);
2776 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
2778 /* Set up peer's events and timers. */
2779 if (peer_active(peer
))
2780 bgp_timer_set(peer
);
2786 int peer_group_unbind(struct bgp
*bgp
, struct peer
*peer
,
2787 struct peer_group
*group
)
2793 if (group
!= peer
->group
)
2794 return BGP_ERR_PEER_GROUP_MISMATCH
;
2796 FOREACH_AFI_SAFI (afi
, safi
) {
2797 if (peer
->afc
[afi
][safi
]) {
2798 peer
->afc
[afi
][safi
] = 0;
2799 peer_af_flag_reset(peer
, afi
, safi
);
2801 if (peer_af_delete(peer
, afi
, safi
) != 0) {
2803 "couldn't delete af structure for peer %s",
2809 assert(listnode_lookup(group
->peer
, peer
));
2810 peer_unlock(peer
); /* peer group list reference */
2811 listnode_delete(group
->peer
, peer
);
2813 other
= peer
->doppelganger
;
2815 if (group
->conf
->as
) {
2817 if (other
&& other
->status
!= Deleted
) {
2820 listnode_delete(group
->peer
, other
);
2822 other
->group
= NULL
;
2828 bgp_bfd_deregister_peer(peer
);
2829 peer_global_config_reset(peer
);
2831 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
2832 peer
->last_reset
= PEER_DOWN_RMAP_UNBIND
;
2833 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
2834 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
2836 bgp_session_reset(peer
);
2841 static int bgp_startup_timer_expire(struct thread
*thread
)
2845 bgp
= THREAD_ARG(thread
);
2846 bgp
->t_startup
= NULL
;
2851 /* BGP instance creation by `router bgp' commands. */
2852 static struct bgp
*bgp_create(as_t
*as
, const char *name
,
2853 enum bgp_instance_type inst_type
)
2859 if ((bgp
= XCALLOC(MTYPE_BGP
, sizeof(struct bgp
))) == NULL
)
2862 if (BGP_DEBUG(zebra
, ZEBRA
)) {
2863 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
2864 zlog_debug("Creating Default VRF, AS %u", *as
);
2866 zlog_debug("Creating %s %s, AS %u",
2867 (inst_type
== BGP_INSTANCE_TYPE_VRF
)
2874 bgp
->heuristic_coalesce
= true;
2875 bgp
->inst_type
= inst_type
;
2876 bgp
->vrf_id
= (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) ? VRF_DEFAULT
2878 bgp
->peer_self
= peer_new(bgp
);
2879 if (bgp
->peer_self
->host
)
2880 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->host
);
2881 bgp
->peer_self
->host
=
2882 XSTRDUP(MTYPE_BGP_PEER_HOST
, "Static announcement");
2883 if (bgp
->peer_self
->hostname
!= NULL
) {
2884 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->hostname
);
2885 bgp
->peer_self
->hostname
= NULL
;
2887 if (cmd_hostname_get())
2888 bgp
->peer_self
->hostname
=
2889 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_hostname_get());
2891 if (bgp
->peer_self
->domainname
!= NULL
) {
2892 XFREE(MTYPE_BGP_PEER_HOST
, bgp
->peer_self
->domainname
);
2893 bgp
->peer_self
->domainname
= NULL
;
2895 if (cmd_domainname_get())
2896 bgp
->peer_self
->domainname
=
2897 XSTRDUP(MTYPE_BGP_PEER_HOST
, cmd_domainname_get());
2898 bgp
->peer
= list_new();
2899 bgp
->peer
->cmp
= (int (*)(void *, void *))peer_cmp
;
2900 bgp
->peerhash
= hash_create(peer_hash_key_make
, peer_hash_same
,
2902 bgp
->peerhash
->max_size
= BGP_PEER_MAX_HASH_SIZE
;
2904 bgp
->group
= list_new();
2905 bgp
->group
->cmp
= (int (*)(void *, void *))peer_group_cmp
;
2907 FOREACH_AFI_SAFI (afi
, safi
) {
2908 bgp
->route
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2909 bgp
->aggregate
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2910 bgp
->rib
[afi
][safi
] = bgp_table_init(bgp
, afi
, safi
);
2912 /* Enable maximum-paths */
2913 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_EBGP
,
2915 bgp_maximum_paths_set(bgp
, afi
, safi
, BGP_PEER_IBGP
,
2919 bgp
->v_update_delay
= BGP_UPDATE_DELAY_DEF
;
2920 bgp
->default_local_pref
= BGP_DEFAULT_LOCAL_PREF
;
2921 bgp
->default_subgroup_pkt_queue_max
=
2922 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
;
2923 bgp
->default_holdtime
= BGP_DEFAULT_HOLDTIME
;
2924 bgp
->default_keepalive
= BGP_DEFAULT_KEEPALIVE
;
2925 bgp
->restart_time
= BGP_DEFAULT_RESTART_TIME
;
2926 bgp
->stalepath_time
= BGP_DEFAULT_STALEPATH_TIME
;
2927 bgp
->dynamic_neighbors_limit
= BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT
;
2928 bgp
->dynamic_neighbors_count
= 0;
2929 #if DFLT_BGP_IMPORT_CHECK
2930 bgp_flag_set(bgp
, BGP_FLAG_IMPORT_CHECK
);
2932 #if DFLT_BGP_SHOW_HOSTNAME
2933 bgp_flag_set(bgp
, BGP_FLAG_SHOW_HOSTNAME
);
2935 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2936 bgp_flag_set(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
);
2938 #if DFLT_BGP_DETERMINISTIC_MED
2939 bgp_flag_set(bgp
, BGP_FLAG_DETERMINISTIC_MED
);
2941 bgp
->addpath_tx_id
= BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE
;
2946 if (inst_type
!= BGP_INSTANCE_TYPE_VRF
) {
2947 bgp
->rfapi
= bgp_rfapi_new(bgp
);
2949 assert(bgp
->rfapi_cfg
);
2951 #endif /* ENABLE_BGP_VNC */
2953 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++) {
2954 bgp
->vpn_policy
[afi
].tovpn_label
= MPLS_LABEL_NONE
;
2955 bgp
->vpn_policy
[afi
].tovpn_zebra_vrf_label_last_sent
=
2959 bgp
->name
= XSTRDUP(MTYPE_BGP
, name
);
2961 /* TODO - The startup timer needs to be run for the whole of BGP
2963 thread_add_timer(bm
->master
, bgp_startup_timer_expire
, bgp
,
2964 bgp
->restart_time
, &bgp
->t_startup
);
2967 /* printable name we can use in debug messages */
2968 if (inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
2969 bgp
->name_pretty
= XSTRDUP(MTYPE_BGP
, "VRF default");
2979 len
= 4 + 1 + strlen(n
) + 1; /* "view foo\0" */
2981 bgp
->name_pretty
= XCALLOC(MTYPE_BGP
, len
);
2982 snprintf(bgp
->name_pretty
, len
, "%s %s",
2983 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
2989 atomic_store_explicit(&bgp
->wpkt_quanta
, BGP_WRITE_PACKET_MAX
,
2990 memory_order_relaxed
);
2991 atomic_store_explicit(&bgp
->rpkt_quanta
, BGP_READ_PACKET_MAX
,
2992 memory_order_relaxed
);
2993 bgp
->coalesce_time
= BGP_DEFAULT_SUBGROUP_COALESCE_TIME
;
2997 update_bgp_group_init(bgp
);
3002 /* Return the "default VRF" instance of BGP. */
3003 struct bgp
*bgp_get_default(void)
3006 struct listnode
*node
, *nnode
;
3008 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3009 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3014 /* Lookup BGP entry. */
3015 struct bgp
*bgp_lookup(as_t as
, const char *name
)
3018 struct listnode
*node
, *nnode
;
3020 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3022 && ((bgp
->name
== NULL
&& name
== NULL
)
3023 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0)))
3028 /* Lookup BGP structure by view name. */
3029 struct bgp
*bgp_lookup_by_name(const char *name
)
3032 struct listnode
*node
, *nnode
;
3034 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
3035 if ((bgp
->name
== NULL
&& name
== NULL
)
3036 || (bgp
->name
&& name
&& strcmp(bgp
->name
, name
) == 0))
3041 /* Lookup BGP instance based on VRF id. */
3042 /* Note: Only to be used for incoming messages from Zebra. */
3043 struct bgp
*bgp_lookup_by_vrf_id(vrf_id_t vrf_id
)
3047 /* Lookup VRF (in tree) and follow link. */
3048 vrf
= vrf_lookup_by_id(vrf_id
);
3051 return (vrf
->info
) ? (struct bgp
*)vrf
->info
: NULL
;
3054 /* handle socket creation or deletion, if necessary
3055 * this is called for all new BGP instances
3057 int bgp_handle_socket(struct bgp
*bgp
, struct vrf
*vrf
, vrf_id_t old_vrf_id
,
3062 /* Create BGP server socket, if listen mode not disabled */
3063 if (!bgp
|| bgp_option_check(BGP_OPT_NO_LISTEN
))
3065 if (bgp
->name
&& bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
&& vrf
) {
3067 * suppress vrf socket
3069 if (create
== FALSE
) {
3070 if (vrf_is_mapped_on_netns(vrf
->vrf_id
))
3071 bgp_close_vrf_socket(bgp
);
3073 ret
= bgp_check_main_socket(create
, bgp
);
3077 * if vrf_id did not change
3079 if (vrf
->vrf_id
== old_vrf_id
)
3081 if (old_vrf_id
!= VRF_UNKNOWN
) {
3082 /* look for old socket. close it. */
3083 bgp_close_vrf_socket(bgp
);
3085 /* if backend is not yet identified ( VRF_UNKNOWN) then
3086 * creation will be done later
3088 if (vrf
->vrf_id
== VRF_UNKNOWN
)
3090 /* if BGP VRF instance requested
3091 * if backend is NETNS, create BGP server socket in the NETNS
3093 if (vrf_is_mapped_on_netns(bgp
->vrf_id
)) {
3094 ret
= bgp_socket(bgp
, bm
->port
, bm
->address
);
3096 return BGP_ERR_INVALID_VALUE
;
3100 /* if BGP VRF instance requested or VRF lite backend
3101 * if BGP non VRF instance, create it
3102 * if not already done
3104 return bgp_check_main_socket(create
, bgp
);
3107 /* Called from VTY commands. */
3108 int bgp_get(struct bgp
**bgp_val
, as_t
*as
, const char *name
,
3109 enum bgp_instance_type inst_type
)
3112 struct vrf
*vrf
= NULL
;
3114 /* Multiple instance check. */
3115 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
3117 bgp
= bgp_lookup_by_name(name
);
3119 bgp
= bgp_get_default();
3121 /* Already exists. */
3123 if (bgp
->as
!= *as
) {
3125 return BGP_ERR_INSTANCE_MISMATCH
;
3127 if (bgp
->inst_type
!= inst_type
)
3128 return BGP_ERR_INSTANCE_MISMATCH
;
3133 /* BGP instance name can not be specified for single instance.
3136 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET
;
3138 /* Get default BGP structure if exists. */
3139 bgp
= bgp_get_default();
3142 if (bgp
->as
!= *as
) {
3144 return BGP_ERR_AS_MISMATCH
;
3151 bgp
= bgp_create(as
, name
, inst_type
);
3152 bgp_router_id_set(bgp
, &bgp
->router_id_zebra
);
3153 bgp_address_init(bgp
);
3154 bgp_tip_hash_init(bgp
);
3158 bgp
->t_rmap_def_originate_eval
= NULL
;
3160 /* If Default instance or VRF, link to the VRF structure, if present. */
3161 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
3162 || bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
) {
3163 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3165 bgp_vrf_link(bgp
, vrf
);
3167 /* BGP server socket already processed if BGP instance
3168 * already part of the list
3170 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, true);
3171 listnode_add(bm
->bgp
, bgp
);
3173 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3174 bgp_zebra_instance_register(bgp
);
3181 * Make BGP instance "up". Applies only to VRFs (non-default) and
3182 * implies the VRF has been learnt from Zebra.
3184 void bgp_instance_up(struct bgp
*bgp
)
3187 struct listnode
*node
, *next
;
3189 /* Register with zebra. */
3190 bgp_zebra_instance_register(bgp
);
3192 /* Kick off any peers that may have been configured. */
3193 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3194 if (!BGP_PEER_START_SUPPRESSED(peer
))
3195 BGP_EVENT_ADD(peer
, BGP_Start
);
3198 /* Process any networks that have been configured. */
3199 bgp_static_add(bgp
);
3203 * Make BGP instance "down". Applies only to VRFs (non-default) and
3204 * implies the VRF has been deleted by Zebra.
3206 void bgp_instance_down(struct bgp
*bgp
)
3209 struct listnode
*node
;
3210 struct listnode
*next
;
3213 if (bgp
->t_rmap_def_originate_eval
) {
3214 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3215 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3219 /* Bring down peers, so corresponding routes are purged. */
3220 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3221 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3222 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3223 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3225 bgp_session_reset(peer
);
3228 /* Purge network and redistributed routes. */
3229 bgp_purge_static_redist_routes(bgp
);
3231 /* Cleanup registered nexthops (flags) */
3232 bgp_cleanup_nexthops(bgp
);
3235 /* Delete BGP instance. */
3236 int bgp_delete(struct bgp
*bgp
)
3239 struct peer_group
*group
;
3240 struct listnode
*node
, *next
;
3245 THREAD_OFF(bgp
->t_startup
);
3247 if (BGP_DEBUG(zebra
, ZEBRA
)) {
3248 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3249 zlog_debug("Deleting Default VRF");
3251 zlog_debug("Deleting %s %s",
3252 (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3258 /* unmap from RT list */
3259 bgp_evpn_vrf_delete(bgp
);
3262 if (bgp
->t_rmap_def_originate_eval
) {
3263 BGP_TIMER_OFF(bgp
->t_rmap_def_originate_eval
);
3264 bgp_unlock(bgp
); /* TODO - This timer is started with a lock -
3268 /* Inform peers we're going down. */
3269 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
)) {
3270 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
3271 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3272 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3275 /* Delete static routes (networks). */
3276 bgp_static_delete(bgp
);
3278 /* Unset redistribution. */
3279 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3280 for (i
= 0; i
< ZEBRA_ROUTE_MAX
; i
++)
3281 if (i
!= ZEBRA_ROUTE_BGP
)
3282 bgp_redistribute_unset(bgp
, afi
, i
, 0);
3284 /* Free peers and peer-groups. */
3285 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, next
, group
))
3286 peer_group_delete(group
);
3288 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, next
, peer
))
3291 if (bgp
->peer_self
) {
3292 peer_delete(bgp
->peer_self
);
3293 bgp
->peer_self
= NULL
;
3296 update_bgp_group_free(bgp
);
3298 /* TODO - Other memory may need to be freed - e.g., NHT */
3303 bgp_cleanup_routes(bgp
);
3305 for (afi
= 0; afi
< AFI_MAX
; ++afi
) {
3306 if (!bgp
->vpn_policy
[afi
].import_redirect_rtlist
)
3309 &bgp
->vpn_policy
[afi
]
3310 .import_redirect_rtlist
);
3311 bgp
->vpn_policy
[afi
].import_redirect_rtlist
= NULL
;
3313 /* Remove visibility via the master list - there may however still be
3314 * routes to be processed still referencing the struct bgp.
3316 listnode_delete(bm
->bgp
, bgp
);
3318 /* Deregister from Zebra, if needed */
3319 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp
))
3320 bgp_zebra_instance_deregister(bgp
);
3322 /* Free interfaces in this instance. */
3325 vrf
= bgp_vrf_lookup_by_instance_type(bgp
);
3326 bgp_handle_socket(bgp
, vrf
, VRF_UNKNOWN
, false);
3328 bgp_vrf_unlink(bgp
, vrf
);
3330 thread_master_free_unused(bm
->master
);
3331 bgp_unlock(bgp
); /* initial reference */
3336 void bgp_free(struct bgp
*bgp
)
3340 struct bgp_table
*table
;
3341 struct bgp_node
*rn
;
3342 struct bgp_rmap
*rmap
;
3346 list_delete_and_null(&bgp
->group
);
3347 list_delete_and_null(&bgp
->peer
);
3349 if (bgp
->peerhash
) {
3350 hash_free(bgp
->peerhash
);
3351 bgp
->peerhash
= NULL
;
3354 FOREACH_AFI_SAFI (afi
, safi
) {
3355 /* Special handling for 2-level routing tables. */
3356 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
3357 || safi
== SAFI_EVPN
) {
3358 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3359 rn
= bgp_route_next(rn
)) {
3360 table
= (struct bgp_table
*)rn
->info
;
3361 bgp_table_finish(&table
);
3364 if (bgp
->route
[afi
][safi
])
3365 bgp_table_finish(&bgp
->route
[afi
][safi
]);
3366 if (bgp
->aggregate
[afi
][safi
])
3367 bgp_table_finish(&bgp
->aggregate
[afi
][safi
]);
3368 if (bgp
->rib
[afi
][safi
])
3369 bgp_table_finish(&bgp
->rib
[afi
][safi
]);
3370 rmap
= &bgp
->table_map
[afi
][safi
];
3372 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
3375 bgp_scan_finish(bgp
);
3376 bgp_address_destroy(bgp
);
3377 bgp_tip_hash_destroy(bgp
);
3379 bgp_evpn_cleanup(bgp
);
3382 XFREE(MTYPE_BGP
, bgp
->name
);
3383 if (bgp
->name_pretty
)
3384 XFREE(MTYPE_BGP
, bgp
->name_pretty
);
3386 XFREE(MTYPE_BGP
, bgp
);
3389 struct peer
*peer_lookup_by_conf_if(struct bgp
*bgp
, const char *conf_if
)
3392 struct listnode
*node
, *nnode
;
3398 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3399 if (peer
->conf_if
&& !strcmp(peer
->conf_if
, conf_if
)
3400 && !CHECK_FLAG(peer
->sflags
,
3401 PEER_STATUS_ACCEPT_PEER
))
3403 } else if (bm
->bgp
!= NULL
) {
3404 struct listnode
*bgpnode
, *nbgpnode
;
3406 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3407 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3409 && !strcmp(peer
->conf_if
, conf_if
)
3410 && !CHECK_FLAG(peer
->sflags
,
3411 PEER_STATUS_ACCEPT_PEER
))
3417 struct peer
*peer_lookup_by_hostname(struct bgp
*bgp
, const char *hostname
)
3420 struct listnode
*node
, *nnode
;
3426 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3427 if (peer
->hostname
&& !strcmp(peer
->hostname
, hostname
)
3428 && !CHECK_FLAG(peer
->sflags
,
3429 PEER_STATUS_ACCEPT_PEER
))
3431 } else if (bm
->bgp
!= NULL
) {
3432 struct listnode
*bgpnode
, *nbgpnode
;
3434 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3435 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
3437 && !strcmp(peer
->hostname
, hostname
)
3438 && !CHECK_FLAG(peer
->sflags
,
3439 PEER_STATUS_ACCEPT_PEER
))
3445 struct peer
*peer_lookup(struct bgp
*bgp
, union sockunion
*su
)
3447 struct peer
*peer
= NULL
;
3448 struct peer tmp_peer
;
3450 memset(&tmp_peer
, 0, sizeof(struct peer
));
3453 * We do not want to find the doppelganger peer so search for the peer
3455 * the hash that has PEER_FLAG_CONFIG_NODE
3457 SET_FLAG(tmp_peer
.flags
, PEER_FLAG_CONFIG_NODE
);
3462 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3463 } else if (bm
->bgp
!= NULL
) {
3464 struct listnode
*bgpnode
, *nbgpnode
;
3466 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
)) {
3467 /* Skip VRFs Lite only, this function will not be
3468 * invoked without an instance
3469 * when examining VRFs.
3471 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
3472 && !vrf_is_mapped_on_netns(bgp
->vrf_id
))
3475 peer
= hash_lookup(bgp
->peerhash
, &tmp_peer
);
3485 struct peer
*peer_create_bind_dynamic_neighbor(struct bgp
*bgp
,
3486 union sockunion
*su
,
3487 struct peer_group
*group
)
3493 /* Create peer first; we've already checked group config is valid. */
3494 peer
= peer_create(su
, NULL
, bgp
, bgp
->as
, group
->conf
->as
,
3495 group
->conf
->as_type
, 0, 0, group
);
3500 peer
= peer_lock(peer
);
3501 listnode_add(group
->peer
, peer
);
3503 peer_group2peer_config_copy(group
, peer
);
3506 * Bind peer for all AFs configured for the group. We don't call
3507 * peer_group_bind as that is sub-optimal and does some stuff we don't
3510 FOREACH_AFI_SAFI (afi
, safi
) {
3511 if (!group
->conf
->afc
[afi
][safi
])
3513 peer
->afc
[afi
][safi
] = 1;
3515 if (!peer_af_find(peer
, afi
, safi
))
3516 peer_af_create(peer
, afi
, safi
);
3518 peer_group2peer_config_copy_af(group
, peer
, afi
, safi
);
3521 /* Mark as dynamic, but also as a "config node" for other things to
3523 SET_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_NEIGHBOR
);
3524 SET_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
);
3530 peer_group_lookup_dynamic_neighbor_range(struct peer_group
*group
,
3531 struct prefix
*prefix
)
3533 struct listnode
*node
, *nnode
;
3534 struct prefix
*range
;
3537 afi
= family2afi(prefix
->family
);
3539 if (group
->listen_range
[afi
])
3540 for (ALL_LIST_ELEMENTS(group
->listen_range
[afi
], node
, nnode
,
3542 if (prefix_match(range
, prefix
))
3549 peer_group_lookup_dynamic_neighbor(struct bgp
*bgp
, struct prefix
*prefix
,
3550 struct prefix
**listen_range
)
3552 struct prefix
*range
= NULL
;
3553 struct peer_group
*group
= NULL
;
3554 struct listnode
*node
, *nnode
;
3556 *listen_range
= NULL
;
3558 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3559 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3562 } else if (bm
->bgp
!= NULL
) {
3563 struct listnode
*bgpnode
, *nbgpnode
;
3565 for (ALL_LIST_ELEMENTS(bm
->bgp
, bgpnode
, nbgpnode
, bgp
))
3566 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
3567 if ((range
= peer_group_lookup_dynamic_neighbor_range(
3573 *listen_range
= range
;
3574 return (group
&& range
) ? group
: NULL
;
3577 struct peer
*peer_lookup_dynamic_neighbor(struct bgp
*bgp
, union sockunion
*su
)
3579 struct peer_group
*group
;
3582 struct prefix prefix
;
3583 struct prefix
*listen_range
;
3585 char buf
[PREFIX2STR_BUFFER
];
3586 char buf1
[PREFIX2STR_BUFFER
];
3588 sockunion2hostprefix(su
, &prefix
);
3590 /* See if incoming connection matches a configured listen range. */
3591 group
= peer_group_lookup_dynamic_neighbor(bgp
, &prefix
, &listen_range
);
3602 prefix2str(&prefix
, buf
, sizeof(buf
));
3603 prefix2str(listen_range
, buf1
, sizeof(buf1
));
3605 if (bgp_debug_neighbor_events(NULL
))
3607 "Dynamic Neighbor %s matches group %s listen range %s",
3608 buf
, group
->name
, buf1
);
3610 /* Are we within the listen limit? */
3611 dncount
= gbgp
->dynamic_neighbors_count
;
3613 if (dncount
>= gbgp
->dynamic_neighbors_limit
) {
3614 if (bgp_debug_neighbor_events(NULL
))
3615 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3616 inet_sutop(su
, buf
),
3617 gbgp
->dynamic_neighbors_limit
);
3621 /* Ensure group is not disabled. */
3622 if (CHECK_FLAG(group
->conf
->flags
, PEER_FLAG_SHUTDOWN
)) {
3623 if (bgp_debug_neighbor_events(NULL
))
3625 "Dynamic Neighbor %s rejected - group %s disabled",
3630 /* Check that at least one AF is activated for the group. */
3631 if (!peer_group_af_configured(group
)) {
3632 if (bgp_debug_neighbor_events(NULL
))
3634 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3639 /* Create dynamic peer and bind to associated group. */
3640 peer
= peer_create_bind_dynamic_neighbor(gbgp
, su
, group
);
3643 gbgp
->dynamic_neighbors_count
= ++dncount
;
3645 if (bgp_debug_neighbor_events(peer
))
3646 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3647 peer
->host
, group
->name
, dncount
);
3652 void peer_drop_dynamic_neighbor(struct peer
*peer
)
3655 if (peer
->group
&& peer
->group
->bgp
) {
3656 dncount
= peer
->group
->bgp
->dynamic_neighbors_count
;
3658 peer
->group
->bgp
->dynamic_neighbors_count
= --dncount
;
3660 if (bgp_debug_neighbor_events(peer
))
3661 zlog_debug("%s dropped from group %s, count %d", peer
->host
,
3662 peer
->group
->name
, dncount
);
3666 /* If peer is configured at least one address family return 1. */
3667 int peer_active(struct peer
*peer
)
3669 if (BGP_PEER_SU_UNSPEC(peer
))
3671 if (peer
->afc
[AFI_IP
][SAFI_UNICAST
] || peer
->afc
[AFI_IP
][SAFI_MULTICAST
]
3672 || peer
->afc
[AFI_IP
][SAFI_LABELED_UNICAST
]
3673 || peer
->afc
[AFI_IP
][SAFI_MPLS_VPN
] || peer
->afc
[AFI_IP
][SAFI_ENCAP
]
3674 || peer
->afc
[AFI_IP
][SAFI_FLOWSPEC
]
3675 || peer
->afc
[AFI_IP6
][SAFI_UNICAST
]
3676 || peer
->afc
[AFI_IP6
][SAFI_MULTICAST
]
3677 || peer
->afc
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3678 || peer
->afc
[AFI_IP6
][SAFI_MPLS_VPN
]
3679 || peer
->afc
[AFI_IP6
][SAFI_ENCAP
]
3680 || peer
->afc
[AFI_IP6
][SAFI_FLOWSPEC
]
3681 || peer
->afc
[AFI_L2VPN
][SAFI_EVPN
])
3686 /* If peer is negotiated at least one address family return 1. */
3687 int peer_active_nego(struct peer
*peer
)
3689 if (peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
3690 || peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
3691 || peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
3692 || peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
3693 || peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
3694 || peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
3695 || peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
3696 || peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
3697 || peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
3698 || peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
3699 || peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
3700 || peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
3701 || peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
])
3706 /* peer_flag_change_type. */
3707 enum peer_change_type
{
3710 peer_change_reset_in
,
3711 peer_change_reset_out
,
3714 static void peer_change_action(struct peer
*peer
, afi_t afi
, safi_t safi
,
3715 enum peer_change_type type
)
3717 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
3720 if (peer
->status
!= Established
)
3723 if (type
== peer_change_reset
) {
3724 /* If we're resetting session, we've to delete both peer struct
3726 if ((peer
->doppelganger
)
3727 && (peer
->doppelganger
->status
!= Deleted
)
3728 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3729 PEER_FLAG_CONFIG_NODE
)))
3730 peer_delete(peer
->doppelganger
);
3732 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3733 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3734 } else if (type
== peer_change_reset_in
) {
3735 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
3736 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
3737 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
3739 if ((peer
->doppelganger
)
3740 && (peer
->doppelganger
->status
!= Deleted
)
3741 && (!CHECK_FLAG(peer
->doppelganger
->flags
,
3742 PEER_FLAG_CONFIG_NODE
)))
3743 peer_delete(peer
->doppelganger
);
3745 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3746 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3748 } else if (type
== peer_change_reset_out
) {
3749 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
3750 bgp_announce_route(peer
, afi
, safi
);
3754 struct peer_flag_action
{
3758 /* This flag can be set for peer-group member. */
3759 uint8_t not_for_member
;
3761 /* Action when the flag is changed. */
3762 enum peer_change_type type
;
3764 /* Peer down cause */
3768 static const struct peer_flag_action peer_flag_action_list
[] = {
3769 {PEER_FLAG_PASSIVE
, 0, peer_change_reset
},
3770 {PEER_FLAG_SHUTDOWN
, 0, peer_change_reset
},
3771 {PEER_FLAG_DONT_CAPABILITY
, 0, peer_change_none
},
3772 {PEER_FLAG_OVERRIDE_CAPABILITY
, 0, peer_change_none
},
3773 {PEER_FLAG_STRICT_CAP_MATCH
, 0, peer_change_none
},
3774 {PEER_FLAG_DYNAMIC_CAPABILITY
, 0, peer_change_reset
},
3775 {PEER_FLAG_DISABLE_CONNECTED_CHECK
, 0, peer_change_reset
},
3776 {PEER_FLAG_CAPABILITY_ENHE
, 0, peer_change_reset
},
3779 static const struct peer_flag_action peer_af_flag_action_list
[] = {
3780 {PEER_FLAG_SEND_COMMUNITY
, 1, peer_change_reset_out
},
3781 {PEER_FLAG_SEND_EXT_COMMUNITY
, 1, peer_change_reset_out
},
3782 {PEER_FLAG_SEND_LARGE_COMMUNITY
, 1, peer_change_reset_out
},
3783 {PEER_FLAG_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3784 {PEER_FLAG_REFLECTOR_CLIENT
, 1, peer_change_reset
},
3785 {PEER_FLAG_RSERVER_CLIENT
, 1, peer_change_reset
},
3786 {PEER_FLAG_SOFT_RECONFIG
, 0, peer_change_reset_in
},
3787 {PEER_FLAG_AS_PATH_UNCHANGED
, 1, peer_change_reset_out
},
3788 {PEER_FLAG_NEXTHOP_UNCHANGED
, 1, peer_change_reset_out
},
3789 {PEER_FLAG_MED_UNCHANGED
, 1, peer_change_reset_out
},
3790 // PEER_FLAG_DEFAULT_ORIGINATE
3791 {PEER_FLAG_REMOVE_PRIVATE_AS
, 1, peer_change_reset_out
},
3792 {PEER_FLAG_ALLOWAS_IN
, 0, peer_change_reset_in
},
3793 {PEER_FLAG_ALLOWAS_IN_ORIGIN
, 0, peer_change_reset_in
},
3794 {PEER_FLAG_ORF_PREFIX_SM
, 1, peer_change_reset
},
3795 {PEER_FLAG_ORF_PREFIX_RM
, 1, peer_change_reset
},
3796 // PEER_FLAG_MAX_PREFIX
3797 // PEER_FLAG_MAX_PREFIX_WARNING
3798 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
, 0, peer_change_reset_out
},
3799 {PEER_FLAG_FORCE_NEXTHOP_SELF
, 1, peer_change_reset_out
},
3800 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL
, 1, peer_change_reset_out
},
3801 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
, 1, peer_change_reset_out
},
3802 {PEER_FLAG_AS_OVERRIDE
, 1, peer_change_reset_out
},
3803 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
, 1, peer_change_reset_out
},
3804 {PEER_FLAG_ADDPATH_TX_ALL_PATHS
, 1, peer_change_reset
},
3805 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
, 1, peer_change_reset
},
3806 {PEER_FLAG_WEIGHT
, 0, peer_change_reset_in
},
3809 /* Proper action set. */
3810 static int peer_flag_action_set(const struct peer_flag_action
*action_list
,
3811 int size
, struct peer_flag_action
*action
,
3818 const struct peer_flag_action
*match
= NULL
;
3820 /* Check peer's frag action. */
3821 for (i
= 0; i
< size
; i
++) {
3822 match
= &action_list
[i
];
3824 if (match
->flag
== 0)
3827 if (match
->flag
& flag
) {
3830 if (match
->type
== peer_change_reset_in
)
3832 if (match
->type
== peer_change_reset_out
)
3834 if (match
->type
== peer_change_reset
) {
3838 if (match
->not_for_member
)
3839 action
->not_for_member
= 1;
3843 /* Set peer clear type. */
3844 if (reset_in
&& reset_out
)
3845 action
->type
= peer_change_reset
;
3847 action
->type
= peer_change_reset_in
;
3849 action
->type
= peer_change_reset_out
;
3851 action
->type
= peer_change_none
;
3856 static void peer_flag_modify_action(struct peer
*peer
, uint32_t flag
)
3858 if (flag
== PEER_FLAG_SHUTDOWN
) {
3859 if (CHECK_FLAG(peer
->flags
, flag
)) {
3860 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3861 peer_nsf_stop(peer
);
3863 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
3864 if (peer
->t_pmax_restart
) {
3865 BGP_TIMER_OFF(peer
->t_pmax_restart
);
3866 if (bgp_debug_neighbor_events(peer
))
3868 "%s Maximum-prefix restart timer canceled",
3872 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
))
3873 peer_nsf_stop(peer
);
3875 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3876 char *msg
= peer
->tx_shutdown_message
;
3879 if (!msg
&& peer_group_active(peer
))
3880 msg
= peer
->group
->conf
3881 ->tx_shutdown_message
;
3882 msglen
= msg
? strlen(msg
) : 0;
3887 uint8_t msgbuf
[129];
3890 memcpy(msgbuf
+ 1, msg
, msglen
);
3892 bgp_notify_send_with_data(
3893 peer
, BGP_NOTIFY_CEASE
,
3894 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
,
3895 msgbuf
, msglen
+ 1);
3898 peer
, BGP_NOTIFY_CEASE
,
3899 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN
);
3901 bgp_session_reset(peer
);
3903 peer
->v_start
= BGP_INIT_START_TIMER
;
3904 BGP_EVENT_ADD(peer
, BGP_Stop
);
3906 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
3907 if (flag
== PEER_FLAG_DYNAMIC_CAPABILITY
)
3908 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
3909 else if (flag
== PEER_FLAG_PASSIVE
)
3910 peer
->last_reset
= PEER_DOWN_PASSIVE_CHANGE
;
3911 else if (flag
== PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3912 peer
->last_reset
= PEER_DOWN_MULTIHOP_CHANGE
;
3914 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
3915 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
3917 bgp_session_reset(peer
);
3920 /* Change specified peer flag. */
3921 static int peer_flag_modify(struct peer
*peer
, uint32_t flag
, int set
)
3925 struct peer_group
*group
;
3926 struct peer
*tmp_peer
;
3927 struct listnode
*node
, *nnode
;
3928 struct peer_flag_action action
;
3930 memset(&action
, 0, sizeof(struct peer_flag_action
));
3931 size
= sizeof peer_flag_action_list
/ sizeof(struct peer_flag_action
);
3933 found
= peer_flag_action_set(peer_flag_action_list
, size
, &action
,
3936 /* No flag action is found. */
3938 return BGP_ERR_INVALID_FLAG
;
3940 /* When unset the peer-group member's flag we have to check
3941 peer-group configuration. */
3942 if (!set
&& peer_group_active(peer
))
3943 if (CHECK_FLAG(peer
->group
->conf
->flags
, flag
)) {
3944 if (flag
== PEER_FLAG_SHUTDOWN
)
3945 return BGP_ERR_PEER_GROUP_SHUTDOWN
;
3948 /* Flag conflict check. */
3949 if (set
&& CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_STRICT_CAP_MATCH
)
3950 && CHECK_FLAG(peer
->flags
| flag
, PEER_FLAG_OVERRIDE_CAPABILITY
))
3951 return BGP_ERR_PEER_FLAG_CONFLICT
;
3953 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3954 if (set
&& CHECK_FLAG(peer
->flags
, flag
) == flag
)
3956 if (!set
&& !CHECK_FLAG(peer
->flags
, flag
))
3961 SET_FLAG(peer
->flags
, flag
);
3963 UNSET_FLAG(peer
->flags
, flag
);
3965 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
3966 if (action
.type
== peer_change_reset
)
3967 peer_flag_modify_action(peer
, flag
);
3972 /* peer-group member updates. */
3973 group
= peer
->group
;
3975 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
3977 if (set
&& CHECK_FLAG(tmp_peer
->flags
, flag
) == flag
)
3980 if (!set
&& !CHECK_FLAG(tmp_peer
->flags
, flag
))
3984 SET_FLAG(tmp_peer
->flags
, flag
);
3986 UNSET_FLAG(tmp_peer
->flags
, flag
);
3988 if (action
.type
== peer_change_reset
)
3989 peer_flag_modify_action(tmp_peer
, flag
);
3994 int peer_flag_set(struct peer
*peer
, uint32_t flag
)
3996 return peer_flag_modify(peer
, flag
, 1);
3999 int peer_flag_unset(struct peer
*peer
, uint32_t flag
)
4001 return peer_flag_modify(peer
, flag
, 0);
4004 static int peer_af_flag_modify(struct peer
*peer
, afi_t afi
, safi_t safi
,
4005 uint32_t flag
, int set
)
4009 struct listnode
*node
, *nnode
;
4010 struct peer_group
*group
;
4011 struct peer_flag_action action
;
4012 struct peer
*tmp_peer
;
4014 int addpath_tx_used
;
4016 memset(&action
, 0, sizeof(struct peer_flag_action
));
4017 size
= sizeof peer_af_flag_action_list
4018 / sizeof(struct peer_flag_action
);
4020 found
= peer_flag_action_set(peer_af_flag_action_list
, size
, &action
,
4023 /* No flag action is found. */
4025 return BGP_ERR_INVALID_FLAG
;
4027 /* Special check for reflector client. */
4028 if (flag
& PEER_FLAG_REFLECTOR_CLIENT
4029 && peer_sort(peer
) != BGP_PEER_IBGP
)
4030 return BGP_ERR_NOT_INTERNAL_PEER
;
4032 /* Special check for remove-private-AS. */
4033 if (flag
& PEER_FLAG_REMOVE_PRIVATE_AS
4034 && peer_sort(peer
) == BGP_PEER_IBGP
)
4035 return BGP_ERR_REMOVE_PRIVATE_AS
;
4037 /* as-override is not allowed for IBGP peers */
4038 if (flag
& PEER_FLAG_AS_OVERRIDE
&& peer_sort(peer
) == BGP_PEER_IBGP
)
4039 return BGP_ERR_AS_OVERRIDE
;
4041 /* When current flag configuration is same as requested one. */
4042 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4043 if (set
&& CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
) == flag
)
4045 if (!set
&& !CHECK_FLAG(peer
->af_flags
[afi
][safi
], flag
))
4050 SET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
4052 UNSET_FLAG(peer
->af_flags
[afi
][safi
], flag
);
4054 /* Execute action when peer is established. */
4055 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4056 && peer
->status
== Established
) {
4057 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4058 bgp_clear_adj_in(peer
, afi
, safi
);
4060 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4061 peer
->last_reset
= PEER_DOWN_RR_CLIENT_CHANGE
;
4062 else if (flag
== PEER_FLAG_RSERVER_CLIENT
)
4063 peer
->last_reset
= PEER_DOWN_RS_CLIENT_CHANGE
;
4064 else if (flag
== PEER_FLAG_ORF_PREFIX_SM
)
4065 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4066 else if (flag
== PEER_FLAG_ORF_PREFIX_RM
)
4067 peer
->last_reset
= PEER_DOWN_CAPABILITY_CHANGE
;
4069 peer_change_action(peer
, afi
, safi
, action
.type
);
4073 /* Peer group member updates. */
4074 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4075 group
= peer
->group
;
4077 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
4079 && CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
)
4084 && !CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
))
4088 SET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
4090 UNSET_FLAG(tmp_peer
->af_flags
[afi
][safi
], flag
);
4092 if (tmp_peer
->status
== Established
) {
4093 if (!set
&& flag
== PEER_FLAG_SOFT_RECONFIG
)
4094 bgp_clear_adj_in(tmp_peer
, afi
, safi
);
4096 if (flag
== PEER_FLAG_REFLECTOR_CLIENT
)
4097 tmp_peer
->last_reset
=
4098 PEER_DOWN_RR_CLIENT_CHANGE
;
4100 == PEER_FLAG_RSERVER_CLIENT
)
4101 tmp_peer
->last_reset
=
4102 PEER_DOWN_RS_CLIENT_CHANGE
;
4104 == PEER_FLAG_ORF_PREFIX_SM
)
4105 tmp_peer
->last_reset
=
4106 PEER_DOWN_CAPABILITY_CHANGE
;
4108 == PEER_FLAG_ORF_PREFIX_RM
)
4109 tmp_peer
->last_reset
=
4110 PEER_DOWN_CAPABILITY_CHANGE
;
4112 peer_change_action(tmp_peer
, afi
, safi
,
4119 /* Track if addpath TX is in use */
4120 if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4121 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4123 addpath_tx_used
= 0;
4126 addpath_tx_used
= 1;
4128 if (flag
& PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
) {
4129 if (!bgp_flag_check(
4130 bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
4132 "%s: enabling bgp deterministic-med, this is required"
4133 " for addpath-tx-bestpath-per-AS",
4137 BGP_FLAG_DETERMINISTIC_MED
);
4138 bgp_recalculate_all_bestpaths(bgp
);
4142 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
,
4144 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
4145 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
4147 tmp_peer
->af_flags
[afi
][safi
],
4148 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
4149 addpath_tx_used
= 1;
4155 bgp
->addpath_tx_used
[afi
][safi
] = addpath_tx_used
;
4161 int peer_af_flag_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4163 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 1);
4166 int peer_af_flag_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, uint32_t flag
)
4168 return peer_af_flag_modify(peer
, afi
, safi
, flag
, 0);
4172 int peer_tx_shutdown_message_set(struct peer
*peer
, const char *msg
)
4174 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4175 peer
->tx_shutdown_message
=
4176 msg
? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG
, msg
) : NULL
;
4180 int peer_tx_shutdown_message_unset(struct peer
*peer
)
4182 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG
, peer
->tx_shutdown_message
);
4187 /* EBGP multihop configuration. */
4188 int peer_ebgp_multihop_set(struct peer
*peer
, int ttl
)
4190 struct peer_group
*group
;
4191 struct listnode
*node
, *nnode
;
4194 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->conf_if
)
4197 /* see comment in peer_ttl_security_hops_set() */
4198 if (ttl
!= MAXTTL
) {
4199 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4200 group
= peer
->group
;
4201 if (group
->conf
->gtsm_hops
!= 0)
4202 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4204 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4206 if (peer1
->sort
== BGP_PEER_IBGP
)
4209 if (peer1
->gtsm_hops
!= 0)
4210 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4213 if (peer
->gtsm_hops
!= 0)
4214 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4220 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4221 if (peer
->fd
>= 0 && peer
->sort
!= BGP_PEER_IBGP
) {
4222 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4223 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4224 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4226 bgp_session_reset(peer
);
4229 group
= peer
->group
;
4230 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4231 if (peer
->sort
== BGP_PEER_IBGP
)
4234 peer
->ttl
= group
->conf
->ttl
;
4236 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4237 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4238 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4240 bgp_session_reset(peer
);
4246 int peer_ebgp_multihop_unset(struct peer
*peer
)
4248 struct peer_group
*group
;
4249 struct listnode
*node
, *nnode
;
4251 if (peer
->sort
== BGP_PEER_IBGP
)
4254 if (peer
->gtsm_hops
!= 0 && peer
->ttl
!= MAXTTL
)
4255 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
4257 if (peer_group_active(peer
))
4258 peer
->ttl
= peer
->group
->conf
->ttl
;
4262 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4263 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4264 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4265 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4267 bgp_session_reset(peer
);
4269 group
= peer
->group
;
4270 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4271 if (peer
->sort
== BGP_PEER_IBGP
)
4276 if (peer
->fd
>= 0) {
4277 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
4279 peer
, BGP_NOTIFY_CEASE
,
4280 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4282 bgp_session_reset(peer
);
4289 /* Neighbor description. */
4290 int peer_description_set(struct peer
*peer
, const char *desc
)
4293 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4295 peer
->desc
= XSTRDUP(MTYPE_PEER_DESC
, desc
);
4300 int peer_description_unset(struct peer
*peer
)
4303 XFREE(MTYPE_PEER_DESC
, peer
->desc
);
4310 /* Neighbor update-source. */
4311 int peer_update_source_if_set(struct peer
*peer
, const char *ifname
)
4313 struct peer_group
*group
;
4314 struct listnode
*node
, *nnode
;
4316 if (peer
->update_if
) {
4317 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4318 && strcmp(peer
->update_if
, ifname
) == 0)
4321 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4322 peer
->update_if
= NULL
;
4325 if (peer
->update_source
) {
4326 sockunion_free(peer
->update_source
);
4327 peer
->update_source
= NULL
;
4330 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4332 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4333 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4334 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4335 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4336 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4338 bgp_session_reset(peer
);
4342 /* peer-group member updates. */
4343 group
= peer
->group
;
4344 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4345 if (peer
->update_if
) {
4346 if (strcmp(peer
->update_if
, ifname
) == 0)
4349 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4350 peer
->update_if
= NULL
;
4353 if (peer
->update_source
) {
4354 sockunion_free(peer
->update_source
);
4355 peer
->update_source
= NULL
;
4358 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
, ifname
);
4360 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4361 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4362 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4363 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4365 bgp_session_reset(peer
);
4370 int peer_update_source_addr_set(struct peer
*peer
, const union sockunion
*su
)
4372 struct peer_group
*group
;
4373 struct listnode
*node
, *nnode
;
4375 if (peer
->update_source
) {
4376 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)
4377 && sockunion_cmp(peer
->update_source
, su
) == 0)
4379 sockunion_free(peer
->update_source
);
4380 peer
->update_source
= NULL
;
4383 if (peer
->update_if
) {
4384 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4385 peer
->update_if
= NULL
;
4388 peer
->update_source
= sockunion_dup(su
);
4390 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4391 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4392 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4393 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4394 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4396 bgp_session_reset(peer
);
4400 /* peer-group member updates. */
4401 group
= peer
->group
;
4402 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4403 if (peer
->update_source
) {
4404 if (sockunion_cmp(peer
->update_source
, su
) == 0)
4406 sockunion_free(peer
->update_source
);
4407 peer
->update_source
= NULL
;
4410 if (peer
->update_if
) {
4411 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4412 peer
->update_if
= NULL
;
4415 peer
->update_source
= sockunion_dup(su
);
4417 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4418 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4419 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4420 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4422 bgp_session_reset(peer
);
4427 int peer_update_source_unset(struct peer
*peer
)
4429 union sockunion
*su
;
4430 struct peer_group
*group
;
4431 struct listnode
*node
, *nnode
;
4433 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
) && !peer
->update_source
4434 && !peer
->update_if
)
4437 if (peer
->update_source
) {
4438 sockunion_free(peer
->update_source
);
4439 peer
->update_source
= NULL
;
4441 if (peer
->update_if
) {
4442 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4443 peer
->update_if
= NULL
;
4446 if (peer_group_active(peer
)) {
4447 group
= peer
->group
;
4449 if (group
->conf
->update_source
) {
4450 su
= sockunion_dup(group
->conf
->update_source
);
4451 peer
->update_source
= su
;
4452 } else if (group
->conf
->update_if
)
4453 peer
->update_if
= XSTRDUP(MTYPE_PEER_UPDATE_SOURCE
,
4454 group
->conf
->update_if
);
4457 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4458 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4459 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4460 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4461 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4463 bgp_session_reset(peer
);
4467 /* peer-group member updates. */
4468 group
= peer
->group
;
4469 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4470 if (!peer
->update_source
&& !peer
->update_if
)
4473 if (peer
->update_source
) {
4474 sockunion_free(peer
->update_source
);
4475 peer
->update_source
= NULL
;
4478 if (peer
->update_if
) {
4479 XFREE(MTYPE_PEER_UPDATE_SOURCE
, peer
->update_if
);
4480 peer
->update_if
= NULL
;
4483 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
4484 peer
->last_reset
= PEER_DOWN_UPDATE_SOURCE_CHANGE
;
4485 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
4486 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
4488 bgp_session_reset(peer
);
4493 int peer_default_originate_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4496 struct peer_group
*group
;
4497 struct listnode
*node
, *nnode
;
4499 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_DEFAULT_ORIGINATE
)
4500 || (rmap
&& !peer
->default_rmap
[afi
][safi
].name
)
4502 && strcmp(rmap
, peer
->default_rmap
[afi
][safi
].name
) != 0)) {
4503 SET_FLAG(peer
->af_flags
[afi
][safi
],
4504 PEER_FLAG_DEFAULT_ORIGINATE
);
4507 if (peer
->default_rmap
[afi
][safi
].name
)
4508 XFREE(MTYPE_ROUTE_MAP_NAME
,
4509 peer
->default_rmap
[afi
][safi
].name
);
4510 peer
->default_rmap
[afi
][safi
].name
=
4511 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4512 peer
->default_rmap
[afi
][safi
].map
=
4513 route_map_lookup_by_name(rmap
);
4517 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4518 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4519 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4520 bgp_default_originate(peer
, afi
, safi
, 0);
4521 bgp_announce_route(peer
, afi
, safi
);
4526 /* peer-group member updates. */
4527 group
= peer
->group
;
4528 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4529 SET_FLAG(peer
->af_flags
[afi
][safi
],
4530 PEER_FLAG_DEFAULT_ORIGINATE
);
4533 if (peer
->default_rmap
[afi
][safi
].name
)
4534 XFREE(MTYPE_ROUTE_MAP_NAME
,
4535 peer
->default_rmap
[afi
][safi
].name
);
4536 peer
->default_rmap
[afi
][safi
].name
=
4537 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4538 peer
->default_rmap
[afi
][safi
].map
=
4539 route_map_lookup_by_name(rmap
);
4542 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4543 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4544 bgp_default_originate(peer
, afi
, safi
, 0);
4545 bgp_announce_route(peer
, afi
, safi
);
4551 int peer_default_originate_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4553 struct peer_group
*group
;
4554 struct listnode
*node
, *nnode
;
4556 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4557 PEER_FLAG_DEFAULT_ORIGINATE
)) {
4558 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4559 PEER_FLAG_DEFAULT_ORIGINATE
);
4561 if (peer
->default_rmap
[afi
][safi
].name
)
4562 XFREE(MTYPE_ROUTE_MAP_NAME
,
4563 peer
->default_rmap
[afi
][safi
].name
);
4564 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4565 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4568 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4569 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4570 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4571 bgp_default_originate(peer
, afi
, safi
, 1);
4572 bgp_announce_route(peer
, afi
, safi
);
4577 /* peer-group member updates. */
4578 group
= peer
->group
;
4579 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4580 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
4581 PEER_FLAG_DEFAULT_ORIGINATE
);
4583 if (peer
->default_rmap
[afi
][safi
].name
)
4584 XFREE(MTYPE_ROUTE_MAP_NAME
,
4585 peer
->default_rmap
[afi
][safi
].name
);
4586 peer
->default_rmap
[afi
][safi
].name
= NULL
;
4587 peer
->default_rmap
[afi
][safi
].map
= NULL
;
4589 if (peer
->status
== Established
&& peer
->afc_nego
[afi
][safi
]) {
4590 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4591 bgp_default_originate(peer
, afi
, safi
, 1);
4592 bgp_announce_route(peer
, afi
, safi
);
4598 int peer_port_set(struct peer
*peer
, uint16_t port
)
4604 int peer_port_unset(struct peer
*peer
)
4606 peer
->port
= BGP_PORT_DEFAULT
;
4611 * Helper function that is called after the name of the policy
4612 * being used by a peer has changed (AF specific). Automatically
4613 * initiates inbound or outbound processing as needed.
4615 static void peer_on_policy_change(struct peer
*peer
, afi_t afi
, safi_t safi
,
4619 update_group_adjust_peer(peer_af_find(peer
, afi
, safi
));
4620 if (peer
->status
== Established
)
4621 bgp_announce_route(peer
, afi
, safi
);
4623 if (peer
->status
!= Established
)
4626 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4627 PEER_FLAG_SOFT_RECONFIG
))
4628 bgp_soft_reconfig_in(peer
, afi
, safi
);
4629 else if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
4630 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
4631 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0, 0);
4636 /* neighbor weight. */
4637 int peer_weight_set(struct peer
*peer
, afi_t afi
, safi_t safi
, uint16_t weight
)
4639 struct peer_group
*group
;
4640 struct listnode
*node
, *nnode
;
4642 if (peer
->weight
[afi
][safi
] != weight
) {
4643 peer
->weight
[afi
][safi
] = weight
;
4644 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4645 peer_on_policy_change(peer
, afi
, safi
, 0);
4648 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4651 /* peer-group member updates. */
4652 group
= peer
->group
;
4653 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4654 if (peer
->weight
[afi
][safi
] != weight
) {
4655 peer
->weight
[afi
][safi
] = weight
;
4656 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
);
4657 peer_on_policy_change(peer
, afi
, safi
, 0);
4663 int peer_weight_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
4665 struct peer_group
*group
;
4666 struct listnode
*node
, *nnode
;
4668 /* not the peer-group itself but a peer in a peer-group */
4669 if (peer_group_active(peer
)) {
4670 group
= peer
->group
;
4672 /* inherit weight from the peer-group */
4673 if (CHECK_FLAG(group
->conf
->af_flags
[afi
][safi
],
4674 PEER_FLAG_WEIGHT
)) {
4675 peer
->weight
[afi
][safi
] =
4676 group
->conf
->weight
[afi
][safi
];
4677 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4678 peer_on_policy_change(peer
, afi
, safi
, 0);
4680 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4681 PEER_FLAG_WEIGHT
)) {
4682 peer
->weight
[afi
][safi
] = 0;
4683 peer_af_flag_unset(peer
, afi
, safi
,
4685 peer_on_policy_change(peer
, afi
, safi
, 0);
4691 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_WEIGHT
)) {
4692 peer
->weight
[afi
][safi
] = 0;
4693 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_WEIGHT
);
4694 peer_on_policy_change(peer
, afi
, safi
, 0);
4697 /* peer-group member updates. */
4698 group
= peer
->group
;
4701 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
4703 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4704 PEER_FLAG_WEIGHT
)) {
4705 peer
->weight
[afi
][safi
] = 0;
4706 peer_af_flag_unset(peer
, afi
, safi
,
4708 peer_on_policy_change(peer
, afi
, safi
,
4717 int peer_timers_set(struct peer
*peer
, uint32_t keepalive
, uint32_t holdtime
)
4719 struct peer_group
*group
;
4720 struct listnode
*node
, *nnode
;
4722 /* keepalive value check. */
4723 if (keepalive
> 65535)
4724 return BGP_ERR_INVALID_VALUE
;
4726 /* Holdtime value check. */
4727 if (holdtime
> 65535)
4728 return BGP_ERR_INVALID_VALUE
;
4730 /* Holdtime value must be either 0 or greater than 3. */
4731 if (holdtime
< 3 && holdtime
!= 0)
4732 return BGP_ERR_INVALID_VALUE
;
4734 /* Set value to the configuration. */
4735 peer
->holdtime
= holdtime
;
4736 peer
->keepalive
= (keepalive
< holdtime
/ 3 ? keepalive
: holdtime
/ 3);
4738 /* First work on real peers with timers */
4739 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4740 SET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4741 UNSET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4743 /* Now work on the peer-group timers */
4744 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4746 /* peer-group member updates. */
4747 group
= peer
->group
;
4748 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4749 /* Skip peers that have their own timers */
4750 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
))
4753 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4754 peer
->holdtime
= group
->conf
->holdtime
;
4755 peer
->keepalive
= group
->conf
->keepalive
;
4762 int peer_timers_unset(struct peer
*peer
)
4764 struct peer_group
*group
;
4765 struct listnode
*node
, *nnode
;
4767 /* First work on real peers vs the peer-group */
4768 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4769 UNSET_FLAG(peer
->config
, PEER_CONFIG_TIMER
);
4770 peer
->keepalive
= 0;
4773 if (peer
->group
&& peer
->group
->conf
->holdtime
) {
4774 SET_FLAG(peer
->config
, PEER_GROUP_CONFIG_TIMER
);
4775 peer
->keepalive
= peer
->group
->conf
->keepalive
;
4776 peer
->holdtime
= peer
->group
->conf
->holdtime
;
4779 /* peer-group member updates. */
4780 group
= peer
->group
;
4781 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4782 if (!CHECK_FLAG(peer
->config
, PEER_CONFIG_TIMER
)) {
4783 UNSET_FLAG(peer
->config
,
4784 PEER_GROUP_CONFIG_TIMER
);
4786 peer
->keepalive
= 0;
4790 UNSET_FLAG(group
->conf
->config
, PEER_GROUP_CONFIG_TIMER
);
4791 group
->conf
->holdtime
= 0;
4792 group
->conf
->keepalive
= 0;
4798 int peer_timers_connect_set(struct peer
*peer
, uint32_t connect
)
4800 struct peer_group
*group
;
4801 struct listnode
*node
, *nnode
;
4803 if (connect
> 65535)
4804 return BGP_ERR_INVALID_VALUE
;
4806 /* Set value to the configuration. */
4807 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4808 peer
->connect
= connect
;
4810 /* Set value to timer setting. */
4811 peer
->v_connect
= connect
;
4813 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4816 /* peer-group member updates. */
4817 group
= peer
->group
;
4818 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4819 SET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4820 peer
->connect
= connect
;
4821 peer
->v_connect
= connect
;
4826 int peer_timers_connect_unset(struct peer
*peer
)
4828 struct peer_group
*group
;
4829 struct listnode
*node
, *nnode
;
4831 /* Clear configuration. */
4832 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4835 /* Set timer setting to default value. */
4836 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4838 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4841 /* peer-group member updates. */
4842 group
= peer
->group
;
4843 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4844 UNSET_FLAG(peer
->config
, PEER_CONFIG_CONNECT
);
4846 peer
->v_connect
= BGP_DEFAULT_CONNECT_RETRY
;
4851 int peer_advertise_interval_set(struct peer
*peer
, uint32_t routeadv
)
4853 struct peer_group
*group
;
4854 struct listnode
*node
, *nnode
;
4857 return BGP_ERR_INVALID_VALUE
;
4859 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4860 peer
->routeadv
= routeadv
;
4861 peer
->v_routeadv
= routeadv
;
4863 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4864 update_group_adjust_peer_afs(peer
);
4865 if (peer
->status
== Established
)
4866 bgp_announce_route_all(peer
);
4870 /* peer-group member updates. */
4871 group
= peer
->group
;
4872 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4873 SET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4874 peer
->routeadv
= routeadv
;
4875 peer
->v_routeadv
= routeadv
;
4876 update_group_adjust_peer_afs(peer
);
4877 if (peer
->status
== Established
)
4878 bgp_announce_route_all(peer
);
4884 int peer_advertise_interval_unset(struct peer
*peer
)
4886 struct peer_group
*group
;
4887 struct listnode
*node
, *nnode
;
4889 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4892 if (peer
->sort
== BGP_PEER_IBGP
)
4893 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4895 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4897 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
4898 update_group_adjust_peer_afs(peer
);
4899 if (peer
->status
== Established
)
4900 bgp_announce_route_all(peer
);
4904 /* peer-group member updates. */
4905 group
= peer
->group
;
4906 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4907 UNSET_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
);
4910 if (peer
->sort
== BGP_PEER_IBGP
)
4911 peer
->v_routeadv
= BGP_DEFAULT_IBGP_ROUTEADV
;
4913 peer
->v_routeadv
= BGP_DEFAULT_EBGP_ROUTEADV
;
4915 update_group_adjust_peer_afs(peer
);
4916 if (peer
->status
== Established
)
4917 bgp_announce_route_all(peer
);
4923 /* neighbor interface */
4924 void peer_interface_set(struct peer
*peer
, const char *str
)
4927 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4928 peer
->ifname
= XSTRDUP(MTYPE_BGP_PEER_IFNAME
, str
);
4931 void peer_interface_unset(struct peer
*peer
)
4934 XFREE(MTYPE_BGP_PEER_IFNAME
, peer
->ifname
);
4935 peer
->ifname
= NULL
;
4939 int peer_allowas_in_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
4940 int allow_num
, int origin
)
4942 struct peer_group
*group
;
4943 struct listnode
*node
, *nnode
;
4946 if (peer
->allowas_in
[afi
][safi
]
4947 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4948 PEER_FLAG_ALLOWAS_IN
)
4949 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4950 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4951 peer
->allowas_in
[afi
][safi
] = 0;
4952 peer_af_flag_unset(peer
, afi
, safi
,
4953 PEER_FLAG_ALLOWAS_IN
);
4954 peer_af_flag_set(peer
, afi
, safi
,
4955 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4956 peer_on_policy_change(peer
, afi
, safi
, 0);
4959 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4962 group
= peer
->group
;
4963 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4964 if (peer
->allowas_in
[afi
][safi
]
4965 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4966 PEER_FLAG_ALLOWAS_IN
)
4967 || !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4968 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4969 peer
->allowas_in
[afi
][safi
] = 0;
4970 peer_af_flag_unset(peer
, afi
, safi
,
4971 PEER_FLAG_ALLOWAS_IN
);
4972 peer_af_flag_set(peer
, afi
, safi
,
4973 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4974 peer_on_policy_change(peer
, afi
, safi
, 0);
4978 if (allow_num
< 1 || allow_num
> 10)
4979 return BGP_ERR_INVALID_VALUE
;
4981 if (peer
->allowas_in
[afi
][safi
] != allow_num
4982 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4983 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4984 peer
->allowas_in
[afi
][safi
] = allow_num
;
4985 peer_af_flag_set(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
4986 peer_af_flag_unset(peer
, afi
, safi
,
4987 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
4988 peer_on_policy_change(peer
, afi
, safi
, 0);
4991 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
4994 group
= peer
->group
;
4995 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
4996 if (peer
->allowas_in
[afi
][safi
] != allow_num
4997 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
4998 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
4999 peer
->allowas_in
[afi
][safi
] = allow_num
;
5000 peer_af_flag_set(peer
, afi
, safi
,
5001 PEER_FLAG_ALLOWAS_IN
);
5002 peer_af_flag_unset(peer
, afi
, safi
,
5003 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5004 peer_on_policy_change(peer
, afi
, safi
, 0);
5012 int peer_allowas_in_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5014 struct peer_group
*group
;
5015 struct peer
*tmp_peer
;
5016 struct listnode
*node
, *nnode
;
5018 /* If this is a peer-group we must first clear the flags for all of the
5019 * peer-group members
5021 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5022 group
= peer
->group
;
5023 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, tmp_peer
)) {
5024 if (CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
5025 PEER_FLAG_ALLOWAS_IN
)
5026 || CHECK_FLAG(tmp_peer
->af_flags
[afi
][safi
],
5027 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5028 tmp_peer
->allowas_in
[afi
][safi
] = 0;
5029 peer_af_flag_unset(tmp_peer
, afi
, safi
,
5030 PEER_FLAG_ALLOWAS_IN
);
5031 peer_af_flag_unset(tmp_peer
, afi
, safi
,
5032 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5033 peer_on_policy_change(tmp_peer
, afi
, safi
, 0);
5038 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN
)
5039 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
5040 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
5041 peer
->allowas_in
[afi
][safi
] = 0;
5042 peer_af_flag_unset(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
);
5043 peer_af_flag_unset(peer
, afi
, safi
,
5044 PEER_FLAG_ALLOWAS_IN_ORIGIN
);
5045 peer_on_policy_change(peer
, afi
, safi
, 0);
5051 int peer_local_as_set(struct peer
*peer
, as_t as
, int no_prepend
,
5054 struct bgp
*bgp
= peer
->bgp
;
5055 struct peer_group
*group
;
5056 struct listnode
*node
, *nnode
;
5058 if (peer_sort(peer
) != BGP_PEER_EBGP
5059 && peer_sort(peer
) != BGP_PEER_INTERNAL
)
5060 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP
;
5063 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS
;
5066 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS
;
5068 if (peer
->change_local_as
== as
5069 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
5071 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
5073 && ((CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
5075 || (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
5079 peer
->change_local_as
= as
;
5081 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5083 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5086 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5088 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5090 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5091 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5092 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5093 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5094 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5096 bgp_session_reset(peer
);
5100 group
= peer
->group
;
5101 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5102 peer
->change_local_as
= as
;
5104 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5106 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5109 SET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5111 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5113 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5114 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5115 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5116 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5118 BGP_EVENT_ADD(peer
, BGP_Stop
);
5124 int peer_local_as_unset(struct peer
*peer
)
5126 struct peer_group
*group
;
5127 struct listnode
*node
, *nnode
;
5129 if (!peer
->change_local_as
)
5132 peer
->change_local_as
= 0;
5133 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5134 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5136 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5137 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5138 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5139 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5140 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5142 BGP_EVENT_ADD(peer
, BGP_Stop
);
5147 group
= peer
->group
;
5148 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5149 peer
->change_local_as
= 0;
5150 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
);
5151 UNSET_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
);
5153 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
)) {
5154 peer
->last_reset
= PEER_DOWN_LOCAL_AS_CHANGE
;
5155 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5156 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5158 bgp_session_reset(peer
);
5163 /* Set password for authenticating with the peer. */
5164 int peer_password_set(struct peer
*peer
, const char *password
)
5166 struct listnode
*nn
, *nnode
;
5167 int len
= password
? strlen(password
) : 0;
5168 int ret
= BGP_SUCCESS
;
5170 if ((len
< PEER_PASSWORD_MINLEN
) || (len
> PEER_PASSWORD_MAXLEN
))
5171 return BGP_ERR_INVALID_VALUE
;
5173 if (peer
->password
&& strcmp(peer
->password
, password
) == 0
5174 && !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5178 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5180 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5182 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5183 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5184 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5185 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5187 bgp_session_reset(peer
);
5189 if (BGP_PEER_SU_UNSPEC(peer
))
5192 return (bgp_md5_set(peer
) >= 0) ? BGP_SUCCESS
5193 : BGP_ERR_TCPSIG_FAILED
;
5196 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5197 if (peer
->password
&& strcmp(peer
->password
, password
) == 0)
5201 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5203 peer
->password
= XSTRDUP(MTYPE_PEER_PASSWORD
, password
);
5205 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5206 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5207 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5209 bgp_session_reset(peer
);
5211 if (!BGP_PEER_SU_UNSPEC(peer
)) {
5212 if (bgp_md5_set(peer
) < 0)
5213 ret
= BGP_ERR_TCPSIG_FAILED
;
5220 int peer_password_unset(struct peer
*peer
)
5222 struct listnode
*nn
, *nnode
;
5224 if (!peer
->password
&& !CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
5227 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5228 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5229 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5230 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5232 bgp_session_reset(peer
);
5235 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5237 peer
->password
= NULL
;
5239 if (!BGP_PEER_SU_UNSPEC(peer
))
5240 bgp_md5_unset(peer
);
5245 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5246 peer
->password
= NULL
;
5248 for (ALL_LIST_ELEMENTS(peer
->group
->peer
, nn
, nnode
, peer
)) {
5249 if (!peer
->password
)
5252 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
5253 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
5254 BGP_NOTIFY_CEASE_CONFIG_CHANGE
);
5256 bgp_session_reset(peer
);
5258 XFREE(MTYPE_PEER_PASSWORD
, peer
->password
);
5259 peer
->password
= NULL
;
5261 if (!BGP_PEER_SU_UNSPEC(peer
))
5262 bgp_md5_unset(peer
);
5269 /* Set distribute list to the peer. */
5270 int peer_distribute_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5273 struct bgp_filter
*filter
;
5274 struct peer_group
*group
;
5275 struct listnode
*node
, *nnode
;
5277 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5278 return BGP_ERR_INVALID_VALUE
;
5280 filter
= &peer
->filter
[afi
][safi
];
5282 if (filter
->plist
[direct
].name
)
5283 return BGP_ERR_PEER_FILTER_CONFLICT
;
5285 if (filter
->dlist
[direct
].name
)
5286 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5287 filter
->dlist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5288 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5290 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5291 peer_on_policy_change(peer
, afi
, safi
,
5292 (direct
== FILTER_OUT
) ? 1 : 0);
5296 group
= peer
->group
;
5297 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5298 filter
= &peer
->filter
[afi
][safi
];
5300 if (filter
->dlist
[direct
].name
)
5301 XFREE(MTYPE_BGP_FILTER_NAME
,
5302 filter
->dlist
[direct
].name
);
5303 filter
->dlist
[direct
].name
=
5304 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5305 filter
->dlist
[direct
].alist
= access_list_lookup(afi
, name
);
5306 peer_on_policy_change(peer
, afi
, safi
,
5307 (direct
== FILTER_OUT
) ? 1 : 0);
5313 int peer_distribute_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5315 struct bgp_filter
*filter
;
5316 struct bgp_filter
*gfilter
;
5317 struct peer_group
*group
;
5318 struct listnode
*node
, *nnode
;
5320 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5321 return BGP_ERR_INVALID_VALUE
;
5323 filter
= &peer
->filter
[afi
][safi
];
5325 /* apply peer-group filter */
5326 if (peer_group_active(peer
)) {
5327 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5329 if (gfilter
->dlist
[direct
].name
) {
5330 if (filter
->dlist
[direct
].name
)
5331 XFREE(MTYPE_BGP_FILTER_NAME
,
5332 filter
->dlist
[direct
].name
);
5333 filter
->dlist
[direct
].name
=
5334 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5335 gfilter
->dlist
[direct
].name
);
5336 filter
->dlist
[direct
].alist
=
5337 gfilter
->dlist
[direct
].alist
;
5338 peer_on_policy_change(peer
, afi
, safi
,
5339 (direct
== FILTER_OUT
) ? 1 : 0);
5344 if (filter
->dlist
[direct
].name
)
5345 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->dlist
[direct
].name
);
5346 filter
->dlist
[direct
].name
= NULL
;
5347 filter
->dlist
[direct
].alist
= NULL
;
5349 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5350 peer_on_policy_change(peer
, afi
, safi
,
5351 (direct
== FILTER_OUT
) ? 1 : 0);
5355 group
= peer
->group
;
5356 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5357 filter
= &peer
->filter
[afi
][safi
];
5359 if (filter
->dlist
[direct
].name
)
5360 XFREE(MTYPE_BGP_FILTER_NAME
,
5361 filter
->dlist
[direct
].name
);
5362 filter
->dlist
[direct
].name
= NULL
;
5363 filter
->dlist
[direct
].alist
= NULL
;
5364 peer_on_policy_change(peer
, afi
, safi
,
5365 (direct
== FILTER_OUT
) ? 1 : 0);
5371 /* Update distribute list. */
5372 static void peer_distribute_update(struct access_list
*access
)
5377 struct listnode
*mnode
, *mnnode
;
5378 struct listnode
*node
, *nnode
;
5381 struct peer_group
*group
;
5382 struct bgp_filter
*filter
;
5384 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5386 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5387 access
->name
, 0, 0);
5388 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5389 FOREACH_AFI_SAFI (afi
, safi
) {
5390 filter
= &peer
->filter
[afi
][safi
];
5392 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5394 if (filter
->dlist
[direct
].name
)
5395 filter
->dlist
[direct
]
5396 .alist
= access_list_lookup(
5398 filter
->dlist
[direct
]
5401 filter
->dlist
[direct
].alist
=
5406 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5407 FOREACH_AFI_SAFI (afi
, safi
) {
5408 filter
= &group
->conf
->filter
[afi
][safi
];
5410 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5412 if (filter
->dlist
[direct
].name
)
5413 filter
->dlist
[direct
]
5414 .alist
= access_list_lookup(
5416 filter
->dlist
[direct
]
5419 filter
->dlist
[direct
].alist
=
5425 vnc_prefix_list_update(bgp
);
5430 /* Set prefix list to the peer. */
5431 int peer_prefix_list_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5434 struct bgp_filter
*filter
;
5435 struct peer_group
*group
;
5436 struct listnode
*node
, *nnode
;
5438 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5439 return BGP_ERR_INVALID_VALUE
;
5441 filter
= &peer
->filter
[afi
][safi
];
5443 if (filter
->dlist
[direct
].name
)
5444 return BGP_ERR_PEER_FILTER_CONFLICT
;
5446 if (filter
->plist
[direct
].name
)
5447 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5448 filter
->plist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5449 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5451 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5452 peer_on_policy_change(peer
, afi
, safi
,
5453 (direct
== FILTER_OUT
) ? 1 : 0);
5457 group
= peer
->group
;
5458 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5459 filter
= &peer
->filter
[afi
][safi
];
5461 if (filter
->plist
[direct
].name
)
5462 XFREE(MTYPE_BGP_FILTER_NAME
,
5463 filter
->plist
[direct
].name
);
5464 filter
->plist
[direct
].name
=
5465 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5466 filter
->plist
[direct
].plist
= prefix_list_lookup(afi
, name
);
5467 peer_on_policy_change(peer
, afi
, safi
,
5468 (direct
== FILTER_OUT
) ? 1 : 0);
5473 int peer_prefix_list_unset(struct peer
*peer
, afi_t afi
, safi_t safi
,
5476 struct bgp_filter
*filter
;
5477 struct bgp_filter
*gfilter
;
5478 struct peer_group
*group
;
5479 struct listnode
*node
, *nnode
;
5481 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5482 return BGP_ERR_INVALID_VALUE
;
5484 filter
= &peer
->filter
[afi
][safi
];
5486 /* apply peer-group filter */
5487 if (peer_group_active(peer
)) {
5488 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5490 if (gfilter
->plist
[direct
].name
) {
5491 if (filter
->plist
[direct
].name
)
5492 XFREE(MTYPE_BGP_FILTER_NAME
,
5493 filter
->plist
[direct
].name
);
5494 filter
->plist
[direct
].name
=
5495 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5496 gfilter
->plist
[direct
].name
);
5497 filter
->plist
[direct
].plist
=
5498 gfilter
->plist
[direct
].plist
;
5499 peer_on_policy_change(peer
, afi
, safi
,
5500 (direct
== FILTER_OUT
) ? 1 : 0);
5505 if (filter
->plist
[direct
].name
)
5506 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->plist
[direct
].name
);
5507 filter
->plist
[direct
].name
= NULL
;
5508 filter
->plist
[direct
].plist
= NULL
;
5510 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5511 peer_on_policy_change(peer
, afi
, safi
,
5512 (direct
== FILTER_OUT
) ? 1 : 0);
5516 group
= peer
->group
;
5517 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5518 filter
= &peer
->filter
[afi
][safi
];
5520 if (filter
->plist
[direct
].name
)
5521 XFREE(MTYPE_BGP_FILTER_NAME
,
5522 filter
->plist
[direct
].name
);
5523 filter
->plist
[direct
].name
= NULL
;
5524 filter
->plist
[direct
].plist
= NULL
;
5525 peer_on_policy_change(peer
, afi
, safi
,
5526 (direct
== FILTER_OUT
) ? 1 : 0);
5532 /* Update prefix-list list. */
5533 static void peer_prefix_list_update(struct prefix_list
*plist
)
5535 struct listnode
*mnode
, *mnnode
;
5536 struct listnode
*node
, *nnode
;
5539 struct peer_group
*group
;
5540 struct bgp_filter
*filter
;
5545 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5548 * Update the prefix-list on update groups.
5550 update_group_policy_update(
5551 bgp
, BGP_POLICY_PREFIX_LIST
,
5552 plist
? prefix_list_name(plist
) : NULL
, 0, 0);
5554 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5555 FOREACH_AFI_SAFI (afi
, safi
) {
5556 filter
= &peer
->filter
[afi
][safi
];
5558 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5560 if (filter
->plist
[direct
].name
)
5561 filter
->plist
[direct
]
5562 .plist
= prefix_list_lookup(
5564 filter
->plist
[direct
]
5567 filter
->plist
[direct
].plist
=
5572 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5573 FOREACH_AFI_SAFI (afi
, safi
) {
5574 filter
= &group
->conf
->filter
[afi
][safi
];
5576 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5578 if (filter
->plist
[direct
].name
)
5579 filter
->plist
[direct
]
5580 .plist
= prefix_list_lookup(
5582 filter
->plist
[direct
]
5585 filter
->plist
[direct
].plist
=
5593 int peer_aslist_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5596 struct bgp_filter
*filter
;
5597 struct peer_group
*group
;
5598 struct listnode
*node
, *nnode
;
5600 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5601 return BGP_ERR_INVALID_VALUE
;
5603 filter
= &peer
->filter
[afi
][safi
];
5605 if (filter
->aslist
[direct
].name
)
5606 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5607 filter
->aslist
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5608 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5610 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5611 peer_on_policy_change(peer
, afi
, safi
,
5612 (direct
== FILTER_OUT
) ? 1 : 0);
5616 group
= peer
->group
;
5617 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5618 filter
= &peer
->filter
[afi
][safi
];
5620 if (filter
->aslist
[direct
].name
)
5621 XFREE(MTYPE_BGP_FILTER_NAME
,
5622 filter
->aslist
[direct
].name
);
5623 filter
->aslist
[direct
].name
=
5624 XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5625 filter
->aslist
[direct
].aslist
= as_list_lookup(name
);
5626 peer_on_policy_change(peer
, afi
, safi
,
5627 (direct
== FILTER_OUT
) ? 1 : 0);
5632 int peer_aslist_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5634 struct bgp_filter
*filter
;
5635 struct bgp_filter
*gfilter
;
5636 struct peer_group
*group
;
5637 struct listnode
*node
, *nnode
;
5639 if (direct
!= FILTER_IN
&& direct
!= FILTER_OUT
)
5640 return BGP_ERR_INVALID_VALUE
;
5642 filter
= &peer
->filter
[afi
][safi
];
5644 /* apply peer-group filter */
5645 if (peer_group_active(peer
)) {
5646 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5648 if (gfilter
->aslist
[direct
].name
) {
5649 if (filter
->aslist
[direct
].name
)
5650 XFREE(MTYPE_BGP_FILTER_NAME
,
5651 filter
->aslist
[direct
].name
);
5652 filter
->aslist
[direct
].name
=
5653 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5654 gfilter
->aslist
[direct
].name
);
5655 filter
->aslist
[direct
].aslist
=
5656 gfilter
->aslist
[direct
].aslist
;
5657 peer_on_policy_change(peer
, afi
, safi
,
5658 (direct
== FILTER_OUT
) ? 1 : 0);
5663 if (filter
->aslist
[direct
].name
)
5664 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->aslist
[direct
].name
);
5665 filter
->aslist
[direct
].name
= NULL
;
5666 filter
->aslist
[direct
].aslist
= NULL
;
5668 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5669 peer_on_policy_change(peer
, afi
, safi
,
5670 (direct
== FILTER_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
->aslist
[direct
].name
)
5679 XFREE(MTYPE_BGP_FILTER_NAME
,
5680 filter
->aslist
[direct
].name
);
5681 filter
->aslist
[direct
].name
= NULL
;
5682 filter
->aslist
[direct
].aslist
= NULL
;
5683 peer_on_policy_change(peer
, afi
, safi
,
5684 (direct
== FILTER_OUT
) ? 1 : 0);
5690 static void peer_aslist_update(const char *aslist_name
)
5695 struct listnode
*mnode
, *mnnode
;
5696 struct listnode
*node
, *nnode
;
5699 struct peer_group
*group
;
5700 struct bgp_filter
*filter
;
5702 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
5703 update_group_policy_update(bgp
, BGP_POLICY_FILTER_LIST
,
5706 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
5707 FOREACH_AFI_SAFI (afi
, safi
) {
5708 filter
= &peer
->filter
[afi
][safi
];
5710 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5712 if (filter
->aslist
[direct
].name
)
5713 filter
->aslist
[direct
]
5714 .aslist
= as_list_lookup(
5715 filter
->aslist
[direct
]
5718 filter
->aslist
[direct
].aslist
=
5723 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
5724 FOREACH_AFI_SAFI (afi
, safi
) {
5725 filter
= &group
->conf
->filter
[afi
][safi
];
5727 for (direct
= FILTER_IN
; direct
< FILTER_MAX
;
5729 if (filter
->aslist
[direct
].name
)
5730 filter
->aslist
[direct
]
5731 .aslist
= as_list_lookup(
5732 filter
->aslist
[direct
]
5735 filter
->aslist
[direct
].aslist
=
5743 static void peer_aslist_add(char *aslist_name
)
5745 peer_aslist_update(aslist_name
);
5746 route_map_notify_dependencies((char *)aslist_name
,
5747 RMAP_EVENT_ASLIST_ADDED
);
5750 static void peer_aslist_del(const char *aslist_name
)
5752 peer_aslist_update(aslist_name
);
5753 route_map_notify_dependencies(aslist_name
, RMAP_EVENT_ASLIST_DELETED
);
5757 int peer_route_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
,
5760 struct bgp_filter
*filter
;
5761 struct peer_group
*group
;
5762 struct listnode
*node
, *nnode
;
5764 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5765 return BGP_ERR_INVALID_VALUE
;
5767 filter
= &peer
->filter
[afi
][safi
];
5769 if (filter
->map
[direct
].name
)
5770 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5772 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5773 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5775 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5776 peer_on_policy_change(peer
, afi
, safi
,
5777 (direct
== RMAP_OUT
) ? 1 : 0);
5781 group
= peer
->group
;
5782 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5783 filter
= &peer
->filter
[afi
][safi
];
5785 if (filter
->map
[direct
].name
)
5786 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5787 filter
->map
[direct
].name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5788 filter
->map
[direct
].map
= route_map_lookup_by_name(name
);
5789 peer_on_policy_change(peer
, afi
, safi
,
5790 (direct
== RMAP_OUT
) ? 1 : 0);
5795 /* Unset route-map from the peer. */
5796 int peer_route_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
, int direct
)
5798 struct bgp_filter
*filter
;
5799 struct bgp_filter
*gfilter
;
5800 struct peer_group
*group
;
5801 struct listnode
*node
, *nnode
;
5803 if (direct
!= RMAP_IN
&& direct
!= RMAP_OUT
)
5804 return BGP_ERR_INVALID_VALUE
;
5806 filter
= &peer
->filter
[afi
][safi
];
5808 /* apply peer-group filter */
5809 if (peer_group_active(peer
)) {
5810 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
5812 if (gfilter
->map
[direct
].name
) {
5813 if (filter
->map
[direct
].name
)
5814 XFREE(MTYPE_BGP_FILTER_NAME
,
5815 filter
->map
[direct
].name
);
5816 filter
->map
[direct
].name
=
5817 XSTRDUP(MTYPE_BGP_FILTER_NAME
,
5818 gfilter
->map
[direct
].name
);
5819 filter
->map
[direct
].map
= gfilter
->map
[direct
].map
;
5820 peer_on_policy_change(peer
, afi
, safi
,
5821 (direct
== RMAP_OUT
) ? 1 : 0);
5826 if (filter
->map
[direct
].name
)
5827 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5828 filter
->map
[direct
].name
= NULL
;
5829 filter
->map
[direct
].map
= NULL
;
5831 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5832 peer_on_policy_change(peer
, afi
, safi
,
5833 (direct
== RMAP_OUT
) ? 1 : 0);
5837 group
= peer
->group
;
5838 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5839 filter
= &peer
->filter
[afi
][safi
];
5841 if (filter
->map
[direct
].name
)
5842 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->map
[direct
].name
);
5843 filter
->map
[direct
].name
= NULL
;
5844 filter
->map
[direct
].map
= NULL
;
5845 peer_on_policy_change(peer
, afi
, safi
,
5846 (direct
== RMAP_OUT
) ? 1 : 0);
5851 /* Set unsuppress-map to the peer. */
5852 int peer_unsuppress_map_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5855 struct bgp_filter
*filter
;
5856 struct peer_group
*group
;
5857 struct listnode
*node
, *nnode
;
5859 filter
= &peer
->filter
[afi
][safi
];
5861 if (filter
->usmap
.name
)
5862 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5864 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5865 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5867 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5868 peer_on_policy_change(peer
, afi
, safi
, 1);
5872 group
= peer
->group
;
5873 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5874 filter
= &peer
->filter
[afi
][safi
];
5876 if (filter
->usmap
.name
)
5877 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5878 filter
->usmap
.name
= XSTRDUP(MTYPE_BGP_FILTER_NAME
, name
);
5879 filter
->usmap
.map
= route_map_lookup_by_name(name
);
5880 peer_on_policy_change(peer
, afi
, safi
, 1);
5885 /* Unset route-map from the peer. */
5886 int peer_unsuppress_map_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5888 struct bgp_filter
*filter
;
5889 struct peer_group
*group
;
5890 struct listnode
*node
, *nnode
;
5892 filter
= &peer
->filter
[afi
][safi
];
5894 if (filter
->usmap
.name
)
5895 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5896 filter
->usmap
.name
= NULL
;
5897 filter
->usmap
.map
= NULL
;
5899 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5900 peer_on_policy_change(peer
, afi
, safi
, 1);
5904 group
= peer
->group
;
5905 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5906 filter
= &peer
->filter
[afi
][safi
];
5908 if (filter
->usmap
.name
)
5909 XFREE(MTYPE_BGP_FILTER_NAME
, filter
->usmap
.name
);
5910 filter
->usmap
.name
= NULL
;
5911 filter
->usmap
.map
= NULL
;
5912 peer_on_policy_change(peer
, afi
, safi
, 1);
5917 int peer_maximum_prefix_set(struct peer
*peer
, afi_t afi
, safi_t safi
,
5918 uint32_t max
, uint8_t threshold
, int warning
,
5921 struct peer_group
*group
;
5922 struct listnode
*node
, *nnode
;
5924 SET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5925 peer
->pmax
[afi
][safi
] = max
;
5926 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5927 peer
->pmax_restart
[afi
][safi
] = restart
;
5929 SET_FLAG(peer
->af_flags
[afi
][safi
],
5930 PEER_FLAG_MAX_PREFIX_WARNING
);
5932 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5933 PEER_FLAG_MAX_PREFIX_WARNING
);
5935 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
5936 group
= peer
->group
;
5937 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
5938 SET_FLAG(peer
->af_flags
[afi
][safi
],
5939 PEER_FLAG_MAX_PREFIX
);
5940 peer
->pmax
[afi
][safi
] = max
;
5941 peer
->pmax_threshold
[afi
][safi
] = threshold
;
5942 peer
->pmax_restart
[afi
][safi
] = restart
;
5944 SET_FLAG(peer
->af_flags
[afi
][safi
],
5945 PEER_FLAG_MAX_PREFIX_WARNING
);
5947 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5948 PEER_FLAG_MAX_PREFIX_WARNING
);
5950 if ((peer
->status
== Established
)
5951 && (peer
->afc
[afi
][safi
]))
5952 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5955 if ((peer
->status
== Established
) && (peer
->afc
[afi
][safi
]))
5956 bgp_maximum_prefix_overflow(peer
, afi
, safi
, 1);
5962 int peer_maximum_prefix_unset(struct peer
*peer
, afi_t afi
, safi_t safi
)
5964 struct peer_group
*group
;
5965 struct listnode
*node
, *nnode
;
5967 /* apply peer-group config */
5968 if (peer_group_active(peer
)) {
5969 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5970 PEER_FLAG_MAX_PREFIX
))
5971 SET_FLAG(peer
->af_flags
[afi
][safi
],
5972 PEER_FLAG_MAX_PREFIX
);
5974 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5975 PEER_FLAG_MAX_PREFIX
);
5977 if (CHECK_FLAG(peer
->group
->conf
->af_flags
[afi
][safi
],
5978 PEER_FLAG_MAX_PREFIX_WARNING
))
5979 SET_FLAG(peer
->af_flags
[afi
][safi
],
5980 PEER_FLAG_MAX_PREFIX_WARNING
);
5982 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
5983 PEER_FLAG_MAX_PREFIX_WARNING
);
5985 peer
->pmax
[afi
][safi
] = peer
->group
->conf
->pmax
[afi
][safi
];
5986 peer
->pmax_threshold
[afi
][safi
] =
5987 peer
->group
->conf
->pmax_threshold
[afi
][safi
];
5988 peer
->pmax_restart
[afi
][safi
] =
5989 peer
->group
->conf
->pmax_restart
[afi
][safi
];
5993 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
5994 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX_WARNING
);
5995 peer
->pmax
[afi
][safi
] = 0;
5996 peer
->pmax_threshold
[afi
][safi
] = 0;
5997 peer
->pmax_restart
[afi
][safi
] = 0;
5999 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
6002 group
= peer
->group
;
6003 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6004 UNSET_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
);
6005 UNSET_FLAG(peer
->af_flags
[afi
][safi
],
6006 PEER_FLAG_MAX_PREFIX_WARNING
);
6007 peer
->pmax
[afi
][safi
] = 0;
6008 peer
->pmax_threshold
[afi
][safi
] = 0;
6009 peer
->pmax_restart
[afi
][safi
] = 0;
6014 int is_ebgp_multihop_configured(struct peer
*peer
)
6016 struct peer_group
*group
;
6017 struct listnode
*node
, *nnode
;
6020 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6021 group
= peer
->group
;
6022 if ((peer_sort(peer
) != BGP_PEER_IBGP
)
6023 && (group
->conf
->ttl
!= 1))
6026 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer1
)) {
6027 if ((peer_sort(peer1
) != BGP_PEER_IBGP
)
6028 && (peer1
->ttl
!= 1))
6032 if ((peer_sort(peer
) != BGP_PEER_IBGP
) && (peer
->ttl
!= 1))
6038 /* Set # of hops between us and BGP peer. */
6039 int peer_ttl_security_hops_set(struct peer
*peer
, int gtsm_hops
)
6041 struct peer_group
*group
;
6042 struct listnode
*node
, *nnode
;
6045 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6046 gtsm_hops
, peer
->host
);
6048 /* We cannot configure ttl-security hops when ebgp-multihop is already
6049 set. For non peer-groups, the check is simple. For peer-groups,
6051 slightly messy, because we need to check both the peer-group
6053 and all peer-group members for any trace of ebgp-multihop
6055 before actually applying the ttl-security rules. Cisco really made a
6056 mess of this configuration parameter, and OpenBGPD got it right.
6059 if ((peer
->gtsm_hops
== 0) && (peer
->sort
!= BGP_PEER_IBGP
)) {
6060 if (is_ebgp_multihop_configured(peer
))
6061 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK
;
6063 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6064 peer
->gtsm_hops
= gtsm_hops
;
6066 /* Calling ebgp multihop also resets the session.
6067 * On restart, NHT will get setup correctly as will the
6068 * min & max ttls on the socket. The return value is
6071 ret
= peer_ebgp_multihop_set(peer
, MAXTTL
);
6076 group
= peer
->group
;
6077 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6079 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6081 /* Calling ebgp multihop also resets the
6083 * On restart, NHT will get setup correctly as
6085 * min & max ttls on the socket. The return
6089 peer_ebgp_multihop_set(peer
, MAXTTL
);
6093 /* Post the first gtsm setup or if its ibgp, maxttl setting
6095 * necessary, just set the minttl.
6097 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6098 peer
->gtsm_hops
= gtsm_hops
;
6101 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6102 MAXTTL
+ 1 - gtsm_hops
);
6103 if ((peer
->status
< Established
) && peer
->doppelganger
6104 && (peer
->doppelganger
->fd
>= 0))
6105 sockopt_minttl(peer
->su
.sa
.sa_family
,
6106 peer
->doppelganger
->fd
,
6107 MAXTTL
+ 1 - gtsm_hops
);
6109 group
= peer
->group
;
6110 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
,
6112 peer
->gtsm_hops
= group
->conf
->gtsm_hops
;
6114 /* Change setting of existing peer
6115 * established then change value (may break
6117 * not established yet (teardown session and
6119 * no session then do nothing (will get
6120 * handled by next connection)
6122 if (peer
->fd
>= 0 && peer
->gtsm_hops
!= 0)
6124 peer
->su
.sa
.sa_family
, peer
->fd
,
6125 MAXTTL
+ 1 - peer
->gtsm_hops
);
6126 if ((peer
->status
< Established
)
6127 && peer
->doppelganger
6128 && (peer
->doppelganger
->fd
>= 0))
6129 sockopt_minttl(peer
->su
.sa
.sa_family
,
6130 peer
->doppelganger
->fd
,
6131 MAXTTL
+ 1 - gtsm_hops
);
6139 int peer_ttl_security_hops_unset(struct peer
*peer
)
6141 struct peer_group
*group
;
6142 struct listnode
*node
, *nnode
;
6145 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6148 /* if a peer-group member, then reset to peer-group default rather than
6150 if (peer_group_active(peer
))
6151 peer
->gtsm_hops
= peer
->group
->conf
->gtsm_hops
;
6153 peer
->gtsm_hops
= 0;
6155 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6156 /* Invoking ebgp_multihop_set will set the TTL back to the
6158 * value as well as restting the NHT and such. The session is
6161 if (peer
->sort
== BGP_PEER_EBGP
)
6162 ret
= peer_ebgp_multihop_unset(peer
);
6165 sockopt_minttl(peer
->su
.sa
.sa_family
, peer
->fd
,
6168 if ((peer
->status
< Established
) && peer
->doppelganger
6169 && (peer
->doppelganger
->fd
>= 0))
6170 sockopt_minttl(peer
->su
.sa
.sa_family
,
6171 peer
->doppelganger
->fd
, 0);
6174 group
= peer
->group
;
6175 for (ALL_LIST_ELEMENTS(group
->peer
, node
, nnode
, peer
)) {
6176 peer
->gtsm_hops
= 0;
6177 if (peer
->sort
== BGP_PEER_EBGP
)
6178 ret
= peer_ebgp_multihop_unset(peer
);
6181 sockopt_minttl(peer
->su
.sa
.sa_family
,
6184 if ((peer
->status
< Established
)
6185 && peer
->doppelganger
6186 && (peer
->doppelganger
->fd
>= 0))
6187 sockopt_minttl(peer
->su
.sa
.sa_family
,
6188 peer
->doppelganger
->fd
,
6198 * If peer clear is invoked in a loop for all peers on the BGP instance,
6199 * it may end up freeing the doppelganger, and if this was the next node
6200 * to the current node, we would end up accessing the freed next node.
6201 * Pass along additional parameter which can be updated if next node
6202 * is freed; only required when walking the peer list on BGP instance.
6204 int peer_clear(struct peer
*peer
, struct listnode
**nnode
)
6206 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6207 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
)) {
6208 UNSET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
6209 if (peer
->t_pmax_restart
) {
6210 BGP_TIMER_OFF(peer
->t_pmax_restart
);
6211 if (bgp_debug_neighbor_events(peer
))
6213 "%s Maximum-prefix restart timer canceled",
6216 BGP_EVENT_ADD(peer
, BGP_Start
);
6220 peer
->v_start
= BGP_INIT_START_TIMER
;
6221 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer
->status
))
6222 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
6223 BGP_NOTIFY_CEASE_ADMIN_RESET
);
6225 bgp_session_reset_safe(peer
, nnode
);
6230 int peer_clear_soft(struct peer
*peer
, afi_t afi
, safi_t safi
,
6231 enum bgp_clear_type stype
)
6233 struct peer_af
*paf
;
6235 if (peer
->status
!= Established
)
6238 if (!peer
->afc
[afi
][safi
])
6239 return BGP_ERR_AF_UNCONFIGURED
;
6241 peer
->rtt
= sockopt_tcp_rtt(peer
->fd
);
6243 if (stype
== BGP_CLEAR_SOFT_OUT
|| stype
== BGP_CLEAR_SOFT_BOTH
) {
6244 /* Clear the "neighbor x.x.x.x default-originate" flag */
6245 paf
= peer_af_find(peer
, afi
, safi
);
6246 if (paf
&& paf
->subgroup
6247 && CHECK_FLAG(paf
->subgroup
->sflags
,
6248 SUBGRP_STATUS_DEFAULT_ORIGINATE
))
6249 UNSET_FLAG(paf
->subgroup
->sflags
,
6250 SUBGRP_STATUS_DEFAULT_ORIGINATE
);
6252 bgp_announce_route(peer
, afi
, safi
);
6255 if (stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6256 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6257 PEER_CAP_ORF_PREFIX_SM_ADV
)
6258 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6259 PEER_CAP_ORF_PREFIX_RM_RCV
)
6260 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6261 PEER_CAP_ORF_PREFIX_RM_OLD_RCV
))) {
6262 struct bgp_filter
*filter
= &peer
->filter
[afi
][safi
];
6263 uint8_t prefix_type
;
6265 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
6266 PEER_CAP_ORF_PREFIX_RM_RCV
))
6267 prefix_type
= ORF_TYPE_PREFIX
;
6269 prefix_type
= ORF_TYPE_PREFIX_OLD
;
6271 if (filter
->plist
[FILTER_IN
].plist
) {
6272 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6273 PEER_STATUS_ORF_PREFIX_SEND
))
6274 bgp_route_refresh_send(
6275 peer
, afi
, safi
, prefix_type
,
6277 bgp_route_refresh_send(peer
, afi
, safi
,
6279 REFRESH_IMMEDIATE
, 0);
6281 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
6282 PEER_STATUS_ORF_PREFIX_SEND
))
6283 bgp_route_refresh_send(
6284 peer
, afi
, safi
, prefix_type
,
6285 REFRESH_IMMEDIATE
, 1);
6287 bgp_route_refresh_send(peer
, afi
, safi
,
6294 if (stype
== BGP_CLEAR_SOFT_IN
|| stype
== BGP_CLEAR_SOFT_BOTH
6295 || stype
== BGP_CLEAR_SOFT_IN_ORF_PREFIX
) {
6296 /* If neighbor has soft reconfiguration inbound flag.
6297 Use Adj-RIB-In database. */
6298 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
6299 PEER_FLAG_SOFT_RECONFIG
))
6300 bgp_soft_reconfig_in(peer
, afi
, safi
);
6302 /* If neighbor has route refresh capability, send route
6304 message to the peer. */
6305 if (CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
)
6306 || CHECK_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
))
6307 bgp_route_refresh_send(peer
, afi
, safi
, 0, 0,
6310 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED
;
6316 /* Display peer uptime.*/
6317 char *peer_uptime(time_t uptime2
, char *buf
, size_t len
, uint8_t use_json
,
6320 time_t uptime1
, epoch_tbuf
;
6323 /* Check buffer length. */
6324 if (len
< BGP_UPTIME_LEN
) {
6326 zlog_warn("peer_uptime (): buffer shortage %lu",
6327 (unsigned long)len
);
6328 /* XXX: should return status instead of buf... */
6329 snprintf(buf
, len
, "<error> ");
6334 /* If there is no connection has been done before print `never'. */
6337 json_object_string_add(json
, "peerUptime", "never");
6338 json_object_int_add(json
, "peerUptimeMsec", 0);
6340 snprintf(buf
, len
, "never");
6344 /* Get current time. */
6345 uptime1
= bgp_clock();
6347 tm
= gmtime(&uptime1
);
6349 if (uptime1
< ONE_DAY_SECOND
)
6350 snprintf(buf
, len
, "%02d:%02d:%02d", tm
->tm_hour
, tm
->tm_min
,
6352 else if (uptime1
< ONE_WEEK_SECOND
)
6353 snprintf(buf
, len
, "%dd%02dh%02dm", tm
->tm_yday
, tm
->tm_hour
,
6355 else if (uptime1
< ONE_YEAR_SECOND
)
6356 snprintf(buf
, len
, "%02dw%dd%02dh", tm
->tm_yday
/ 7,
6357 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7), tm
->tm_hour
);
6359 snprintf(buf
, len
, "%02dy%02dw%dd", tm
->tm_year
- 70,
6361 tm
->tm_yday
- ((tm
->tm_yday
/ 7) * 7));
6364 epoch_tbuf
= time(NULL
) - uptime1
;
6365 json_object_string_add(json
, "peerUptime", buf
);
6366 json_object_int_add(json
, "peerUptimeMsec", uptime1
* 1000);
6367 json_object_int_add(json
, "peerUptimeEstablishedEpoch",
6374 static void bgp_config_write_filter(struct vty
*vty
, struct peer
*peer
,
6375 afi_t afi
, safi_t safi
)
6377 struct bgp_filter
*filter
;
6378 struct bgp_filter
*gfilter
= NULL
;
6381 int out
= FILTER_OUT
;
6384 filter
= &peer
->filter
[afi
][safi
];
6386 if (peer_group_active(peer
))
6387 gfilter
= &peer
->group
->conf
->filter
[afi
][safi
];
6389 /* distribute-list. */
6390 if (filter
->dlist
[in
].name
)
6391 if (!gfilter
|| !gfilter
->dlist
[in
].name
6392 || strcmp(filter
->dlist
[in
].name
, gfilter
->dlist
[in
].name
)
6394 vty_out(vty
, " neighbor %s distribute-list %s in\n",
6395 addr
, filter
->dlist
[in
].name
);
6398 if (filter
->dlist
[out
].name
&& !gfilter
) {
6399 vty_out(vty
, " neighbor %s distribute-list %s out\n", addr
,
6400 filter
->dlist
[out
].name
);
6404 if (filter
->plist
[in
].name
)
6405 if (!gfilter
|| !gfilter
->plist
[in
].name
6406 || strcmp(filter
->plist
[in
].name
, gfilter
->plist
[in
].name
)
6408 vty_out(vty
, " neighbor %s prefix-list %s in\n", addr
,
6409 filter
->plist
[in
].name
);
6412 if (filter
->plist
[out
].name
)
6413 if (!gfilter
|| !gfilter
->plist
[out
].name
6414 || strcmp(filter
->plist
[out
].name
, gfilter
->plist
[out
].name
)
6416 vty_out(vty
, " neighbor %s prefix-list %s out\n", addr
,
6417 filter
->plist
[out
].name
);
6421 if (filter
->map
[RMAP_IN
].name
)
6422 if (!gfilter
|| !gfilter
->map
[RMAP_IN
].name
6423 || strcmp(filter
->map
[RMAP_IN
].name
,
6424 gfilter
->map
[RMAP_IN
].name
)
6426 vty_out(vty
, " neighbor %s route-map %s in\n", addr
,
6427 filter
->map
[RMAP_IN
].name
);
6430 if (filter
->map
[RMAP_OUT
].name
)
6431 if (!gfilter
|| !gfilter
->map
[RMAP_OUT
].name
6432 || strcmp(filter
->map
[RMAP_OUT
].name
,
6433 gfilter
->map
[RMAP_OUT
].name
)
6435 vty_out(vty
, " neighbor %s route-map %s out\n", addr
,
6436 filter
->map
[RMAP_OUT
].name
);
6439 /* unsuppress-map */
6440 if (filter
->usmap
.name
&& !gfilter
) {
6441 vty_out(vty
, " neighbor %s unsuppress-map %s\n", addr
,
6442 filter
->usmap
.name
);
6446 if (filter
->aslist
[in
].name
)
6447 if (!gfilter
|| !gfilter
->aslist
[in
].name
6448 || strcmp(filter
->aslist
[in
].name
, gfilter
->aslist
[in
].name
)
6450 vty_out(vty
, " neighbor %s filter-list %s in\n", addr
,
6451 filter
->aslist
[in
].name
);
6454 if (filter
->aslist
[out
].name
&& !gfilter
) {
6455 vty_out(vty
, " neighbor %s filter-list %s out\n", addr
,
6456 filter
->aslist
[out
].name
);
6460 /* BGP peer configuration display function. */
6461 static void bgp_config_write_peer_global(struct vty
*vty
, struct bgp
*bgp
,
6464 struct peer
*g_peer
= NULL
;
6465 char buf
[SU_ADDRSTRLEN
];
6467 int if_pg_printed
= FALSE
;
6468 int if_ras_printed
= FALSE
;
6470 /* Skip dynamic neighbors. */
6471 if (peer_dynamic_neighbor(peer
))
6475 addr
= peer
->conf_if
;
6479 /************************************
6480 ****** Global to the neighbor ******
6481 ************************************/
6482 if (peer
->conf_if
) {
6483 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_IFPEER_V6ONLY
))
6484 vty_out(vty
, " neighbor %s interface v6only", addr
);
6486 vty_out(vty
, " neighbor %s interface", addr
);
6488 if (peer_group_active(peer
)) {
6489 vty_out(vty
, " peer-group %s", peer
->group
->name
);
6490 if_pg_printed
= TRUE
;
6491 } else if (peer
->as_type
== AS_SPECIFIED
) {
6492 vty_out(vty
, " remote-as %u", peer
->as
);
6493 if_ras_printed
= TRUE
;
6494 } else if (peer
->as_type
== AS_INTERNAL
) {
6495 vty_out(vty
, " remote-as internal");
6496 if_ras_printed
= TRUE
;
6497 } else if (peer
->as_type
== AS_EXTERNAL
) {
6498 vty_out(vty
, " remote-as external");
6499 if_ras_printed
= TRUE
;
6505 /* remote-as and peer-group */
6506 /* peer is a member of a peer-group */
6507 if (peer_group_active(peer
)) {
6508 g_peer
= peer
->group
->conf
;
6510 if (g_peer
->as_type
== AS_UNSPECIFIED
&& !if_ras_printed
) {
6511 if (peer
->as_type
== AS_SPECIFIED
) {
6512 vty_out(vty
, " neighbor %s remote-as %u\n",
6514 } else if (peer
->as_type
== AS_INTERNAL
) {
6516 " neighbor %s remote-as internal\n",
6518 } else if (peer
->as_type
== AS_EXTERNAL
) {
6520 " neighbor %s remote-as external\n",
6525 /* For swpX peers we displayed the peer-group
6526 * via 'neighbor swpX interface peer-group WORD' */
6528 vty_out(vty
, " neighbor %s peer-group %s\n", addr
,
6532 /* peer is NOT a member of a peer-group */
6534 /* peer is a peer-group, declare the peer-group */
6535 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
)) {
6536 vty_out(vty
, " neighbor %s peer-group\n", addr
);
6539 if (!if_ras_printed
) {
6540 if (peer
->as_type
== AS_SPECIFIED
) {
6541 vty_out(vty
, " neighbor %s remote-as %u\n",
6543 } else if (peer
->as_type
== AS_INTERNAL
) {
6545 " neighbor %s remote-as internal\n",
6547 } else if (peer
->as_type
== AS_EXTERNAL
) {
6549 " neighbor %s remote-as external\n",
6556 if (peer
->change_local_as
) {
6557 if (!peer_group_active(peer
)
6558 || peer
->change_local_as
!= g_peer
->change_local_as
6559 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6560 != CHECK_FLAG(g_peer
->flags
,
6561 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
6562 || (CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6563 != CHECK_FLAG(g_peer
->flags
,
6564 PEER_FLAG_LOCAL_AS_REPLACE_AS
))) {
6565 vty_out(vty
, " neighbor %s local-as %u%s%s\n", addr
,
6566 peer
->change_local_as
,
6567 CHECK_FLAG(peer
->flags
,
6568 PEER_FLAG_LOCAL_AS_NO_PREPEND
)
6571 CHECK_FLAG(peer
->flags
,
6572 PEER_FLAG_LOCAL_AS_REPLACE_AS
)
6580 vty_out(vty
, " neighbor %s description %s\n", addr
, peer
->desc
);
6584 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_SHUTDOWN
)) {
6585 if (!peer_group_active(peer
)
6586 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_SHUTDOWN
)
6587 || peer
->tx_shutdown_message
) {
6588 if (peer
->tx_shutdown_message
)
6590 " neighbor %s shutdown message %s\n",
6591 addr
, peer
->tx_shutdown_message
);
6593 vty_out(vty
, " neighbor %s shutdown\n", addr
);
6598 if (peer
->bfd_info
) {
6599 if (!peer_group_active(peer
) || !g_peer
->bfd_info
) {
6600 bgp_bfd_peer_config_write(vty
, peer
, addr
);
6605 if (peer
->password
) {
6606 if (!peer_group_active(peer
) || !g_peer
->password
6607 || strcmp(peer
->password
, g_peer
->password
) != 0) {
6608 vty_out(vty
, " neighbor %s password %s\n", addr
,
6614 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
)) {
6615 if (!peer_group_active(peer
)) {
6616 vty_out(vty
, " neighbor %s solo\n", addr
);
6621 if (peer
->port
!= BGP_PORT_DEFAULT
) {
6622 vty_out(vty
, " neighbor %s port %d\n", addr
, peer
->port
);
6625 /* Local interface name */
6627 vty_out(vty
, " neighbor %s interface %s\n", addr
, peer
->ifname
);
6631 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_PASSIVE
)) {
6632 if (!peer_group_active(peer
)
6633 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_PASSIVE
)) {
6634 vty_out(vty
, " neighbor %s passive\n", addr
);
6639 if (peer
->sort
!= BGP_PEER_IBGP
&& peer
->ttl
!= 1
6640 && !(peer
->gtsm_hops
!= 0 && peer
->ttl
== MAXTTL
)) {
6641 if (!peer_group_active(peer
) || g_peer
->ttl
!= peer
->ttl
) {
6642 vty_out(vty
, " neighbor %s ebgp-multihop %d\n", addr
,
6647 /* ttl-security hops */
6648 if (peer
->gtsm_hops
!= 0) {
6649 if (!peer_group_active(peer
)
6650 || g_peer
->gtsm_hops
!= peer
->gtsm_hops
) {
6651 vty_out(vty
, " neighbor %s ttl-security hops %d\n",
6652 addr
, peer
->gtsm_hops
);
6656 /* disable-connected-check */
6657 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6658 if (!peer_group_active(peer
)
6659 || !CHECK_FLAG(g_peer
->flags
,
6660 PEER_FLAG_DISABLE_CONNECTED_CHECK
)) {
6661 vty_out(vty
, " neighbor %s disable-connected-check\n",
6667 if (peer
->update_if
) {
6668 if (!peer_group_active(peer
) || !g_peer
->update_if
6669 || strcmp(g_peer
->update_if
, peer
->update_if
) != 0) {
6670 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6674 if (peer
->update_source
) {
6675 if (!peer_group_active(peer
) || !g_peer
->update_source
6676 || sockunion_cmp(g_peer
->update_source
, peer
->update_source
)
6678 vty_out(vty
, " neighbor %s update-source %s\n", addr
,
6679 sockunion2str(peer
->update_source
, buf
,
6684 /* advertisement-interval */
6685 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_ROUTEADV
)
6686 && ((!peer_group_active(peer
)
6687 && peer
->v_routeadv
!= BGP_DEFAULT_EBGP_ROUTEADV
)
6688 || (peer_group_active(peer
)
6689 && peer
->v_routeadv
!= g_peer
->v_routeadv
))) {
6690 vty_out(vty
, " neighbor %s advertisement-interval %u\n", addr
,
6695 if ((PEER_OR_GROUP_TIMER_SET(peer
))
6696 && ((!peer_group_active(peer
)
6697 && (peer
->keepalive
!= BGP_DEFAULT_KEEPALIVE
6698 || peer
->holdtime
!= BGP_DEFAULT_HOLDTIME
))
6699 || (peer_group_active(peer
)
6700 && (peer
->keepalive
!= g_peer
->keepalive
6701 || peer
->holdtime
!= g_peer
->holdtime
)))) {
6702 vty_out(vty
, " neighbor %s timers %u %u\n", addr
,
6703 peer
->keepalive
, peer
->holdtime
);
6706 if (CHECK_FLAG(peer
->config
, PEER_CONFIG_CONNECT
)
6707 && ((!peer_group_active(peer
)
6708 && peer
->connect
!= BGP_DEFAULT_CONNECT_RETRY
)
6709 || (peer_group_active(peer
)
6710 && peer
->connect
!= g_peer
->connect
)))
6713 vty_out(vty
, " neighbor %s timers connect %u\n", addr
,
6717 /* capability dynamic */
6718 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6719 if (!peer_group_active(peer
)
6720 || !CHECK_FLAG(g_peer
->flags
,
6721 PEER_FLAG_DYNAMIC_CAPABILITY
)) {
6722 vty_out(vty
, " neighbor %s capability dynamic\n", addr
);
6726 /* capability extended-nexthop */
6727 if (peer
->ifp
&& !CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6728 if (!peer_group_active(peer
)
6729 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6731 " no neighbor %s capability extended-nexthop\n",
6736 if (!peer
->ifp
&& CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6737 if (!peer_group_active(peer
)
6738 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)) {
6740 " neighbor %s capability extended-nexthop\n",
6745 /* dont-capability-negotiation */
6746 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6747 if (!peer_group_active(peer
)
6748 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_DONT_CAPABILITY
)) {
6749 vty_out(vty
, " neighbor %s dont-capability-negotiate\n",
6754 /* override-capability */
6755 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6756 if (!peer_group_active(peer
)
6757 || !CHECK_FLAG(g_peer
->flags
,
6758 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
6759 vty_out(vty
, " neighbor %s override-capability\n",
6764 /* strict-capability-match */
6765 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6766 if (!peer_group_active(peer
)
6767 || !CHECK_FLAG(g_peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
6768 vty_out(vty
, " neighbor %s strict-capability-match\n",
6774 /* BGP peer configuration display function. */
6775 static void bgp_config_write_peer_af(struct vty
*vty
, struct bgp
*bgp
,
6776 struct peer
*peer
, afi_t afi
, safi_t safi
)
6778 struct peer
*g_peer
= NULL
;
6781 /* Skip dynamic neighbors. */
6782 if (peer_dynamic_neighbor(peer
))
6786 addr
= peer
->conf_if
;
6790 /************************************
6791 ****** Per AF to the neighbor ******
6792 ************************************/
6793 if (peer_group_active(peer
)) {
6794 g_peer
= peer
->group
->conf
;
6796 /* If the peer-group is active but peer is not, print a 'no
6798 if (g_peer
->afc
[afi
][safi
] && !peer
->afc
[afi
][safi
]) {
6799 vty_out(vty
, " no neighbor %s activate\n", addr
);
6802 /* If the peer-group is not active but peer is, print an
6804 else if (!g_peer
->afc
[afi
][safi
] && peer
->afc
[afi
][safi
]) {
6805 vty_out(vty
, " neighbor %s activate\n", addr
);
6808 if (peer
->afc
[afi
][safi
]) {
6809 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6810 if (bgp_flag_check(bgp
,
6811 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6812 vty_out(vty
, " neighbor %s activate\n",
6816 vty_out(vty
, " neighbor %s activate\n", addr
);
6818 if ((afi
== AFI_IP
) && (safi
== SAFI_UNICAST
)) {
6819 if (!bgp_flag_check(bgp
,
6820 BGP_FLAG_NO_DEFAULT_IPV4
)) {
6822 " no neighbor %s activate\n",
6829 /* addpath TX knobs */
6830 if (peergroup_af_flag_check(peer
, afi
, safi
,
6831 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)) {
6832 vty_out(vty
, " neighbor %s addpath-tx-all-paths\n", addr
);
6835 if (peergroup_af_flag_check(peer
, afi
, safi
,
6836 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
)) {
6837 vty_out(vty
, " neighbor %s addpath-tx-bestpath-per-AS\n",
6841 /* ORF capability. */
6842 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ORF_PREFIX_SM
)
6843 || peergroup_af_flag_check(peer
, afi
, safi
,
6844 PEER_FLAG_ORF_PREFIX_RM
)) {
6845 vty_out(vty
, " neighbor %s capability orf prefix-list", addr
);
6847 if (peergroup_af_flag_check(peer
, afi
, safi
,
6848 PEER_FLAG_ORF_PREFIX_SM
)
6849 && peergroup_af_flag_check(peer
, afi
, safi
,
6850 PEER_FLAG_ORF_PREFIX_RM
))
6851 vty_out(vty
, " both");
6852 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6853 PEER_FLAG_ORF_PREFIX_SM
))
6854 vty_out(vty
, " send");
6856 vty_out(vty
, " receive");
6860 /* Route reflector client. */
6861 if (peergroup_af_flag_check(peer
, afi
, safi
,
6862 PEER_FLAG_REFLECTOR_CLIENT
)) {
6863 vty_out(vty
, " neighbor %s route-reflector-client\n", addr
);
6866 /* next-hop-self force */
6867 if (peergroup_af_flag_check(peer
, afi
, safi
,
6868 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
6869 vty_out(vty
, " neighbor %s next-hop-self force\n", addr
);
6873 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_SELF
)) {
6874 vty_out(vty
, " neighbor %s next-hop-self\n", addr
);
6877 /* remove-private-AS */
6878 if (peergroup_af_flag_check(peer
, afi
, safi
,
6879 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)) {
6880 vty_out(vty
, " neighbor %s remove-private-AS all replace-AS\n",
6884 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6885 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)) {
6886 vty_out(vty
, " neighbor %s remove-private-AS replace-AS\n",
6890 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6891 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
6892 vty_out(vty
, " neighbor %s remove-private-AS all\n", addr
);
6895 else if (peergroup_af_flag_check(peer
, afi
, safi
,
6896 PEER_FLAG_REMOVE_PRIVATE_AS
)) {
6897 vty_out(vty
, " neighbor %s remove-private-AS\n", addr
);
6901 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
6902 vty_out(vty
, " neighbor %s as-override\n", addr
);
6905 /* send-community print. */
6906 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
6907 if (peergroup_af_flag_check(peer
, afi
, safi
,
6908 PEER_FLAG_SEND_COMMUNITY
)
6909 && peergroup_af_flag_check(peer
, afi
, safi
,
6910 PEER_FLAG_SEND_EXT_COMMUNITY
)
6911 && peergroup_af_flag_check(
6913 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6914 vty_out(vty
, " neighbor %s send-community all\n",
6916 } else if (peergroup_af_flag_check(
6918 PEER_FLAG_SEND_LARGE_COMMUNITY
)) {
6919 vty_out(vty
, " neighbor %s send-community large\n",
6921 } else if (peergroup_af_flag_check(
6923 PEER_FLAG_SEND_EXT_COMMUNITY
)) {
6924 vty_out(vty
, " neighbor %s send-community extended\n",
6926 } else if (peergroup_af_flag_check(peer
, afi
, safi
,
6927 PEER_FLAG_SEND_COMMUNITY
)) {
6928 vty_out(vty
, " neighbor %s send-community\n", addr
);
6931 if (!peer_af_flag_check(peer
, afi
, safi
,
6932 PEER_FLAG_SEND_COMMUNITY
)
6933 && (!g_peer
|| peer_af_flag_check(g_peer
, afi
, safi
,
6934 PEER_FLAG_SEND_COMMUNITY
))
6935 && !peer_af_flag_check(peer
, afi
, safi
,
6936 PEER_FLAG_SEND_EXT_COMMUNITY
)
6938 || peer_af_flag_check(g_peer
, afi
, safi
,
6939 PEER_FLAG_SEND_EXT_COMMUNITY
))
6940 && !peer_af_flag_check(peer
, afi
, safi
,
6941 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6942 && (!g_peer
|| peer_af_flag_check(
6944 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6945 vty_out(vty
, " no neighbor %s send-community all\n",
6948 if (!peer_af_flag_check(peer
, afi
, safi
,
6949 PEER_FLAG_SEND_LARGE_COMMUNITY
)
6951 || peer_af_flag_check(
6953 PEER_FLAG_SEND_LARGE_COMMUNITY
))) {
6955 " no neighbor %s send-community large\n",
6959 if (!peer_af_flag_check(peer
, afi
, safi
,
6960 PEER_FLAG_SEND_EXT_COMMUNITY
)
6962 || peer_af_flag_check(
6964 PEER_FLAG_SEND_EXT_COMMUNITY
))) {
6966 " no neighbor %s send-community extended\n",
6970 if (!peer_af_flag_check(peer
, afi
, safi
,
6971 PEER_FLAG_SEND_COMMUNITY
)
6972 && (!g_peer
|| peer_af_flag_check(
6974 PEER_FLAG_SEND_COMMUNITY
))) {
6976 " no neighbor %s send-community\n",
6982 /* Default information */
6983 if (peergroup_af_flag_check(peer
, afi
, safi
,
6984 PEER_FLAG_DEFAULT_ORIGINATE
)
6986 && ((peer
->default_rmap
[afi
][safi
].name
6987 && !g_peer
->default_rmap
[afi
][safi
].name
)
6988 || (!peer
->default_rmap
[afi
][safi
].name
6989 && g_peer
->default_rmap
[afi
][safi
].name
)
6990 || (peer
->default_rmap
[afi
][safi
].name
6991 && strcmp(peer
->default_rmap
[afi
][safi
].name
,
6992 g_peer
->default_rmap
[afi
][safi
].name
))))) {
6993 vty_out(vty
, " neighbor %s default-originate", addr
);
6994 if (peer
->default_rmap
[afi
][safi
].name
)
6995 vty_out(vty
, " route-map %s",
6996 peer
->default_rmap
[afi
][safi
].name
);
7000 /* Soft reconfiguration inbound. */
7001 if (peergroup_af_flag_check(peer
, afi
, safi
, PEER_FLAG_SOFT_RECONFIG
)) {
7002 vty_out(vty
, " neighbor %s soft-reconfiguration inbound\n",
7006 /* maximum-prefix. */
7007 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
7008 if (!peer_group_active(peer
)
7009 || g_peer
->pmax
[afi
][safi
] != peer
->pmax
[afi
][safi
]
7010 || g_peer
->pmax_threshold
[afi
][safi
]
7011 != peer
->pmax_threshold
[afi
][safi
]
7012 || CHECK_FLAG(g_peer
->af_flags
[afi
][safi
],
7013 PEER_FLAG_MAX_PREFIX_WARNING
)
7014 != CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7015 PEER_FLAG_MAX_PREFIX_WARNING
)) {
7016 vty_out(vty
, " neighbor %s maximum-prefix %lu", addr
,
7017 peer
->pmax
[afi
][safi
]);
7018 if (peer
->pmax_threshold
[afi
][safi
]
7019 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT
)
7021 peer
->pmax_threshold
[afi
][safi
]);
7022 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
7023 PEER_FLAG_MAX_PREFIX_WARNING
))
7024 vty_out(vty
, " warning-only");
7025 if (peer
->pmax_restart
[afi
][safi
])
7026 vty_out(vty
, " restart %u",
7027 peer
->pmax_restart
[afi
][safi
]);
7031 /* Route server client. */
7032 if (peergroup_af_flag_check(peer
, afi
, safi
,
7033 PEER_FLAG_RSERVER_CLIENT
)) {
7034 vty_out(vty
, " neighbor %s route-server-client\n", addr
);
7037 /* Nexthop-local unchanged. */
7038 if (peergroup_af_flag_check(peer
, afi
, safi
,
7039 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)) {
7040 vty_out(vty
, " neighbor %s nexthop-local unchanged\n", addr
);
7043 /* allowas-in <1-10> */
7044 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_ALLOWAS_IN
)) {
7045 if (!peer_group_active(peer
)
7046 || !peer_af_flag_check(g_peer
, afi
, safi
,
7047 PEER_FLAG_ALLOWAS_IN
)
7048 || peer
->allowas_in
[afi
][safi
]
7049 != g_peer
->allowas_in
[afi
][safi
]) {
7050 if (peer
->allowas_in
[afi
][safi
] == 3) {
7051 vty_out(vty
, " neighbor %s allowas-in\n",
7054 vty_out(vty
, " neighbor %s allowas-in %d\n",
7055 addr
, peer
->allowas_in
[afi
][safi
]);
7060 /* allowas-in origin */
7061 else if (peer_af_flag_check(peer
, afi
, safi
,
7062 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7063 if (!peer_group_active(peer
)
7064 || !peer_af_flag_check(g_peer
, afi
, safi
,
7065 PEER_FLAG_ALLOWAS_IN_ORIGIN
)) {
7066 vty_out(vty
, " neighbor %s allowas-in origin\n", addr
);
7071 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_WEIGHT
))
7072 if (!peer_group_active(peer
)
7073 || !peer_af_flag_check(g_peer
, afi
, safi
, PEER_FLAG_WEIGHT
)
7074 || peer
->weight
[afi
][safi
] != g_peer
->weight
[afi
][safi
]) {
7075 if (peer
->weight
[afi
][safi
]) {
7076 vty_out(vty
, " neighbor %s weight %lu\n", addr
,
7077 peer
->weight
[afi
][safi
]);
7082 bgp_config_write_filter(vty
, peer
, afi
, safi
);
7084 /* atribute-unchanged. */
7085 if (peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_PATH_UNCHANGED
)
7086 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_NEXTHOP_UNCHANGED
)
7087 || peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_MED_UNCHANGED
)) {
7089 if (!peer_group_active(peer
)
7090 || peergroup_af_flag_check(peer
, afi
, safi
,
7091 PEER_FLAG_AS_PATH_UNCHANGED
)
7092 || peergroup_af_flag_check(peer
, afi
, safi
,
7093 PEER_FLAG_NEXTHOP_UNCHANGED
)
7094 || peergroup_af_flag_check(peer
, afi
, safi
,
7095 PEER_FLAG_MED_UNCHANGED
)) {
7098 " neighbor %s attribute-unchanged%s%s%s\n",
7100 peer_af_flag_check(peer
, afi
, safi
,
7101 PEER_FLAG_AS_PATH_UNCHANGED
)
7104 peer_af_flag_check(peer
, afi
, safi
,
7105 PEER_FLAG_NEXTHOP_UNCHANGED
)
7108 peer_af_flag_check(peer
, afi
, safi
,
7109 PEER_FLAG_MED_UNCHANGED
)
7116 /* Address family based peer configuration display. */
7117 static void bgp_config_write_family(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
7121 struct peer_group
*group
;
7122 struct listnode
*node
, *nnode
;
7125 vty_frame(vty
, " !\n address-family ");
7126 if (afi
== AFI_IP
) {
7127 if (safi
== SAFI_UNICAST
)
7128 vty_frame(vty
, "ipv4 unicast");
7129 else if (safi
== SAFI_LABELED_UNICAST
)
7130 vty_frame(vty
, "ipv4 labeled-unicast");
7131 else if (safi
== SAFI_MULTICAST
)
7132 vty_frame(vty
, "ipv4 multicast");
7133 else if (safi
== SAFI_MPLS_VPN
)
7134 vty_frame(vty
, "ipv4 vpn");
7135 else if (safi
== SAFI_ENCAP
)
7136 vty_frame(vty
, "ipv4 encap");
7137 else if (safi
== SAFI_FLOWSPEC
)
7138 vty_frame(vty
, "ipv4 flowspec");
7139 } else if (afi
== AFI_IP6
) {
7140 if (safi
== SAFI_UNICAST
)
7141 vty_frame(vty
, "ipv6 unicast");
7142 else if (safi
== SAFI_LABELED_UNICAST
)
7143 vty_frame(vty
, "ipv6 labeled-unicast");
7144 else if (safi
== SAFI_MULTICAST
)
7145 vty_frame(vty
, "ipv6 multicast");
7146 else if (safi
== SAFI_MPLS_VPN
)
7147 vty_frame(vty
, "ipv6 vpn");
7148 else if (safi
== SAFI_ENCAP
)
7149 vty_frame(vty
, "ipv6 encap");
7150 else if (safi
== SAFI_FLOWSPEC
)
7151 vty_frame(vty
, "ipv6 flowspec");
7152 } else if (afi
== AFI_L2VPN
) {
7153 if (safi
== SAFI_EVPN
)
7154 vty_frame(vty
, "l2vpn evpn");
7156 vty_frame(vty
, "\n");
7158 bgp_config_write_distance(vty
, bgp
, afi
, safi
);
7160 bgp_config_write_network(vty
, bgp
, afi
, safi
);
7162 bgp_config_write_redistribute(vty
, bgp
, afi
, safi
);
7164 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
))
7165 bgp_config_write_peer_af(vty
, bgp
, group
->conf
, afi
, safi
);
7167 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7168 /* Skip dynamic neighbors. */
7169 if (peer_dynamic_neighbor(peer
))
7172 /* Do not display doppelganger peers */
7173 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7174 bgp_config_write_peer_af(vty
, bgp
, peer
, afi
, safi
);
7177 bgp_config_write_maxpaths(vty
, bgp
, afi
, safi
);
7178 bgp_config_write_table_map(vty
, bgp
, afi
, safi
);
7180 if (safi
== SAFI_EVPN
)
7181 bgp_config_write_evpn_info(vty
, bgp
, afi
, safi
);
7183 if (safi
== SAFI_UNICAST
) {
7184 bgp_vpn_policy_config_write_afi(vty
, bgp
, afi
);
7185 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7186 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT
)) {
7188 vty_out(vty
, " export vpn\n");
7190 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
7191 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT
)) {
7193 vty_out(vty
, " import vpn\n");
7197 vty_endframe(vty
, " exit-address-family\n");
7200 int bgp_config_write(struct vty
*vty
)
7204 struct peer_group
*group
;
7206 struct listnode
*node
, *nnode
;
7207 struct listnode
*mnode
, *mnnode
;
7209 /* BGP Multiple instance. */
7210 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7211 vty_out(vty
, "no bgp multiple-instance\n");
7215 /* BGP Config type. */
7216 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)) {
7217 vty_out(vty
, "bgp config-type cisco\n");
7221 if (bm
->rmap_update_timer
!= RMAP_DEFAULT_UPDATE_TIMER
)
7222 vty_out(vty
, "bgp route-map delay-timer %u\n",
7223 bm
->rmap_update_timer
);
7226 vty_out(vty
, "!\n");
7228 /* BGP configuration. */
7229 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
)) {
7231 /* skip all auto created vrf as they dont have user config */
7232 if (CHECK_FLAG(bgp
->vrf_flags
, BGP_VRF_AUTO
))
7235 /* Router bgp ASN */
7236 vty_out(vty
, "router bgp %u", bgp
->as
);
7238 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE
)) {
7240 vty_out(vty
, " %s %s",
7242 == BGP_INSTANCE_TYPE_VIEW
)
7249 /* No Synchronization */
7250 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7251 vty_out(vty
, " no synchronization\n");
7253 /* BGP fast-external-failover. */
7254 if (CHECK_FLAG(bgp
->flags
, BGP_FLAG_NO_FAST_EXT_FAILOVER
))
7255 vty_out(vty
, " no bgp fast-external-failover\n");
7257 /* BGP router ID. */
7258 if (bgp
->router_id_static
.s_addr
!= 0)
7259 vty_out(vty
, " bgp router-id %s\n",
7260 inet_ntoa(bgp
->router_id_static
));
7262 /* BGP log-neighbor-changes. */
7263 if (!!bgp_flag_check(bgp
, BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7264 != DFLT_BGP_LOG_NEIGHBOR_CHANGES
)
7265 vty_out(vty
, " %sbgp log-neighbor-changes\n",
7267 BGP_FLAG_LOG_NEIGHBOR_CHANGES
)
7271 /* BGP configuration. */
7272 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
))
7273 vty_out(vty
, " bgp always-compare-med\n");
7275 /* BGP default ipv4-unicast. */
7276 if (bgp_flag_check(bgp
, BGP_FLAG_NO_DEFAULT_IPV4
))
7277 vty_out(vty
, " no bgp default ipv4-unicast\n");
7279 /* BGP default local-preference. */
7280 if (bgp
->default_local_pref
!= BGP_DEFAULT_LOCAL_PREF
)
7281 vty_out(vty
, " bgp default local-preference %u\n",
7282 bgp
->default_local_pref
);
7284 /* BGP default show-hostname */
7285 if (!!bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7286 != DFLT_BGP_SHOW_HOSTNAME
)
7287 vty_out(vty
, " %sbgp default show-hostname\n",
7288 bgp_flag_check(bgp
, BGP_FLAG_SHOW_HOSTNAME
)
7292 /* BGP default subgroup-pkt-queue-max. */
7293 if (bgp
->default_subgroup_pkt_queue_max
7294 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX
)
7295 vty_out(vty
, " bgp default subgroup-pkt-queue-max %u\n",
7296 bgp
->default_subgroup_pkt_queue_max
);
7298 /* BGP default autoshutdown neighbors */
7299 if (bgp
->autoshutdown
)
7300 vty_out(vty
, " bgp default shutdown\n");
7302 /* BGP client-to-client reflection. */
7303 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
7304 vty_out(vty
, " no bgp client-to-client reflection\n");
7306 /* BGP cluster ID. */
7307 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CLUSTER_ID
))
7308 vty_out(vty
, " bgp cluster-id %s\n",
7309 inet_ntoa(bgp
->cluster_id
));
7311 /* Disable ebgp connected nexthop check */
7312 if (bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
7314 " bgp disable-ebgp-connected-route-check\n");
7316 /* Confederation identifier*/
7317 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
))
7318 vty_out(vty
, " bgp confederation identifier %i\n",
7321 /* Confederation peer */
7322 if (bgp
->confed_peers_cnt
> 0) {
7325 vty_out(vty
, " bgp confederation peers");
7327 for (i
= 0; i
< bgp
->confed_peers_cnt
; i
++)
7328 vty_out(vty
, " %u", bgp
->confed_peers
[i
]);
7333 /* BGP enforce-first-as. */
7334 if (bgp_flag_check(bgp
, BGP_FLAG_ENFORCE_FIRST_AS
))
7335 vty_out(vty
, " bgp enforce-first-as\n");
7337 /* BGP deterministic-med. */
7338 if (!!bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7339 != DFLT_BGP_DETERMINISTIC_MED
)
7340 vty_out(vty
, " %sbgp deterministic-med\n",
7341 bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
7345 /* BGP update-delay. */
7346 bgp_config_write_update_delay(vty
, bgp
);
7348 if (bgp
->v_maxmed_onstartup
7349 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED
) {
7350 vty_out(vty
, " bgp max-med on-startup %u",
7351 bgp
->v_maxmed_onstartup
);
7352 if (bgp
->maxmed_onstartup_value
7353 != BGP_MAXMED_VALUE_DEFAULT
)
7355 bgp
->maxmed_onstartup_value
);
7358 if (bgp
->v_maxmed_admin
!= BGP_MAXMED_ADMIN_UNCONFIGURED
) {
7359 vty_out(vty
, " bgp max-med administrative");
7360 if (bgp
->maxmed_admin_value
!= BGP_MAXMED_VALUE_DEFAULT
)
7361 vty_out(vty
, " %u", bgp
->maxmed_admin_value
);
7366 bgp_config_write_wpkt_quanta(vty
, bgp
);
7368 bgp_config_write_rpkt_quanta(vty
, bgp
);
7371 bgp_config_write_coalesce_time(vty
, bgp
);
7373 /* BGP graceful-restart. */
7374 if (bgp
->stalepath_time
!= BGP_DEFAULT_STALEPATH_TIME
)
7376 " bgp graceful-restart stalepath-time %u\n",
7377 bgp
->stalepath_time
);
7378 if (bgp
->restart_time
!= BGP_DEFAULT_RESTART_TIME
)
7379 vty_out(vty
, " bgp graceful-restart restart-time %u\n",
7381 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_RESTART
))
7382 vty_out(vty
, " bgp graceful-restart\n");
7384 /* BGP graceful-shutdown */
7385 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
7386 vty_out(vty
, " bgp graceful-shutdown\n");
7388 /* BGP graceful-restart Preserve State F bit. */
7389 if (bgp_flag_check(bgp
, BGP_FLAG_GR_PRESERVE_FWD
))
7391 " bgp graceful-restart preserve-fw-state\n");
7393 /* BGP bestpath method. */
7394 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
))
7395 vty_out(vty
, " bgp bestpath as-path ignore\n");
7396 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
))
7397 vty_out(vty
, " bgp bestpath as-path confed\n");
7399 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
7400 if (bgp_flag_check(bgp
,
7401 BGP_FLAG_MULTIPATH_RELAX_AS_SET
)) {
7403 " bgp bestpath as-path multipath-relax as-set\n");
7406 " bgp bestpath as-path multipath-relax\n");
7410 if (bgp_flag_check(bgp
, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
7412 " bgp route-reflector allow-outbound-policy\n");
7414 if (bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
))
7415 vty_out(vty
, " bgp bestpath compare-routerid\n");
7416 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
)
7417 || bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
)) {
7418 vty_out(vty
, " bgp bestpath med");
7419 if (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
))
7420 vty_out(vty
, " confed");
7421 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
7422 vty_out(vty
, " missing-as-worst");
7426 /* BGP network import check. */
7427 if (!!bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7428 != DFLT_BGP_IMPORT_CHECK
)
7429 vty_out(vty
, " %sbgp network import-check\n",
7430 bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
7434 /* BGP flag dampening. */
7435 if (CHECK_FLAG(bgp
->af_flags
[AFI_IP
][SAFI_UNICAST
],
7436 BGP_CONFIG_DAMPENING
))
7437 bgp_config_write_damp(vty
);
7439 /* BGP timers configuration. */
7440 if (bgp
->default_keepalive
!= BGP_DEFAULT_KEEPALIVE
7441 && bgp
->default_holdtime
!= BGP_DEFAULT_HOLDTIME
)
7442 vty_out(vty
, " timers bgp %u %u\n",
7443 bgp
->default_keepalive
, bgp
->default_holdtime
);
7446 for (ALL_LIST_ELEMENTS(bgp
->group
, node
, nnode
, group
)) {
7447 bgp_config_write_peer_global(vty
, bgp
, group
->conf
);
7450 /* Normal neighbor configuration. */
7451 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7452 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CONFIG_NODE
))
7453 bgp_config_write_peer_global(vty
, bgp
, peer
);
7456 /* listen range and limit for dynamic BGP neighbors */
7457 bgp_config_write_listen(vty
, bgp
);
7459 /* No auto-summary */
7460 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
))
7461 vty_out(vty
, " no auto-summary\n");
7463 /* IPv4 unicast configuration. */
7464 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_UNICAST
);
7466 /* IPv4 multicast configuration. */
7467 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MULTICAST
);
7469 /* IPv4 labeled-unicast configuration. */
7470 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_LABELED_UNICAST
);
7472 /* IPv4 VPN configuration. */
7473 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_MPLS_VPN
);
7475 /* ENCAPv4 configuration. */
7476 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_ENCAP
);
7478 /* FLOWSPEC v4 configuration. */
7479 bgp_config_write_family(vty
, bgp
, AFI_IP
, SAFI_FLOWSPEC
);
7481 /* IPv6 unicast configuration. */
7482 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_UNICAST
);
7484 /* IPv6 multicast configuration. */
7485 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MULTICAST
);
7487 /* IPv6 labeled-unicast configuration. */
7488 bgp_config_write_family(vty
, bgp
, AFI_IP6
,
7489 SAFI_LABELED_UNICAST
);
7491 /* IPv6 VPN configuration. */
7492 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_MPLS_VPN
);
7494 /* ENCAPv6 configuration. */
7495 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_ENCAP
);
7497 /* FLOWSPEC v6 configuration. */
7498 bgp_config_write_family(vty
, bgp
, AFI_IP6
, SAFI_FLOWSPEC
);
7500 /* EVPN configuration. */
7501 bgp_config_write_family(vty
, bgp
, AFI_L2VPN
, SAFI_EVPN
);
7504 bgp_rfapi_cfg_write(vty
, bgp
);
7507 vty_out(vty
, "!\n");
7512 void bgp_master_init(struct thread_master
*master
)
7516 memset(&bgp_master
, 0, sizeof(struct bgp_master
));
7519 bm
->bgp
= list_new();
7520 bm
->listen_sockets
= list_new();
7521 bm
->port
= BGP_PORT_DEFAULT
;
7522 bm
->master
= master
;
7523 bm
->start_time
= bgp_clock();
7524 bm
->t_rmap_update
= NULL
;
7525 bm
->rmap_update_timer
= RMAP_DEFAULT_UPDATE_TIMER
;
7527 bgp_process_queue_init();
7529 /* init the rd id space.
7530 assign 0th index in the bitfield,
7531 so that we start with id 1
7533 bf_init(bm
->rd_idspace
, UINT16_MAX
);
7534 bf_assign_zero_index(bm
->rd_idspace
);
7536 /* Enable multiple instances by default. */
7537 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE
);
7539 QOBJ_REG(bm
, bgp_master
);
7543 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7544 * instance delete (non-default only) or BGP exit.
7546 static void bgp_if_finish(struct bgp
*bgp
)
7548 struct vrf
*vrf
= vrf_lookup_by_id(bgp
->vrf_id
);
7549 struct interface
*ifp
;
7551 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_VIEW
|| !vrf
)
7554 FOR_ALL_INTERFACES (vrf
, ifp
) {
7555 struct listnode
*c_node
, *c_nnode
;
7556 struct connected
*c
;
7558 for (ALL_LIST_ELEMENTS(ifp
->connected
, c_node
, c_nnode
, c
))
7559 bgp_connected_delete(bgp
, c
);
7563 extern void bgp_snmp_init(void);
7565 static void bgp_viewvrf_autocomplete(vector comps
, struct cmd_token
*token
)
7567 struct vrf
*vrf
= NULL
;
7568 struct listnode
*next
;
7571 RB_FOREACH (vrf
, vrf_name_head
, &vrfs_by_name
) {
7572 if (vrf
->vrf_id
!= VRF_DEFAULT
)
7573 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, vrf
->name
));
7576 for (ALL_LIST_ELEMENTS_RO(bm
->bgp
, next
, bgp
)) {
7577 if (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
7580 vector_set(comps
, XSTRDUP(MTYPE_COMPLETION
, bgp
->name
));
7584 static const struct cmd_variable_handler bgp_viewvrf_var_handlers
[] = {
7585 {.tokenname
= "VIEWVRFNAME", .completions
= bgp_viewvrf_autocomplete
},
7586 {.completions
= NULL
},
7589 static void bgp_pthreads_init()
7593 struct frr_pthread_attr io
= {
7595 .start
= frr_pthread_attr_default
.start
,
7596 .stop
= frr_pthread_attr_default
.stop
,
7598 struct frr_pthread_attr ka
= {
7599 .id
= PTHREAD_KEEPALIVES
,
7600 .start
= bgp_keepalives_start
,
7601 .stop
= bgp_keepalives_stop
,
7603 frr_pthread_new(&io
, "BGP I/O thread");
7604 frr_pthread_new(&ka
, "BGP Keepalives thread");
7607 void bgp_pthreads_run()
7609 struct frr_pthread
*io
= frr_pthread_get(PTHREAD_IO
);
7610 struct frr_pthread
*ka
= frr_pthread_get(PTHREAD_KEEPALIVES
);
7612 frr_pthread_run(io
, NULL
);
7613 frr_pthread_run(ka
, NULL
);
7615 /* Wait until threads are ready. */
7616 frr_pthread_wait_running(io
);
7617 frr_pthread_wait_running(ka
);
7620 void bgp_pthreads_finish()
7622 frr_pthread_stop_all();
7623 frr_pthread_finish();
7629 /* allocates some vital data structures used by peer commands in
7632 /* pre-init pthreads */
7633 bgp_pthreads_init();
7636 bgp_zebra_init(bm
->master
);
7639 vnc_zebra_init(bm
->master
);
7642 /* BGP VTY commands installation. */
7650 bgp_route_map_init();
7651 bgp_scan_vty_init();
7656 bgp_ethernetvpn_init();
7657 bgp_flowspec_vty_init();
7659 /* Access list initialize. */
7661 access_list_add_hook(peer_distribute_update
);
7662 access_list_delete_hook(peer_distribute_update
);
7664 /* Filter list initialize. */
7666 as_list_add_hook(peer_aslist_add
);
7667 as_list_delete_hook(peer_aslist_del
);
7669 /* Prefix list initialize.*/
7671 prefix_list_add_hook(peer_prefix_list_update
);
7672 prefix_list_delete_hook(peer_prefix_list_update
);
7674 /* Community list initialize. */
7675 bgp_clist
= community_list_init();
7680 cmd_variable_handler_register(bgp_viewvrf_var_handlers
);
7683 void bgp_terminate(void)
7687 struct listnode
*node
, *nnode
;
7688 struct listnode
*mnode
, *mnnode
;
7692 /* Close the listener sockets first as this prevents peers from
7694 * to reconnect on receiving the peer unconfig message. In the presence
7695 * of a large number of peers this will ensure that no peer is left with
7696 * a dangling connection
7698 /* reverse bgp_master_init */
7701 if (bm
->listen_sockets
)
7702 list_delete_and_null(&bm
->listen_sockets
);
7704 for (ALL_LIST_ELEMENTS(bm
->bgp
, mnode
, mnnode
, bgp
))
7705 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
))
7706 if (peer
->status
== Established
7707 || peer
->status
== OpenSent
7708 || peer
->status
== OpenConfirm
)
7709 bgp_notify_send(peer
, BGP_NOTIFY_CEASE
,
7710 BGP_NOTIFY_CEASE_PEER_UNCONFIG
);
7712 if (bm
->process_main_queue
)
7713 work_queue_free_and_null(&bm
->process_main_queue
);
7715 if (bm
->t_rmap_update
)
7716 BGP_TIMER_OFF(bm
->t_rmap_update
);