]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgpd.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / bgpd.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP-4, BGP-4+ daemon program
3 * Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 */
5
6 #include <zebra.h>
7
8 #include "prefix.h"
9 #include "thread.h"
10 #include "buffer.h"
11 #include "stream.h"
12 #include "ringbuf.h"
13 #include "command.h"
14 #include "sockunion.h"
15 #include "sockopt.h"
16 #include "network.h"
17 #include "memory.h"
18 #include "filter.h"
19 #include "routemap.h"
20 #include "log.h"
21 #include "plist.h"
22 #include "linklist.h"
23 #include "workqueue.h"
24 #include "queue.h"
25 #include "zclient.h"
26 #include "bfd.h"
27 #include "hash.h"
28 #include "jhash.h"
29 #include "table.h"
30 #include "lib/json.h"
31 #include "lib/sockopt.h"
32 #include "frr_pthread.h"
33 #include "bitfield.h"
34
35 #include "bgpd/bgpd.h"
36 #include "bgpd/bgp_table.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_dump.h"
40 #include "bgpd/bgp_debug.h"
41 #include "bgpd/bgp_errors.h"
42 #include "bgpd/bgp_community.h"
43 #include "bgpd/bgp_community_alias.h"
44 #include "bgpd/bgp_conditional_adv.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_regex.h"
47 #include "bgpd/bgp_clist.h"
48 #include "bgpd/bgp_fsm.h"
49 #include "bgpd/bgp_packet.h"
50 #include "bgpd/bgp_zebra.h"
51 #include "bgpd/bgp_open.h"
52 #include "bgpd/bgp_filter.h"
53 #include "bgpd/bgp_nexthop.h"
54 #include "bgpd/bgp_damp.h"
55 #include "bgpd/bgp_mplsvpn.h"
56 #ifdef ENABLE_BGP_VNC
57 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
58 #include "bgpd/rfapi/rfapi_backend.h"
59 #endif
60 #include "bgpd/bgp_evpn.h"
61 #include "bgpd/bgp_advertise.h"
62 #include "bgpd/bgp_network.h"
63 #include "bgpd/bgp_vty.h"
64 #include "bgpd/bgp_mpath.h"
65 #include "bgpd/bgp_nht.h"
66 #include "bgpd/bgp_updgrp.h"
67 #include "bgpd/bgp_bfd.h"
68 #include "bgpd/bgp_memory.h"
69 #include "bgpd/bgp_evpn_vty.h"
70 #include "bgpd/bgp_keepalives.h"
71 #include "bgpd/bgp_io.h"
72 #include "bgpd/bgp_ecommunity.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_labelpool.h"
75 #include "bgpd/bgp_pbr.h"
76 #include "bgpd/bgp_addpath.h"
77 #include "bgpd/bgp_evpn_private.h"
78 #include "bgpd/bgp_evpn_mh.h"
79 #include "bgpd/bgp_mac.h"
80 #include "bgp_trace.h"
81
82 DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
83 DEFINE_MTYPE_STATIC(BGPD, BGP_EVPN_INFO, "BGP EVPN instance information");
84 DEFINE_QOBJ_TYPE(bgp_master);
85 DEFINE_QOBJ_TYPE(bgp);
86 DEFINE_QOBJ_TYPE(peer);
87 DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp));
88
89 /* BGP process wide configuration. */
90 static struct bgp_master bgp_master;
91
92 /* BGP process wide configuration pointer to export. */
93 struct bgp_master *bm;
94
95 /* BGP community-list. */
96 struct community_list_handler *bgp_clist;
97
98 unsigned int multipath_num = MULTIPATH_NUM;
99
100 /* Number of bgp instances configured for suppress fib config */
101 unsigned int bgp_suppress_fib_count;
102
103 static void bgp_if_finish(struct bgp *bgp);
104 static void peer_drop_dynamic_neighbor(struct peer *peer);
105
106 extern struct zclient *zclient;
107
108 /* handle main socket creation or deletion */
109 static int bgp_check_main_socket(bool create, struct bgp *bgp)
110 {
111 static int bgp_server_main_created;
112 struct listnode *node;
113 char *address;
114
115 if (create) {
116 if (bgp_server_main_created)
117 return 0;
118 if (list_isempty(bm->addresses)) {
119 if (bgp_socket(bgp, bm->port, NULL) < 0)
120 return BGP_ERR_INVALID_VALUE;
121 } else {
122 for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
123 if (bgp_socket(bgp, bm->port, address) < 0)
124 return BGP_ERR_INVALID_VALUE;
125 }
126 bgp_server_main_created = 1;
127 return 0;
128 }
129 if (!bgp_server_main_created)
130 return 0;
131 bgp_close();
132 bgp_server_main_created = 0;
133 return 0;
134 }
135
136 void bgp_session_reset(struct peer *peer)
137 {
138 if (peer->doppelganger && (peer->doppelganger->status != Deleted)
139 && !(CHECK_FLAG(peer->doppelganger->flags, PEER_FLAG_CONFIG_NODE)))
140 peer_delete(peer->doppelganger);
141
142 BGP_EVENT_ADD(peer, BGP_Stop);
143 }
144
145 /*
146 * During session reset, we may delete the doppelganger peer, which would
147 * be the next node to the current node. If the session reset was invoked
148 * during walk of peer list, we would end up accessing the freed next
149 * node. This function moves the next node along.
150 */
151 static void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode)
152 {
153 struct listnode *n;
154 struct peer *npeer;
155
156 n = (nnode) ? *nnode : NULL;
157 npeer = (n) ? listgetdata(n) : NULL;
158
159 if (peer->doppelganger && (peer->doppelganger->status != Deleted)
160 && !(CHECK_FLAG(peer->doppelganger->flags,
161 PEER_FLAG_CONFIG_NODE))) {
162 if (peer->doppelganger == npeer)
163 /* nnode and *nnode are confirmed to be non-NULL here */
164 *nnode = (*nnode)->next;
165 peer_delete(peer->doppelganger);
166 }
167
168 BGP_EVENT_ADD(peer, BGP_Stop);
169 }
170
171 /* BGP global flag manipulation. */
172 int bgp_option_set(int flag)
173 {
174 switch (flag) {
175 case BGP_OPT_NO_FIB:
176 case BGP_OPT_NO_LISTEN:
177 case BGP_OPT_NO_ZEBRA:
178 SET_FLAG(bm->options, flag);
179 break;
180 default:
181 return BGP_ERR_INVALID_FLAG;
182 }
183 return 0;
184 }
185
186 int bgp_option_unset(int flag)
187 {
188 switch (flag) {
189 /* Fall through. */
190 case BGP_OPT_NO_ZEBRA:
191 case BGP_OPT_NO_FIB:
192 UNSET_FLAG(bm->options, flag);
193 break;
194 default:
195 return BGP_ERR_INVALID_FLAG;
196 }
197 return 0;
198 }
199
200 int bgp_option_check(int flag)
201 {
202 return CHECK_FLAG(bm->options, flag);
203 }
204
205 /* set the bgp no-rib option during runtime and remove installed routes */
206 void bgp_option_norib_set_runtime(void)
207 {
208 struct bgp *bgp;
209 struct listnode *node;
210 afi_t afi;
211 safi_t safi;
212
213 if (bgp_option_check(BGP_OPT_NO_FIB))
214 return;
215
216 bgp_option_set(BGP_OPT_NO_FIB);
217
218 zlog_info("Disabled BGP route installation to RIB (Zebra)");
219
220 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
221 FOREACH_AFI_SAFI (afi, safi) {
222 /*
223 * Stop a crash, more work is needed
224 * here to properly add/remove these types of
225 * routes from zebra.
226 */
227 if (!bgp_fibupd_safi(safi))
228 continue;
229
230 bgp_zebra_withdraw_table_all_subtypes(bgp, afi, safi);
231 }
232 }
233
234 zlog_info("All routes have been withdrawn from RIB (Zebra)");
235 }
236
237 /* unset the bgp no-rib option during runtime and announce routes to Zebra */
238 void bgp_option_norib_unset_runtime(void)
239 {
240 struct bgp *bgp;
241 struct listnode *node;
242 afi_t afi;
243 safi_t safi;
244
245 if (!bgp_option_check(BGP_OPT_NO_FIB))
246 return;
247
248 bgp_option_unset(BGP_OPT_NO_FIB);
249
250 zlog_info("Enabled BGP route installation to RIB (Zebra)");
251
252 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
253 FOREACH_AFI_SAFI (afi, safi) {
254 /*
255 * Stop a crash, more work is needed
256 * here to properly add/remove these types
257 * of routes from zebra
258 */
259 if (!bgp_fibupd_safi(safi))
260 continue;
261
262 bgp_zebra_announce_table_all_subtypes(bgp, afi, safi);
263 }
264 }
265
266 zlog_info("All routes have been installed in RIB (Zebra)");
267 }
268
269 /* Internal function to set BGP structure configureation flag. */
270 static void bgp_config_set(struct bgp *bgp, int config)
271 {
272 SET_FLAG(bgp->config, config);
273 }
274
275 static void bgp_config_unset(struct bgp *bgp, int config)
276 {
277 UNSET_FLAG(bgp->config, config);
278 }
279
280 static int bgp_config_check(struct bgp *bgp, int config)
281 {
282 return CHECK_FLAG(bgp->config, config);
283 }
284
285 /* Set BGP router identifier; distinguish between explicit config and other
286 * cases.
287 */
288 static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id,
289 bool is_config)
290 {
291 struct peer *peer;
292 struct listnode *node, *nnode;
293
294 if (IPV4_ADDR_SAME(&bgp->router_id, id))
295 return 0;
296
297 /* EVPN uses router id in RD, withdraw them */
298 if (is_evpn_enabled())
299 bgp_evpn_handle_router_id_update(bgp, true);
300
301 vpn_handle_router_id_update(bgp, true, is_config);
302
303 IPV4_ADDR_COPY(&bgp->router_id, id);
304
305 /* Set all peer's local identifier with this value. */
306 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
307 IPV4_ADDR_COPY(&peer->local_id, id);
308
309 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
310 peer->last_reset = PEER_DOWN_RID_CHANGE;
311 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
312 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
313 }
314 }
315
316 /* EVPN uses router id in RD, update them */
317 if (is_evpn_enabled())
318 bgp_evpn_handle_router_id_update(bgp, false);
319
320 vpn_handle_router_id_update(bgp, false, is_config);
321
322 return 0;
323 }
324
325 void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id)
326 {
327 struct listnode *node, *nnode;
328 struct bgp *bgp;
329 struct in_addr *addr = NULL;
330
331 if (router_id != NULL)
332 addr = (struct in_addr *)&(router_id->u.prefix4);
333
334 if (vrf_id == VRF_DEFAULT) {
335 /* Router-id change for default VRF has to also update all
336 * views. */
337 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
338 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
339 continue;
340
341 if (addr)
342 bgp->router_id_zebra = *addr;
343 else
344 addr = &bgp->router_id_zebra;
345
346 if (!bgp->router_id_static.s_addr) {
347 /* Router ID is updated if there are no active
348 * peer sessions
349 */
350 if (bgp->established_peers == 0) {
351 if (BGP_DEBUG(zebra, ZEBRA))
352 zlog_debug(
353 "RID change : vrf %s(%u), RTR ID %pI4",
354 bgp->name_pretty,
355 bgp->vrf_id, addr);
356 /*
357 * if old router-id was 0x0, set flag
358 * to use this new value
359 */
360 bgp_router_id_set(bgp, addr,
361 (bgp->router_id.s_addr
362 == INADDR_ANY)
363 ? true
364 : false);
365 }
366 }
367 }
368 } else {
369 bgp = bgp_lookup_by_vrf_id(vrf_id);
370 if (bgp) {
371 if (addr)
372 bgp->router_id_zebra = *addr;
373 else
374 addr = &bgp->router_id_zebra;
375
376 if (!bgp->router_id_static.s_addr) {
377 /* Router ID is updated if there are no active
378 * peer sessions
379 */
380 if (bgp->established_peers == 0) {
381 if (BGP_DEBUG(zebra, ZEBRA))
382 zlog_debug(
383 "RID change : vrf %s(%u), RTR ID %pI4",
384 bgp->name_pretty,
385 bgp->vrf_id, addr);
386 /*
387 * if old router-id was 0x0, set flag
388 * to use this new value
389 */
390 bgp_router_id_set(bgp, addr,
391 (bgp->router_id.s_addr
392 == INADDR_ANY)
393 ? true
394 : false);
395 }
396 }
397
398 }
399 }
400 }
401
402 void bgp_router_id_static_set(struct bgp *bgp, struct in_addr id)
403 {
404 bgp->router_id_static = id;
405 bgp_router_id_set(bgp,
406 id.s_addr != INADDR_ANY ? &id : &bgp->router_id_zebra,
407 true /* is config */);
408 }
409
410 void bm_wait_for_fib_set(bool set)
411 {
412 bool send_msg = false;
413
414 if (bm->wait_for_fib == set)
415 return;
416
417 bm->wait_for_fib = set;
418 if (set) {
419 if (bgp_suppress_fib_count == 0)
420 send_msg = true;
421 bgp_suppress_fib_count++;
422 } else {
423 bgp_suppress_fib_count--;
424 if (bgp_suppress_fib_count == 0)
425 send_msg = true;
426 }
427
428 if (send_msg && zclient)
429 zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST,
430 zclient, set);
431 }
432
433 /* Set the suppress fib pending for the bgp configuration */
434 void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set)
435 {
436 bool send_msg = false;
437
438 if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
439 return;
440
441 if (set) {
442 SET_FLAG(bgp->flags, BGP_FLAG_SUPPRESS_FIB_PENDING);
443 /* Send msg to zebra for the first instance of bgp enabled
444 * with suppress fib
445 */
446 if (bgp_suppress_fib_count == 0)
447 send_msg = true;
448 bgp_suppress_fib_count++;
449 } else {
450 UNSET_FLAG(bgp->flags, BGP_FLAG_SUPPRESS_FIB_PENDING);
451 bgp_suppress_fib_count--;
452
453 /* Send msg to zebra if there are no instances enabled
454 * with suppress fib
455 */
456 if (bgp_suppress_fib_count == 0)
457 send_msg = true;
458 }
459 /* Send route notify request to RIB */
460 if (send_msg) {
461 if (BGP_DEBUG(zebra, ZEBRA))
462 zlog_debug("Sending ZEBRA_ROUTE_NOTIFY_REQUEST");
463
464 if (zclient)
465 zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST,
466 zclient, set);
467 }
468 }
469
470 /* BGP's cluster-id control. */
471 void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
472 {
473 struct peer *peer;
474 struct listnode *node, *nnode;
475
476 if (bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID)
477 && IPV4_ADDR_SAME(&bgp->cluster_id, cluster_id))
478 return;
479
480 IPV4_ADDR_COPY(&bgp->cluster_id, cluster_id);
481 bgp_config_set(bgp, BGP_CONFIG_CLUSTER_ID);
482
483 /* Clear all IBGP peer. */
484 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
485 if (peer->sort != BGP_PEER_IBGP)
486 continue;
487
488 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
489 peer->last_reset = PEER_DOWN_CLID_CHANGE;
490 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
491 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
492 }
493 }
494 }
495
496 void bgp_cluster_id_unset(struct bgp *bgp)
497 {
498 struct peer *peer;
499 struct listnode *node, *nnode;
500
501 if (!bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID))
502 return;
503
504 bgp->cluster_id.s_addr = 0;
505 bgp_config_unset(bgp, BGP_CONFIG_CLUSTER_ID);
506
507 /* Clear all IBGP peer. */
508 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
509 if (peer->sort != BGP_PEER_IBGP)
510 continue;
511
512 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
513 peer->last_reset = PEER_DOWN_CLID_CHANGE;
514 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
515 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
516 }
517 }
518 }
519
520 /* BGP timer configuration. */
521 void bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime,
522 uint32_t connect_retry, uint32_t delayopen)
523 {
524 bgp->default_keepalive =
525 (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
526 bgp->default_holdtime = holdtime;
527 bgp->default_connect_retry = connect_retry;
528 bgp->default_delayopen = delayopen;
529 }
530
531 /* mostly for completeness - CLI uses its own defaults */
532 void bgp_timers_unset(struct bgp *bgp)
533 {
534 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
535 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
536 bgp->default_connect_retry = BGP_DEFAULT_CONNECT_RETRY;
537 bgp->default_delayopen = BGP_DEFAULT_DELAYOPEN;
538 }
539
540 void bgp_tcp_keepalive_set(struct bgp *bgp, uint16_t keepalive_idle,
541 uint16_t keepalive_intvl, uint16_t keepalive_probes)
542 {
543 bgp->tcp_keepalive_idle = keepalive_idle;
544 bgp->tcp_keepalive_intvl = keepalive_intvl;
545 bgp->tcp_keepalive_probes = keepalive_probes;
546 }
547
548 void bgp_tcp_keepalive_unset(struct bgp *bgp)
549 {
550 bgp->tcp_keepalive_idle = 0;
551 bgp->tcp_keepalive_intvl = 0;
552 bgp->tcp_keepalive_probes = 0;
553 }
554
555 /* BGP confederation configuration. */
556 void bgp_confederation_id_set(struct bgp *bgp, as_t as, const char *as_str)
557 {
558 struct peer *peer;
559 struct listnode *node, *nnode;
560 int already_confed;
561
562 if (as == 0)
563 return;
564
565 /* Remember - were we doing confederation before? */
566 already_confed = bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION);
567 bgp->confed_id = as;
568 if (bgp->confed_id_pretty)
569 XFREE(MTYPE_BGP, bgp->confed_id_pretty);
570 bgp->confed_id_pretty = XSTRDUP(MTYPE_BGP, as_str);
571 bgp_config_set(bgp, BGP_CONFIG_CONFEDERATION);
572
573 /* If we were doing confederation already, this is just an external
574 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
575 were not doing confederation before, reset all EBGP sessions. */
576 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
577 enum bgp_peer_sort ptype = peer_sort(peer);
578
579 /* We're looking for peers who's AS is not local or part of our
580 confederation. */
581 if (already_confed) {
582 if (ptype == BGP_PEER_EBGP) {
583 peer->local_as = as;
584 if (BGP_IS_VALID_STATE_FOR_NOTIF(
585 peer->status)) {
586 peer->last_reset =
587 PEER_DOWN_CONFED_ID_CHANGE;
588 bgp_notify_send(
589 peer, BGP_NOTIFY_CEASE,
590 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
591 } else
592 bgp_session_reset_safe(peer, &nnode);
593 }
594 } else {
595 /* Not doign confederation before, so reset every
596 non-local
597 session */
598 if (ptype != BGP_PEER_IBGP) {
599 /* Reset the local_as to be our EBGP one */
600 if (ptype == BGP_PEER_EBGP)
601 peer->local_as = as;
602 if (BGP_IS_VALID_STATE_FOR_NOTIF(
603 peer->status)) {
604 peer->last_reset =
605 PEER_DOWN_CONFED_ID_CHANGE;
606 bgp_notify_send(
607 peer, BGP_NOTIFY_CEASE,
608 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
609 } else
610 bgp_session_reset_safe(peer, &nnode);
611 }
612 }
613 }
614 return;
615 }
616
617 void bgp_confederation_id_unset(struct bgp *bgp)
618 {
619 struct peer *peer;
620 struct listnode *node, *nnode;
621
622 bgp->confed_id = 0;
623 XFREE(MTYPE_BGP, bgp->confed_id_pretty);
624 bgp_config_unset(bgp, BGP_CONFIG_CONFEDERATION);
625
626 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
627 /* We're looking for peers who's AS is not local */
628 if (peer_sort(peer) != BGP_PEER_IBGP) {
629 peer->local_as = bgp->as;
630 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
631 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
632 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
633 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
634 }
635
636 else
637 bgp_session_reset_safe(peer, &nnode);
638 }
639 }
640 }
641
642 /* Is an AS part of the confed or not? */
643 bool bgp_confederation_peers_check(struct bgp *bgp, as_t as)
644 {
645 int i;
646
647 if (!bgp)
648 return false;
649
650 for (i = 0; i < bgp->confed_peers_cnt; i++)
651 if (bgp->confed_peers[i].as == as)
652 return true;
653
654 return false;
655 }
656
657 /* Add an AS to the confederation set. */
658 void bgp_confederation_peers_add(struct bgp *bgp, as_t as, const char *as_str)
659 {
660 struct peer *peer;
661 struct listnode *node, *nnode;
662
663 if (!bgp)
664 return;
665
666 if (bgp_confederation_peers_check(bgp, as))
667 return;
668
669 bgp->confed_peers = XREALLOC(MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
670 (bgp->confed_peers_cnt + 1) *
671 sizeof(struct as_confed));
672
673 bgp->confed_peers[bgp->confed_peers_cnt].as = as;
674 bgp->confed_peers[bgp->confed_peers_cnt].as_pretty =
675 XSTRDUP(MTYPE_BGP, as_str);
676 bgp->confed_peers_cnt++;
677
678 if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
679 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
680 if (peer->as == as) {
681 peer->local_as = bgp->as;
682 (void)peer_sort(peer);
683 if (BGP_IS_VALID_STATE_FOR_NOTIF(
684 peer->status)) {
685 peer->last_reset =
686 PEER_DOWN_CONFED_PEER_CHANGE;
687 bgp_notify_send(
688 peer, BGP_NOTIFY_CEASE,
689 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
690 } else
691 bgp_session_reset_safe(peer, &nnode);
692 }
693 }
694 }
695 }
696
697 /* Delete an AS from the confederation set. */
698 void bgp_confederation_peers_remove(struct bgp *bgp, as_t as)
699 {
700 int i;
701 int j;
702 struct peer *peer;
703 struct listnode *node, *nnode;
704
705 if (!bgp)
706 return;
707
708 if (!bgp_confederation_peers_check(bgp, as))
709 return;
710
711 for (i = 0; i < bgp->confed_peers_cnt; i++)
712 if (bgp->confed_peers[i].as == as) {
713 XFREE(MTYPE_BGP, bgp->confed_peers[i].as_pretty);
714 for (j = i + 1; j < bgp->confed_peers_cnt; j++) {
715 bgp->confed_peers[j - 1].as =
716 bgp->confed_peers[j].as;
717 bgp->confed_peers[j - 1].as_pretty =
718 bgp->confed_peers[j].as_pretty;
719 }
720 }
721
722 bgp->confed_peers_cnt--;
723
724 if (bgp->confed_peers_cnt == 0) {
725 if (bgp->confed_peers)
726 XFREE(MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
727 bgp->confed_peers = NULL;
728 } else
729 bgp->confed_peers = XREALLOC(
730 MTYPE_BGP_CONFED_LIST, bgp->confed_peers,
731 bgp->confed_peers_cnt * sizeof(struct as_confed));
732
733 /* Now reset any peer who's remote AS has just been removed from the
734 CONFED */
735 if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)) {
736 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
737 if (peer->as == as) {
738 peer->local_as = bgp->confed_id;
739 (void)peer_sort(peer);
740 if (BGP_IS_VALID_STATE_FOR_NOTIF(
741 peer->status)) {
742 peer->last_reset =
743 PEER_DOWN_CONFED_PEER_CHANGE;
744 bgp_notify_send(
745 peer, BGP_NOTIFY_CEASE,
746 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
747 } else
748 bgp_session_reset_safe(peer, &nnode);
749 }
750 }
751 }
752 }
753
754 /* Local preference configuration. */
755 void bgp_default_local_preference_set(struct bgp *bgp, uint32_t local_pref)
756 {
757 if (!bgp)
758 return;
759
760 bgp->default_local_pref = local_pref;
761 }
762
763 void bgp_default_local_preference_unset(struct bgp *bgp)
764 {
765 if (!bgp)
766 return;
767
768 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
769 }
770
771 /* Local preference configuration. */
772 void bgp_default_subgroup_pkt_queue_max_set(struct bgp *bgp,
773 uint32_t queue_size)
774 {
775 if (!bgp)
776 return;
777
778 bgp->default_subgroup_pkt_queue_max = queue_size;
779 }
780
781 void bgp_default_subgroup_pkt_queue_max_unset(struct bgp *bgp)
782 {
783 if (!bgp)
784 return;
785 bgp->default_subgroup_pkt_queue_max =
786 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
787 }
788
789 /* Listen limit configuration. */
790 void bgp_listen_limit_set(struct bgp *bgp, int listen_limit)
791 {
792 if (!bgp)
793 return;
794
795 bgp->dynamic_neighbors_limit = listen_limit;
796 }
797
798 void bgp_listen_limit_unset(struct bgp *bgp)
799 {
800 if (!bgp)
801 return;
802
803 bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
804 }
805
806 int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
807 afi_t *afi, safi_t *safi)
808 {
809 /* Map from IANA values to internal values, return error if
810 * values are unrecognized.
811 */
812 *afi = afi_iana2int(pkt_afi);
813 *safi = safi_iana2int(pkt_safi);
814 if (*afi == AFI_MAX || *safi == SAFI_MAX)
815 return -1;
816
817 return 0;
818 }
819
820 int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi, iana_afi_t *pkt_afi,
821 iana_safi_t *pkt_safi)
822 {
823 /* Map from internal values to IANA values, return error if
824 * internal values are bad (unexpected).
825 */
826 if (afi == AFI_MAX || safi == SAFI_MAX)
827 return -1;
828 *pkt_afi = afi_int2iana(afi);
829 *pkt_safi = safi_int2iana(safi);
830 return 0;
831 }
832
833 struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi)
834 {
835 struct peer_af *af;
836 int afid;
837 struct bgp *bgp;
838
839 if (!peer)
840 return NULL;
841
842 afid = afindex(afi, safi);
843 if (afid >= BGP_AF_MAX)
844 return NULL;
845
846 bgp = peer->bgp;
847 assert(peer->peer_af_array[afid] == NULL);
848
849 /* Allocate new peer af */
850 af = XCALLOC(MTYPE_BGP_PEER_AF, sizeof(struct peer_af));
851
852 peer->peer_af_array[afid] = af;
853 af->afi = afi;
854 af->safi = safi;
855 af->afid = afid;
856 af->peer = peer;
857 bgp->af_peer_count[afi][safi]++;
858
859 return af;
860 }
861
862 struct peer_af *peer_af_find(struct peer *peer, afi_t afi, safi_t safi)
863 {
864 int afid;
865
866 if (!peer)
867 return NULL;
868
869 afid = afindex(afi, safi);
870 if (afid >= BGP_AF_MAX)
871 return NULL;
872
873 return peer->peer_af_array[afid];
874 }
875
876 int peer_af_delete(struct peer *peer, afi_t afi, safi_t safi)
877 {
878 struct peer_af *af;
879 int afid;
880 struct bgp *bgp;
881
882 if (!peer)
883 return -1;
884
885 afid = afindex(afi, safi);
886 if (afid >= BGP_AF_MAX)
887 return -1;
888
889 af = peer->peer_af_array[afid];
890 if (!af)
891 return -1;
892
893 bgp = peer->bgp;
894 bgp_soft_reconfig_table_task_cancel(bgp, bgp->rib[afi][safi], peer);
895
896 bgp_stop_announce_route_timer(af);
897
898 if (PAF_SUBGRP(af)) {
899 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
900 zlog_debug("u%" PRIu64 ":s%" PRIu64 " remove peer %s",
901 af->subgroup->update_group->id,
902 af->subgroup->id, peer->host);
903 }
904
905
906 update_subgroup_remove_peer(af->subgroup, af);
907
908 if (bgp->af_peer_count[afi][safi])
909 bgp->af_peer_count[afi][safi]--;
910
911 peer->peer_af_array[afid] = NULL;
912 XFREE(MTYPE_BGP_PEER_AF, af);
913 return 0;
914 }
915
916 /* Peer comparison function for sorting. */
917 int peer_cmp(struct peer *p1, struct peer *p2)
918 {
919 if (p1->group && !p2->group)
920 return -1;
921
922 if (!p1->group && p2->group)
923 return 1;
924
925 if (p1->group == p2->group) {
926 if (p1->conf_if && !p2->conf_if)
927 return -1;
928
929 if (!p1->conf_if && p2->conf_if)
930 return 1;
931
932 if (p1->conf_if && p2->conf_if)
933 return if_cmp_name_func(p1->conf_if, p2->conf_if);
934 } else
935 return strcmp(p1->group->name, p2->group->name);
936
937 return sockunion_cmp(&p1->su, &p2->su);
938 }
939
940 static unsigned int peer_hash_key_make(const void *p)
941 {
942 const struct peer *peer = p;
943 return sockunion_hash(&peer->su);
944 }
945
946 static bool peer_hash_same(const void *p1, const void *p2)
947 {
948 const struct peer *peer1 = p1;
949 const struct peer *peer2 = p2;
950
951 return (sockunion_same(&peer1->su, &peer2->su)
952 && CHECK_FLAG(peer1->flags, PEER_FLAG_CONFIG_NODE)
953 == CHECK_FLAG(peer2->flags, PEER_FLAG_CONFIG_NODE));
954 }
955
956 void peer_flag_inherit(struct peer *peer, uint64_t flag)
957 {
958 bool group_val;
959
960 /* Skip if peer is not a peer-group member. */
961 if (!peer_group_active(peer))
962 return;
963
964 /* Unset override flag to signal inheritance from peer-group. */
965 UNSET_FLAG(peer->flags_override, flag);
966
967 /*
968 * Inherit flag state from peer-group. If the flag of the peer-group is
969 * not being inverted, the peer must inherit the inverse of the current
970 * peer-group flag state.
971 */
972 group_val = CHECK_FLAG(peer->group->conf->flags, flag);
973 if (!CHECK_FLAG(peer->group->conf->flags_invert, flag)
974 && CHECK_FLAG(peer->flags_invert, flag))
975 COND_FLAG(peer->flags, flag, !group_val);
976 else
977 COND_FLAG(peer->flags, flag, group_val);
978 }
979
980 int peer_af_flag_check(struct peer *peer, afi_t afi, safi_t safi, uint32_t flag)
981 {
982 return CHECK_FLAG(peer->af_flags[afi][safi], flag);
983 }
984
985 void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi,
986 uint64_t flag)
987 {
988 bool group_val;
989
990 /* Skip if peer is not a peer-group member. */
991 if (!peer_group_active(peer))
992 return;
993
994 /* Unset override flag to signal inheritance from peer-group. */
995 UNSET_FLAG(peer->af_flags_override[afi][safi], flag);
996
997 /*
998 * Inherit flag state from peer-group. If the flag of the peer-group is
999 * not being inverted, the peer must inherit the inverse of the current
1000 * peer-group flag state.
1001 */
1002 group_val = CHECK_FLAG(peer->group->conf->af_flags[afi][safi], flag);
1003 if (!CHECK_FLAG(peer->group->conf->af_flags_invert[afi][safi], flag)
1004 && CHECK_FLAG(peer->af_flags_invert[afi][safi], flag))
1005 COND_FLAG(peer->af_flags[afi][safi], flag, !group_val);
1006 else
1007 COND_FLAG(peer->af_flags[afi][safi], flag, group_val);
1008 }
1009
1010 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
1011 static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer)
1012 {
1013 struct bgp *bgp;
1014 as_t local_as;
1015
1016 bgp = peer->bgp;
1017
1018 if (peer->change_local_as)
1019 local_as = peer->change_local_as;
1020 else
1021 local_as = peer->local_as;
1022
1023 /* Peer-group */
1024 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
1025 if (peer->as_type == AS_INTERNAL)
1026 return BGP_PEER_IBGP;
1027
1028 else if (peer->as_type == AS_EXTERNAL)
1029 return BGP_PEER_EBGP;
1030
1031 else if (peer->as_type == AS_SPECIFIED && peer->as) {
1032 assert(bgp);
1033 return (local_as == peer->as ? BGP_PEER_IBGP
1034 : BGP_PEER_EBGP);
1035 }
1036
1037 else {
1038 struct peer *peer1;
1039
1040 assert(peer->group);
1041 peer1 = listnode_head(peer->group->peer);
1042
1043 if (peer1)
1044 return peer1->sort;
1045 }
1046 return BGP_PEER_INTERNAL;
1047 }
1048
1049 /* Normal peer */
1050 if (bgp && CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1051 if (local_as == 0)
1052 return BGP_PEER_INTERNAL;
1053
1054 if (local_as == peer->as) {
1055 if (bgp->as == bgp->confed_id) {
1056 if (local_as == bgp->as)
1057 return BGP_PEER_IBGP;
1058 else
1059 return BGP_PEER_EBGP;
1060 } else {
1061 if (local_as == bgp->confed_id)
1062 return BGP_PEER_EBGP;
1063 else
1064 return BGP_PEER_IBGP;
1065 }
1066 }
1067
1068 if (bgp_confederation_peers_check(bgp, peer->as))
1069 return BGP_PEER_CONFED;
1070
1071 return BGP_PEER_EBGP;
1072 } else {
1073 if (peer->as_type == AS_UNSPECIFIED) {
1074 /* check if in peer-group with AS information */
1075 if (peer->group
1076 && (peer->group->conf->as_type != AS_UNSPECIFIED)) {
1077 if (peer->group->conf->as_type
1078 == AS_SPECIFIED) {
1079 if (local_as == peer->group->conf->as)
1080 return BGP_PEER_IBGP;
1081 else
1082 return BGP_PEER_EBGP;
1083 } else if (peer->group->conf->as_type
1084 == AS_INTERNAL)
1085 return BGP_PEER_IBGP;
1086 else
1087 return BGP_PEER_EBGP;
1088 }
1089 /* no AS information anywhere, let caller know */
1090 return BGP_PEER_UNSPECIFIED;
1091 } else if (peer->as_type != AS_SPECIFIED)
1092 return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP
1093 : BGP_PEER_EBGP);
1094
1095 return (local_as == 0 ? BGP_PEER_INTERNAL
1096 : local_as == peer->as ? BGP_PEER_IBGP
1097 : BGP_PEER_EBGP);
1098 }
1099 }
1100
1101 /* Calculate and cache the peer "sort" */
1102 enum bgp_peer_sort peer_sort(struct peer *peer)
1103 {
1104 peer->sort = peer_calc_sort(peer);
1105 return peer->sort;
1106 }
1107
1108 enum bgp_peer_sort peer_sort_lookup(struct peer *peer)
1109 {
1110 return peer->sort;
1111 }
1112
1113 static void peer_free(struct peer *peer)
1114 {
1115 afi_t afi;
1116 safi_t safi;
1117
1118 assert(peer->status == Deleted);
1119
1120 QOBJ_UNREG(peer);
1121
1122 /* this /ought/ to have been done already through bgp_stop earlier,
1123 * but just to be sure..
1124 */
1125 bgp_timer_set(peer);
1126 bgp_reads_off(peer);
1127 bgp_writes_off(peer);
1128 thread_cancel_event_ready(bm->master, peer);
1129 FOREACH_AFI_SAFI (afi, safi)
1130 THREAD_OFF(peer->t_revalidate_all[afi][safi]);
1131 assert(!peer->t_write);
1132 assert(!peer->t_read);
1133 BGP_EVENT_FLUSH(peer);
1134
1135 pthread_mutex_destroy(&peer->io_mtx);
1136
1137 /* Free connected nexthop, if present */
1138 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
1139 && !peer_dynamic_neighbor(peer))
1140 bgp_delete_connected_nexthop(family2afi(peer->su.sa.sa_family),
1141 peer);
1142
1143 FOREACH_AFI_SAFI (afi, safi) {
1144 if (peer->filter[afi][safi].advmap.aname)
1145 XFREE(MTYPE_BGP_FILTER_NAME,
1146 peer->filter[afi][safi].advmap.aname);
1147 if (peer->filter[afi][safi].advmap.cname)
1148 XFREE(MTYPE_BGP_FILTER_NAME,
1149 peer->filter[afi][safi].advmap.cname);
1150 }
1151
1152 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
1153
1154 XFREE(MTYPE_PEER_DESC, peer->desc);
1155 XFREE(MTYPE_BGP_PEER_HOST, peer->host);
1156 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
1157 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
1158 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
1159
1160 /* Update source configuration. */
1161 if (peer->update_source) {
1162 sockunion_free(peer->update_source);
1163 peer->update_source = NULL;
1164 }
1165
1166 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1167
1168 XFREE(MTYPE_BGP_NOTIFICATION, peer->notify.data);
1169 memset(&peer->notify, 0, sizeof(struct bgp_notify));
1170
1171 if (peer->clear_node_queue)
1172 work_queue_free_and_null(&peer->clear_node_queue);
1173
1174 bgp_sync_delete(peer);
1175
1176 XFREE(MTYPE_PEER_CONF_IF, peer->conf_if);
1177
1178 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
1179
1180 /* Remove BFD configuration. */
1181 if (peer->bfd_config)
1182 bgp_peer_remove_bfd_config(peer);
1183
1184 FOREACH_AFI_SAFI (afi, safi)
1185 bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE);
1186
1187 if (peer->change_local_as_pretty)
1188 XFREE(MTYPE_BGP, peer->change_local_as_pretty);
1189 if (peer->as_pretty)
1190 XFREE(MTYPE_BGP, peer->as_pretty);
1191
1192 bgp_unlock(peer->bgp);
1193
1194 memset(peer, 0, sizeof(struct peer));
1195
1196 XFREE(MTYPE_BGP_PEER, peer);
1197 }
1198
1199 /* increase reference count on a struct peer */
1200 struct peer *peer_lock_with_caller(const char *name, struct peer *peer)
1201 {
1202 frrtrace(2, frr_bgp, bgp_peer_lock, peer, name);
1203 assert(peer && (peer->lock >= 0));
1204
1205 peer->lock++;
1206
1207 return peer;
1208 }
1209
1210 /* decrease reference count on a struct peer
1211 * struct peer is freed and NULL returned if last reference
1212 */
1213 struct peer *peer_unlock_with_caller(const char *name, struct peer *peer)
1214 {
1215 frrtrace(2, frr_bgp, bgp_peer_unlock, peer, name);
1216 assert(peer && (peer->lock > 0));
1217
1218 peer->lock--;
1219
1220 if (peer->lock == 0) {
1221 peer_free(peer);
1222 return NULL;
1223 }
1224
1225 return peer;
1226 }
1227 /* BGP GR changes */
1228
1229 int bgp_global_gr_init(struct bgp *bgp)
1230 {
1231 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1232 zlog_debug("%s called ..", __func__);
1233
1234 int local_GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE][BGP_GLOBAL_GR_EVENT_CMD] = {
1235 /* GLOBAL_HELPER Mode */
1236 {
1237 /*Event -> */
1238 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1239 GLOBAL_GR, GLOBAL_INVALID,
1240 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1241 GLOBAL_DISABLE, GLOBAL_INVALID
1242 },
1243 /* GLOBAL_GR Mode */
1244 {
1245 /*Event -> */
1246 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1247 GLOBAL_GR, GLOBAL_HELPER,
1248 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1249 GLOBAL_DISABLE, GLOBAL_INVALID
1250 },
1251 /* GLOBAL_DISABLE Mode */
1252 {
1253 /*Event -> */
1254 /*GLOBAL_GR_cmd */ /*no_Global_GR_cmd*/
1255 GLOBAL_GR, GLOBAL_INVALID,
1256 /*GLOBAL_DISABLE_cmd*//*no_Global_Disable_cmd*/
1257 GLOBAL_INVALID, GLOBAL_HELPER
1258 },
1259 /* GLOBAL_INVALID Mode */
1260 {
1261 /*Event -> */
1262 /*GLOBAL_GR_cmd*/ /*no_Global_GR_cmd*/
1263 GLOBAL_INVALID, GLOBAL_INVALID,
1264 /*GLOBAL_DISABLE_cmd*/ /*no_Global_Disable_cmd*/
1265 GLOBAL_INVALID, GLOBAL_INVALID
1266 }
1267 };
1268 memcpy(bgp->GLOBAL_GR_FSM, local_GLOBAL_GR_FSM,
1269 sizeof(local_GLOBAL_GR_FSM));
1270
1271 bgp->global_gr_present_state = GLOBAL_HELPER;
1272 bgp->present_zebra_gr_state = ZEBRA_GR_DISABLE;
1273
1274 return BGP_GR_SUCCESS;
1275 }
1276
1277 int bgp_peer_gr_init(struct peer *peer)
1278 {
1279 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1280 zlog_debug("%s called ..", __func__);
1281
1282 struct bgp_peer_gr local_Peer_GR_FSM[BGP_PEER_GR_MODE]
1283 [BGP_PEER_GR_EVENT_CMD] = {
1284 {
1285 /* PEER_HELPER Mode */
1286 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1287 { PEER_GR, bgp_peer_gr_action }, {PEER_INVALID, NULL },
1288 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1289 {PEER_DISABLE, bgp_peer_gr_action }, {PEER_INVALID, NULL },
1290 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1291 { PEER_INVALID, NULL }, {PEER_GLOBAL_INHERIT,
1292 bgp_peer_gr_action }
1293 },
1294 {
1295 /* PEER_GR Mode */
1296 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1297 { PEER_INVALID, NULL }, { PEER_GLOBAL_INHERIT,
1298 bgp_peer_gr_action },
1299 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1300 {PEER_DISABLE, bgp_peer_gr_action }, { PEER_INVALID, NULL },
1301 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1302 { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
1303 },
1304 {
1305 /* PEER_DISABLE Mode */
1306 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1307 { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL },
1308 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1309 { PEER_INVALID, NULL }, { PEER_GLOBAL_INHERIT,
1310 bgp_peer_gr_action },
1311 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1312 { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
1313 },
1314 {
1315 /* PEER_INVALID Mode */
1316 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1317 { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
1318 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1319 { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
1320 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1321 { PEER_INVALID, NULL }, { PEER_INVALID, NULL },
1322 },
1323 {
1324 /* PEER_GLOBAL_INHERIT Mode */
1325 /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */
1326 { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL },
1327 /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */
1328 { PEER_DISABLE, bgp_peer_gr_action}, { PEER_INVALID, NULL },
1329 /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */
1330 { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL }
1331 }
1332 };
1333 memcpy(&peer->PEER_GR_FSM, local_Peer_GR_FSM,
1334 sizeof(local_Peer_GR_FSM));
1335 peer->peer_gr_present_state = PEER_GLOBAL_INHERIT;
1336 bgp_peer_move_to_gr_mode(peer, PEER_GLOBAL_INHERIT);
1337
1338 return BGP_GR_SUCCESS;
1339 }
1340
1341 static void bgp_srv6_init(struct bgp *bgp)
1342 {
1343 bgp->srv6_enabled = false;
1344 memset(bgp->srv6_locator_name, 0, sizeof(bgp->srv6_locator_name));
1345 bgp->srv6_locator_chunks = list_new();
1346 bgp->srv6_functions = list_new();
1347 }
1348
1349 static void bgp_srv6_cleanup(struct bgp *bgp)
1350 {
1351 if (bgp->srv6_locator_chunks)
1352 list_delete(&bgp->srv6_locator_chunks);
1353 if (bgp->srv6_functions)
1354 list_delete(&bgp->srv6_functions);
1355 }
1356
1357 /* Allocate new peer object, implicitely locked. */
1358 struct peer *peer_new(struct bgp *bgp)
1359 {
1360 afi_t afi;
1361 safi_t safi;
1362 struct peer *peer;
1363 struct servent *sp;
1364
1365 /* bgp argument is absolutely required */
1366 assert(bgp);
1367
1368 /* Allocate new peer. */
1369 peer = XCALLOC(MTYPE_BGP_PEER, sizeof(struct peer));
1370
1371 /* Set default value. */
1372 peer->fd = -1;
1373 peer->v_start = BGP_INIT_START_TIMER;
1374 peer->v_connect = bgp->default_connect_retry;
1375 peer->status = Idle;
1376 peer->ostatus = Idle;
1377 peer->cur_event = peer->last_event = peer->last_major_event = 0;
1378 peer->bgp = bgp_lock(bgp);
1379 peer = peer_lock(peer); /* initial reference */
1380 peer->local_role = ROLE_UNDEFINED;
1381 peer->remote_role = ROLE_UNDEFINED;
1382 peer->password = NULL;
1383 peer->max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
1384
1385 /* Set default flags. */
1386 FOREACH_AFI_SAFI (afi, safi) {
1387 SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
1388 SET_FLAG(peer->af_flags[afi][safi],
1389 PEER_FLAG_SEND_EXT_COMMUNITY);
1390 SET_FLAG(peer->af_flags[afi][safi],
1391 PEER_FLAG_SEND_LARGE_COMMUNITY);
1392
1393 SET_FLAG(peer->af_flags_invert[afi][safi],
1394 PEER_FLAG_SEND_COMMUNITY);
1395 SET_FLAG(peer->af_flags_invert[afi][safi],
1396 PEER_FLAG_SEND_EXT_COMMUNITY);
1397 SET_FLAG(peer->af_flags_invert[afi][safi],
1398 PEER_FLAG_SEND_LARGE_COMMUNITY);
1399 peer->addpath_type[afi][safi] = BGP_ADDPATH_NONE;
1400 peer->soo[afi][safi] = NULL;
1401 }
1402
1403 /* set nexthop-unchanged for l2vpn evpn by default */
1404 SET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
1405 PEER_FLAG_NEXTHOP_UNCHANGED);
1406
1407 SET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
1408
1409 /* Initialize per peer bgp GR FSM */
1410 bgp_peer_gr_init(peer);
1411
1412 /* Create buffers. */
1413 peer->ibuf = stream_fifo_new();
1414 peer->obuf = stream_fifo_new();
1415 pthread_mutex_init(&peer->io_mtx, NULL);
1416
1417 /* We use a larger buffer for peer->obuf_work in the event that:
1418 * - We RX a BGP_UPDATE where the attributes alone are just
1419 * under BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE.
1420 * - The user configures an outbound route-map that does many as-path
1421 * prepends or adds many communities. At most they can have
1422 * CMD_ARGC_MAX args in a route-map so there is a finite limit on how
1423 * large they can make the attributes.
1424 *
1425 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
1426 * bounds checking for every single attribute as we construct an
1427 * UPDATE.
1428 */
1429 peer->obuf_work =
1430 stream_new(BGP_MAX_PACKET_SIZE + BGP_MAX_PACKET_SIZE_OVERFLOW);
1431 peer->ibuf_work =
1432 ringbuf_new(BGP_MAX_PACKET_SIZE * BGP_READ_PACKET_MAX);
1433
1434 peer->scratch = stream_new(BGP_MAX_PACKET_SIZE);
1435
1436 bgp_sync_init(peer);
1437
1438 /* Get service port number. */
1439 sp = getservbyname("bgp", "tcp");
1440 peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs(sp->s_port);
1441
1442 QOBJ_REG(peer, peer);
1443 return peer;
1444 }
1445
1446 /*
1447 * This function is invoked when a duplicate peer structure associated with
1448 * a neighbor is being deleted. If this about-to-be-deleted structure is
1449 * the one with all the config, then we have to copy over the info.
1450 */
1451 void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
1452 {
1453 struct peer_af *paf;
1454 afi_t afi;
1455 safi_t safi;
1456 int afidx;
1457
1458 assert(peer_src);
1459 assert(peer_dst);
1460
1461 /* The following function is used by both peer group config copy to
1462 * individual peer and when we transfer config
1463 */
1464 if (peer_src->change_local_as)
1465 peer_dst->change_local_as = peer_src->change_local_as;
1466
1467 /* peer flags apply */
1468 peer_dst->flags = peer_src->flags;
1469 /*
1470 * The doppelganger *must* not have a config node stored
1471 */
1472 UNSET_FLAG(peer_dst->flags, PEER_FLAG_CONFIG_NODE);
1473 peer_dst->peer_gr_present_state = peer_src->peer_gr_present_state;
1474 peer_dst->peer_gr_new_status_flag = peer_src->peer_gr_new_status_flag;
1475
1476 peer_dst->local_as = peer_src->local_as;
1477 peer_dst->port = peer_src->port;
1478 /* copy tcp_mss value */
1479 peer_dst->tcp_mss = peer_src->tcp_mss;
1480 (void)peer_sort(peer_dst);
1481 peer_dst->rmap_type = peer_src->rmap_type;
1482 peer_dst->local_role = peer_src->local_role;
1483
1484 peer_dst->max_packet_size = peer_src->max_packet_size;
1485
1486 /* Timers */
1487 peer_dst->holdtime = peer_src->holdtime;
1488 peer_dst->keepalive = peer_src->keepalive;
1489 peer_dst->connect = peer_src->connect;
1490 peer_dst->delayopen = peer_src->delayopen;
1491 peer_dst->v_holdtime = peer_src->v_holdtime;
1492 peer_dst->v_keepalive = peer_src->v_keepalive;
1493 peer_dst->routeadv = peer_src->routeadv;
1494 peer_dst->v_routeadv = peer_src->v_routeadv;
1495 peer_dst->v_delayopen = peer_src->v_delayopen;
1496
1497 /* password apply */
1498 if (peer_src->password && !peer_dst->password)
1499 peer_dst->password =
1500 XSTRDUP(MTYPE_PEER_PASSWORD, peer_src->password);
1501
1502 FOREACH_AFI_SAFI (afi, safi) {
1503 peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
1504 peer_dst->af_flags[afi][safi] = peer_src->af_flags[afi][safi];
1505 peer_dst->allowas_in[afi][safi] =
1506 peer_src->allowas_in[afi][safi];
1507 peer_dst->weight[afi][safi] = peer_src->weight[afi][safi];
1508 peer_dst->addpath_type[afi][safi] =
1509 peer_src->addpath_type[afi][safi];
1510 }
1511
1512 for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
1513 paf = peer_src->peer_af_array[afidx];
1514 if (paf != NULL) {
1515 if (!peer_af_find(peer_dst, paf->afi, paf->safi))
1516 peer_af_create(peer_dst, paf->afi, paf->safi);
1517 }
1518 }
1519
1520 /* update-source apply */
1521 if (peer_src->update_source) {
1522 if (peer_dst->update_source)
1523 sockunion_free(peer_dst->update_source);
1524 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer_dst->update_if);
1525 peer_dst->update_source =
1526 sockunion_dup(peer_src->update_source);
1527 } else if (peer_src->update_if) {
1528 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer_dst->update_if);
1529 if (peer_dst->update_source) {
1530 sockunion_free(peer_dst->update_source);
1531 peer_dst->update_source = NULL;
1532 }
1533 peer_dst->update_if =
1534 XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, peer_src->update_if);
1535 }
1536
1537 if (peer_src->ifname) {
1538 XFREE(MTYPE_BGP_PEER_IFNAME, peer_dst->ifname);
1539
1540 peer_dst->ifname =
1541 XSTRDUP(MTYPE_BGP_PEER_IFNAME, peer_src->ifname);
1542 }
1543 }
1544
1545 static int bgp_peer_conf_if_to_su_update_v4(struct peer *peer,
1546 struct interface *ifp)
1547 {
1548 struct connected *ifc;
1549 struct prefix p;
1550 uint32_t addr;
1551 struct listnode *node;
1552
1553 /* If our IPv4 address on the interface is /30 or /31, we can derive the
1554 * IPv4 address of the other end.
1555 */
1556 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
1557 if (ifc->address && (ifc->address->family == AF_INET)) {
1558 prefix_copy(&p, CONNECTED_PREFIX(ifc));
1559 if (p.prefixlen == 30) {
1560 peer->su.sa.sa_family = AF_INET;
1561 addr = ntohl(p.u.prefix4.s_addr);
1562 if (addr % 4 == 1)
1563 peer->su.sin.sin_addr.s_addr =
1564 htonl(addr + 1);
1565 else if (addr % 4 == 2)
1566 peer->su.sin.sin_addr.s_addr =
1567 htonl(addr - 1);
1568 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1569 peer->su.sin.sin_len =
1570 sizeof(struct sockaddr_in);
1571 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1572 return 1;
1573 } else if (p.prefixlen == 31) {
1574 peer->su.sa.sa_family = AF_INET;
1575 addr = ntohl(p.u.prefix4.s_addr);
1576 if (addr % 2 == 0)
1577 peer->su.sin.sin_addr.s_addr =
1578 htonl(addr + 1);
1579 else
1580 peer->su.sin.sin_addr.s_addr =
1581 htonl(addr - 1);
1582 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1583 peer->su.sin.sin_len =
1584 sizeof(struct sockaddr_in);
1585 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
1586 return 1;
1587 } else if (bgp_debug_neighbor_events(peer))
1588 zlog_debug(
1589 "%s: IPv4 interface address is not /30 or /31, v4 session not started",
1590 peer->conf_if);
1591 }
1592 }
1593
1594 return 0;
1595 }
1596
1597 static bool bgp_peer_conf_if_to_su_update_v6(struct peer *peer,
1598 struct interface *ifp)
1599 {
1600 struct nbr_connected *ifc_nbr;
1601
1602 /* Have we learnt the peer's IPv6 link-local address? */
1603 if (ifp->nbr_connected
1604 && (ifc_nbr = listnode_head(ifp->nbr_connected))) {
1605 peer->su.sa.sa_family = AF_INET6;
1606 memcpy(&peer->su.sin6.sin6_addr, &ifc_nbr->address->u.prefix,
1607 sizeof(struct in6_addr));
1608 #ifdef SIN6_LEN
1609 peer->su.sin6.sin6_len = sizeof(struct sockaddr_in6);
1610 #endif
1611 peer->su.sin6.sin6_scope_id = ifp->ifindex;
1612 return true;
1613 }
1614
1615 return false;
1616 }
1617
1618 /*
1619 * Set or reset the peer address socketunion structure based on the
1620 * learnt/derived peer address. If the address has changed, update the
1621 * password on the listen socket, if needed.
1622 */
1623 void bgp_peer_conf_if_to_su_update(struct peer *peer)
1624 {
1625 struct interface *ifp;
1626 int prev_family;
1627 int peer_addr_updated = 0;
1628 struct listnode *node;
1629 union sockunion old_su;
1630
1631 /*
1632 * This function is only ever needed when FRR an interface
1633 * based peering, so this simple test will tell us if
1634 * we are in an interface based configuration or not
1635 */
1636 if (!peer->conf_if)
1637 return;
1638
1639 old_su = peer->su;
1640
1641 prev_family = peer->su.sa.sa_family;
1642 if ((ifp = if_lookup_by_name(peer->conf_if, peer->bgp->vrf_id))) {
1643 peer->ifp = ifp;
1644 /* If BGP unnumbered is not "v6only", we first see if we can
1645 * derive the
1646 * peer's IPv4 address.
1647 */
1648 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
1649 peer_addr_updated =
1650 bgp_peer_conf_if_to_su_update_v4(peer, ifp);
1651
1652 /* If "v6only" or we can't derive peer's IPv4 address, see if
1653 * we've
1654 * learnt the peer's IPv6 link-local address. This is from the
1655 * source
1656 * IPv6 address in router advertisement.
1657 */
1658 if (!peer_addr_updated)
1659 peer_addr_updated =
1660 bgp_peer_conf_if_to_su_update_v6(peer, ifp);
1661 }
1662 /* If we could derive the peer address, we may need to install the
1663 * password
1664 * configured for the peer, if any, on the listen socket. Otherwise,
1665 * mark
1666 * that peer's address is not available and uninstall the password, if
1667 * needed.
1668 */
1669 if (peer_addr_updated) {
1670 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)
1671 && prev_family == AF_UNSPEC)
1672 bgp_md5_set(peer);
1673 } else {
1674 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)
1675 && prev_family != AF_UNSPEC)
1676 bgp_md5_unset(peer);
1677 peer->su.sa.sa_family = AF_UNSPEC;
1678 memset(&peer->su.sin6.sin6_addr, 0, sizeof(struct in6_addr));
1679 }
1680
1681 /*
1682 * If they are the same, nothing to do here, move along
1683 */
1684 if (!sockunion_same(&old_su, &peer->su)) {
1685 union sockunion new_su = peer->su;
1686 struct bgp *bgp = peer->bgp;
1687
1688 /*
1689 * Our peer structure is stored in the bgp->peerhash
1690 * release it before we modify anything in both the
1691 * hash and the list. But *only* if the peer
1692 * is in the bgp->peerhash as that on deletion
1693 * we call bgp_stop which calls this function :(
1694 * so on deletion let's remove from the list first
1695 * and then do the deletion preventing this from
1696 * being added back on the list below when we
1697 * fail to remove it up here.
1698 */
1699
1700 /*
1701 * listnode_lookup just scans the list
1702 * for the peer structure so it's safe
1703 * to use without modifying the su
1704 */
1705 node = listnode_lookup(bgp->peer, peer);
1706 if (node) {
1707 /*
1708 * Let's reset the peer->su release and
1709 * reset it and put it back. We have to
1710 * do this because hash_release will
1711 * scan through looking for a matching
1712 * su if needed.
1713 */
1714 peer->su = old_su;
1715 hash_release(peer->bgp->peerhash, peer);
1716 listnode_delete(peer->bgp->peer, peer);
1717
1718 peer->su = new_su;
1719 (void)hash_get(peer->bgp->peerhash, peer,
1720 hash_alloc_intern);
1721 listnode_add_sort(peer->bgp->peer, peer);
1722 }
1723 }
1724 }
1725
1726 void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, safi_t safi)
1727 {
1728 struct bgp_dest *dest, *ndest;
1729 struct bgp_table *table;
1730
1731 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
1732 dest = bgp_route_next(dest)) {
1733 table = bgp_dest_get_bgp_table_info(dest);
1734 if (table != NULL) {
1735 /* Special handling for 2-level routing
1736 * tables. */
1737 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
1738 || safi == SAFI_EVPN) {
1739 for (ndest = bgp_table_top(table); ndest;
1740 ndest = bgp_route_next(ndest))
1741 bgp_process(bgp, ndest, afi, safi);
1742 } else
1743 bgp_process(bgp, dest, afi, safi);
1744 }
1745 }
1746 }
1747
1748 /* Force a bestpath recalculation for all prefixes. This is used
1749 * when 'bgp bestpath' commands are entered.
1750 */
1751 void bgp_recalculate_all_bestpaths(struct bgp *bgp)
1752 {
1753 afi_t afi;
1754 safi_t safi;
1755
1756 FOREACH_AFI_SAFI (afi, safi) {
1757 bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
1758 }
1759 }
1760
1761 /*
1762 * Create new BGP peer.
1763 *
1764 * conf_if and su are mutually exclusive if configuring from the cli.
1765 * If we are handing a doppelganger, then we *must* pass in both
1766 * the original peer's su and conf_if, so that we can appropriately
1767 * track the bgp->peerhash( ie we don't want to remove the current
1768 * one from the config ).
1769 */
1770 struct peer *peer_create(union sockunion *su, const char *conf_if,
1771 struct bgp *bgp, as_t local_as, as_t remote_as,
1772 int as_type, struct peer_group *group,
1773 bool config_node, const char *as_str)
1774 {
1775 int active;
1776 struct peer *peer;
1777 char buf[SU_ADDRSTRLEN];
1778 afi_t afi;
1779 safi_t safi;
1780
1781 peer = peer_new(bgp);
1782 if (conf_if) {
1783 peer->conf_if = XSTRDUP(MTYPE_PEER_CONF_IF, conf_if);
1784 if (su)
1785 peer->su = *su;
1786 else
1787 bgp_peer_conf_if_to_su_update(peer);
1788 XFREE(MTYPE_BGP_PEER_HOST, peer->host);
1789 peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, conf_if);
1790 } else if (su) {
1791 peer->su = *su;
1792 sockunion2str(su, buf, SU_ADDRSTRLEN);
1793 XFREE(MTYPE_BGP_PEER_HOST, peer->host);
1794 peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf);
1795 }
1796 peer->local_as = local_as;
1797 peer->as = remote_as;
1798 /* internal and external values do not use as_pretty */
1799 if (as_str && asn_str2asn(as_str, NULL))
1800 peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
1801 peer->as_type = as_type;
1802 peer->local_id = bgp->router_id;
1803 peer->v_holdtime = bgp->default_holdtime;
1804 peer->v_keepalive = bgp->default_keepalive;
1805 peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
1806 ? BGP_DEFAULT_IBGP_ROUTEADV
1807 : BGP_DEFAULT_EBGP_ROUTEADV;
1808 if (bgp_config_inprocess())
1809 peer->shut_during_cfg = true;
1810
1811 peer = peer_lock(peer); /* bgp peer list reference */
1812 peer->group = group;
1813 listnode_add_sort(bgp->peer, peer);
1814
1815 if (config_node)
1816 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
1817
1818 (void)hash_get(bgp->peerhash, peer, hash_alloc_intern);
1819
1820 /* Adjust update-group coalesce timer heuristics for # peers. */
1821 if (bgp->heuristic_coalesce) {
1822 long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
1823 + (bgp->peer->count
1824 * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
1825 bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
1826 }
1827
1828 active = peer_active(peer);
1829 if (!active) {
1830 if (peer->su.sa.sa_family == AF_UNSPEC)
1831 peer->last_reset = PEER_DOWN_NBR_ADDR;
1832 else
1833 peer->last_reset = PEER_DOWN_NOAFI_ACTIVATED;
1834 }
1835
1836 /* Last read and reset time set */
1837 peer->readtime = peer->resettime = monotime(NULL);
1838
1839 /* Default TTL set. */
1840 peer->ttl = (peer->sort == BGP_PEER_IBGP) ? MAXTTL : BGP_DEFAULT_TTL;
1841
1842 /* Default configured keepalives count for shutdown rtt command */
1843 peer->rtt_keepalive_conf = 1;
1844
1845 /* If 'bgp default <afi>-<safi>' is configured, then activate the
1846 * neighbor for the corresponding address family. IPv4 Unicast is
1847 * the only address family enabled by default without expliict
1848 * configuration.
1849 */
1850 FOREACH_AFI_SAFI (afi, safi) {
1851 if (bgp->default_af[afi][safi]) {
1852 peer->afc[afi][safi] = 1;
1853 peer_af_create(peer, afi, safi);
1854 }
1855 }
1856
1857 /* auto shutdown if configured */
1858 if (bgp->autoshutdown)
1859 peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
1860 /* Set up peer's events and timers. */
1861 else if (!active && peer_active(peer))
1862 bgp_timer_set(peer);
1863
1864 bgp_peer_gr_flags_update(peer);
1865 BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer);
1866
1867 return peer;
1868 }
1869
1870 /* Make accept BGP peer. This function is only called from the test code */
1871 struct peer *peer_create_accept(struct bgp *bgp)
1872 {
1873 struct peer *peer;
1874
1875 peer = peer_new(bgp);
1876
1877 peer = peer_lock(peer); /* bgp peer list reference */
1878 listnode_add_sort(bgp->peer, peer);
1879 (void)hash_get(bgp->peerhash, peer, hash_alloc_intern);
1880
1881 return peer;
1882 }
1883
1884 /*
1885 * Return true if we have a peer configured to use this afi/safi
1886 */
1887 bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
1888 {
1889 struct listnode *node;
1890 struct peer *peer;
1891
1892 for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
1893 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1894 continue;
1895
1896 if (peer->afc[afi][safi])
1897 return true;
1898 }
1899
1900 return false;
1901 }
1902
1903 /* Change peer's AS number. */
1904 void peer_as_change(struct peer *peer, as_t as, int as_specified,
1905 const char *as_str)
1906 {
1907 enum bgp_peer_sort origtype, newtype;
1908
1909 /* Stop peer. */
1910 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
1911 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
1912 peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
1913 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
1914 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1915 } else
1916 bgp_session_reset(peer);
1917 }
1918 origtype = peer_sort_lookup(peer);
1919 peer->as = as;
1920 if (as_specified == AS_SPECIFIED && as_str) {
1921 if (peer->as_pretty)
1922 XFREE(MTYPE_BGP, peer->as_pretty);
1923 peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
1924 } else if (peer->as_type == AS_UNSPECIFIED && peer->as_pretty)
1925 XFREE(MTYPE_BGP, peer->as_pretty);
1926 peer->as_type = as_specified;
1927
1928 if (bgp_config_check(peer->bgp, BGP_CONFIG_CONFEDERATION)
1929 && !bgp_confederation_peers_check(peer->bgp, as)
1930 && peer->bgp->as != as)
1931 peer->local_as = peer->bgp->confed_id;
1932 else
1933 peer->local_as = peer->bgp->as;
1934
1935 newtype = peer_sort(peer);
1936 /* Advertisement-interval reset */
1937 if (!CHECK_FLAG(peer->flags, PEER_FLAG_ROUTEADV)) {
1938 peer->v_routeadv = (newtype == BGP_PEER_IBGP)
1939 ? BGP_DEFAULT_IBGP_ROUTEADV
1940 : BGP_DEFAULT_EBGP_ROUTEADV;
1941 }
1942
1943 /* TTL reset */
1944 if (newtype == BGP_PEER_IBGP)
1945 peer->ttl = MAXTTL;
1946 else if (origtype == BGP_PEER_IBGP)
1947 peer->ttl = BGP_DEFAULT_TTL;
1948
1949 /* reflector-client reset */
1950 if (newtype != BGP_PEER_IBGP) {
1951 UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_UNICAST],
1952 PEER_FLAG_REFLECTOR_CLIENT);
1953 UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_MULTICAST],
1954 PEER_FLAG_REFLECTOR_CLIENT);
1955 UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_LABELED_UNICAST],
1956 PEER_FLAG_REFLECTOR_CLIENT);
1957 UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
1958 PEER_FLAG_REFLECTOR_CLIENT);
1959 UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_ENCAP],
1960 PEER_FLAG_REFLECTOR_CLIENT);
1961 UNSET_FLAG(peer->af_flags[AFI_IP][SAFI_FLOWSPEC],
1962 PEER_FLAG_REFLECTOR_CLIENT);
1963 UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_UNICAST],
1964 PEER_FLAG_REFLECTOR_CLIENT);
1965 UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_MULTICAST],
1966 PEER_FLAG_REFLECTOR_CLIENT);
1967 UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_LABELED_UNICAST],
1968 PEER_FLAG_REFLECTOR_CLIENT);
1969 UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
1970 PEER_FLAG_REFLECTOR_CLIENT);
1971 UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_ENCAP],
1972 PEER_FLAG_REFLECTOR_CLIENT);
1973 UNSET_FLAG(peer->af_flags[AFI_IP6][SAFI_FLOWSPEC],
1974 PEER_FLAG_REFLECTOR_CLIENT);
1975 UNSET_FLAG(peer->af_flags[AFI_L2VPN][SAFI_EVPN],
1976 PEER_FLAG_REFLECTOR_CLIENT);
1977 }
1978 }
1979
1980 /* If peer does not exist, create new one. If peer already exists,
1981 set AS number to the peer. */
1982 int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
1983 as_t *as, int as_type, const char *as_str)
1984 {
1985 struct peer *peer;
1986 as_t local_as;
1987
1988 if (conf_if)
1989 peer = peer_lookup_by_conf_if(bgp, conf_if);
1990 else
1991 peer = peer_lookup(bgp, su);
1992
1993 if (peer) {
1994 /* Not allowed for a dynamic peer. */
1995 if (peer_dynamic_neighbor(peer)) {
1996 *as = peer->as;
1997 return BGP_ERR_INVALID_FOR_DYNAMIC_PEER;
1998 }
1999
2000 /* When this peer is a member of peer-group. */
2001 if (peer->group) {
2002 /* peer-group already has AS number/internal/external */
2003 if (peer->group->conf->as
2004 || peer->group->conf->as_type) {
2005 /* Return peer group's AS number. */
2006 *as = peer->group->conf->as;
2007 return BGP_ERR_PEER_GROUP_MEMBER;
2008 }
2009
2010 enum bgp_peer_sort peer_sort_type =
2011 peer_sort(peer->group->conf);
2012
2013 /* Explicit AS numbers used, compare AS numbers */
2014 if (as_type == AS_SPECIFIED) {
2015 if (((peer_sort_type == BGP_PEER_IBGP)
2016 && (bgp->as != *as))
2017 || ((peer_sort_type == BGP_PEER_EBGP)
2018 && (bgp->as == *as))) {
2019 *as = peer->as;
2020 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
2021 }
2022 } else {
2023 /* internal/external used, compare as-types */
2024 if (((peer_sort_type == BGP_PEER_IBGP)
2025 && (as_type != AS_INTERNAL))
2026 || ((peer_sort_type == BGP_PEER_EBGP)
2027 && (as_type != AS_EXTERNAL))) {
2028 *as = peer->as;
2029 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
2030 }
2031 }
2032 }
2033
2034 /* Existing peer's AS number change. */
2035 if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
2036 || (peer->as_type != as_type))
2037 peer_as_change(peer, *as, as_type, as_str);
2038 } else {
2039 if (conf_if)
2040 return BGP_ERR_NO_INTERFACE_CONFIG;
2041
2042 /* If the peer is not part of our confederation, and its not an
2043 iBGP peer then spoof the source AS */
2044 if (bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION)
2045 && !bgp_confederation_peers_check(bgp, *as)
2046 && bgp->as != *as)
2047 local_as = bgp->confed_id;
2048 else
2049 local_as = bgp->as;
2050
2051 peer_create(su, conf_if, bgp, local_as, *as, as_type, NULL,
2052 true, as_str);
2053 }
2054
2055 return 0;
2056 }
2057
2058 const char *bgp_get_name_by_role(uint8_t role)
2059 {
2060 switch (role) {
2061 case ROLE_PROVIDER:
2062 return "provider";
2063 case ROLE_RS_SERVER:
2064 return "rs-server";
2065 case ROLE_RS_CLIENT:
2066 return "rs-client";
2067 case ROLE_CUSTOMER:
2068 return "customer";
2069 case ROLE_PEER:
2070 return "peer";
2071 case ROLE_UNDEFINED:
2072 return "undefined";
2073 }
2074 return "unknown";
2075 }
2076
2077 enum asnotation_mode bgp_get_asnotation(struct bgp *bgp)
2078 {
2079 if (!bgp)
2080 return ASNOTATION_PLAIN;
2081 return bgp->asnotation;
2082 }
2083
2084 static void peer_group2peer_config_copy_af(struct peer_group *group,
2085 struct peer *peer, afi_t afi,
2086 safi_t safi)
2087 {
2088 int in = FILTER_IN;
2089 int out = FILTER_OUT;
2090 uint64_t flags_tmp;
2091 uint64_t pflags_ovrd;
2092 uint8_t *pfilter_ovrd;
2093 struct peer *conf;
2094
2095 conf = group->conf;
2096 pflags_ovrd = peer->af_flags_override[afi][safi];
2097 pfilter_ovrd = &peer->filter_override[afi][safi][in];
2098
2099 /* peer af_flags apply */
2100 flags_tmp = conf->af_flags[afi][safi] & ~pflags_ovrd;
2101 flags_tmp ^= conf->af_flags_invert[afi][safi]
2102 ^ peer->af_flags_invert[afi][safi];
2103 flags_tmp &= ~pflags_ovrd;
2104
2105 UNSET_FLAG(peer->af_flags[afi][safi], ~pflags_ovrd);
2106 SET_FLAG(peer->af_flags[afi][safi], flags_tmp);
2107 SET_FLAG(peer->af_flags_invert[afi][safi],
2108 conf->af_flags_invert[afi][safi]);
2109
2110 /* maximum-prefix */
2111 if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_MAX_PREFIX)) {
2112 PEER_ATTR_INHERIT(peer, group, pmax[afi][safi]);
2113 PEER_ATTR_INHERIT(peer, group, pmax_threshold[afi][safi]);
2114 PEER_ATTR_INHERIT(peer, group, pmax_restart[afi][safi]);
2115 }
2116
2117 /* maximum-prefix-out */
2118 if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_MAX_PREFIX_OUT))
2119 PEER_ATTR_INHERIT(peer, group, pmax_out[afi][safi]);
2120
2121 /* allowas-in */
2122 if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_ALLOWAS_IN))
2123 PEER_ATTR_INHERIT(peer, group, allowas_in[afi][safi]);
2124
2125 /* soo */
2126 if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_SOO))
2127 PEER_ATTR_INHERIT(peer, group, soo[afi][safi]);
2128
2129 /* weight */
2130 if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_WEIGHT))
2131 PEER_ATTR_INHERIT(peer, group, weight[afi][safi]);
2132
2133 /* default-originate route-map */
2134 if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_DEFAULT_ORIGINATE)) {
2135 PEER_STR_ATTR_INHERIT(peer, group, default_rmap[afi][safi].name,
2136 MTYPE_ROUTE_MAP_NAME);
2137 PEER_ATTR_INHERIT(peer, group, default_rmap[afi][safi].map);
2138 }
2139
2140 /* inbound filter apply */
2141 if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_DISTRIBUTE_LIST)) {
2142 PEER_STR_ATTR_INHERIT(peer, group,
2143 filter[afi][safi].dlist[in].name,
2144 MTYPE_BGP_FILTER_NAME);
2145 PEER_ATTR_INHERIT(peer, group,
2146 filter[afi][safi].dlist[in].alist);
2147 }
2148
2149 if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_PREFIX_LIST)) {
2150 PEER_STR_ATTR_INHERIT(peer, group,
2151 filter[afi][safi].plist[in].name,
2152 MTYPE_BGP_FILTER_NAME);
2153 PEER_ATTR_INHERIT(peer, group,
2154 filter[afi][safi].plist[in].plist);
2155 }
2156
2157 if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_FILTER_LIST)) {
2158 PEER_STR_ATTR_INHERIT(peer, group,
2159 filter[afi][safi].aslist[in].name,
2160 MTYPE_BGP_FILTER_NAME);
2161 PEER_ATTR_INHERIT(peer, group,
2162 filter[afi][safi].aslist[in].aslist);
2163 }
2164
2165 if (!CHECK_FLAG(pfilter_ovrd[RMAP_IN], PEER_FT_ROUTE_MAP)) {
2166 PEER_STR_ATTR_INHERIT(peer, group,
2167 filter[afi][safi].map[in].name,
2168 MTYPE_BGP_FILTER_NAME);
2169 PEER_ATTR_INHERIT(peer, group,
2170 filter[afi][safi].map[RMAP_IN].map);
2171 }
2172
2173 /* outbound filter apply */
2174 if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_DISTRIBUTE_LIST)) {
2175 PEER_STR_ATTR_INHERIT(peer, group,
2176 filter[afi][safi].dlist[out].name,
2177 MTYPE_BGP_FILTER_NAME);
2178 PEER_ATTR_INHERIT(peer, group,
2179 filter[afi][safi].dlist[out].alist);
2180 }
2181
2182 if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_PREFIX_LIST)) {
2183 PEER_STR_ATTR_INHERIT(peer, group,
2184 filter[afi][safi].plist[out].name,
2185 MTYPE_BGP_FILTER_NAME);
2186 PEER_ATTR_INHERIT(peer, group,
2187 filter[afi][safi].plist[out].plist);
2188 }
2189
2190 if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_FILTER_LIST)) {
2191 PEER_STR_ATTR_INHERIT(peer, group,
2192 filter[afi][safi].aslist[out].name,
2193 MTYPE_BGP_FILTER_NAME);
2194 PEER_ATTR_INHERIT(peer, group,
2195 filter[afi][safi].aslist[out].aslist);
2196 }
2197
2198 if (!CHECK_FLAG(pfilter_ovrd[RMAP_OUT], PEER_FT_ROUTE_MAP)) {
2199 PEER_STR_ATTR_INHERIT(peer, group,
2200 filter[afi][safi].map[RMAP_OUT].name,
2201 MTYPE_BGP_FILTER_NAME);
2202 PEER_ATTR_INHERIT(peer, group,
2203 filter[afi][safi].map[RMAP_OUT].map);
2204 }
2205
2206 /* nondirectional filter apply */
2207 if (!CHECK_FLAG(pfilter_ovrd[0], PEER_FT_UNSUPPRESS_MAP)) {
2208 PEER_STR_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.name,
2209 MTYPE_BGP_FILTER_NAME);
2210 PEER_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.map);
2211 }
2212
2213 /* Conditional Advertisements */
2214 if (!CHECK_FLAG(pfilter_ovrd[RMAP_OUT], PEER_FT_ADVERTISE_MAP)) {
2215 PEER_STR_ATTR_INHERIT(peer, group,
2216 filter[afi][safi].advmap.aname,
2217 MTYPE_BGP_FILTER_NAME);
2218 PEER_ATTR_INHERIT(peer, group, filter[afi][safi].advmap.amap);
2219 PEER_STR_ATTR_INHERIT(peer, group,
2220 filter[afi][safi].advmap.cname,
2221 MTYPE_BGP_FILTER_NAME);
2222 PEER_ATTR_INHERIT(peer, group, filter[afi][safi].advmap.cmap);
2223 PEER_ATTR_INHERIT(peer, group,
2224 filter[afi][safi].advmap.condition);
2225 }
2226
2227 if (peer->addpath_type[afi][safi] == BGP_ADDPATH_NONE) {
2228 peer->addpath_type[afi][safi] = conf->addpath_type[afi][safi];
2229 bgp_addpath_type_changed(conf->bgp);
2230 }
2231 }
2232
2233 static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi)
2234 {
2235 int active;
2236 struct peer *other;
2237
2238 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2239 flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s",
2240 __func__, peer->host);
2241 return 1;
2242 }
2243
2244 /* Do not activate a peer for both SAFI_UNICAST and SAFI_LABELED_UNICAST
2245 */
2246 if ((safi == SAFI_UNICAST && peer->afc[afi][SAFI_LABELED_UNICAST])
2247 || (safi == SAFI_LABELED_UNICAST && peer->afc[afi][SAFI_UNICAST]))
2248 return BGP_ERR_PEER_SAFI_CONFLICT;
2249
2250 /* Nothing to do if we've already activated this peer */
2251 if (peer->afc[afi][safi])
2252 return 0;
2253
2254 if (peer_af_create(peer, afi, safi) == NULL)
2255 return 1;
2256
2257 active = peer_active(peer);
2258 peer->afc[afi][safi] = 1;
2259
2260 if (peer->group)
2261 peer_group2peer_config_copy_af(peer->group, peer, afi, safi);
2262
2263 if (!active && peer_active(peer)) {
2264 bgp_timer_set(peer);
2265 } else {
2266 if (peer_established(peer)) {
2267 if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) {
2268 peer->afc_adv[afi][safi] = 1;
2269 bgp_capability_send(peer, afi, safi,
2270 CAPABILITY_CODE_MP,
2271 CAPABILITY_ACTION_SET);
2272 if (peer->afc_recv[afi][safi]) {
2273 peer->afc_nego[afi][safi] = 1;
2274 bgp_announce_route(peer, afi, safi,
2275 false);
2276 }
2277 } else {
2278 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
2279 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2280 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2281 }
2282 }
2283 if (peer->status == OpenSent || peer->status == OpenConfirm) {
2284 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
2285 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2286 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2287 }
2288 /*
2289 * If we are turning on a AFI/SAFI locally and we've
2290 * started bringing a peer up, we need to tell
2291 * the other peer to restart because we might loose
2292 * configuration here because when the doppelganger
2293 * gets to a established state due to how
2294 * we resolve we could just overwrite the afi/safi
2295 * activation.
2296 */
2297 other = peer->doppelganger;
2298 if (other
2299 && (other->status == OpenSent
2300 || other->status == OpenConfirm)) {
2301 other->last_reset = PEER_DOWN_AF_ACTIVATE;
2302 bgp_notify_send(other, BGP_NOTIFY_CEASE,
2303 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2304 }
2305 }
2306
2307 return 0;
2308 }
2309
2310 /* Activate the peer or peer group for specified AFI and SAFI. */
2311 int peer_activate(struct peer *peer, afi_t afi, safi_t safi)
2312 {
2313 int ret = 0;
2314 struct peer_group *group;
2315 struct listnode *node, *nnode;
2316 struct peer *tmp_peer;
2317 struct bgp *bgp;
2318
2319 /* Nothing to do if we've already activated this peer */
2320 if (peer->afc[afi][safi])
2321 return ret;
2322
2323 bgp = peer->bgp;
2324
2325 /* This is a peer-group so activate all of the members of the
2326 * peer-group as well */
2327 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2328
2329 /* Do not activate a peer for both SAFI_UNICAST and
2330 * SAFI_LABELED_UNICAST */
2331 if ((safi == SAFI_UNICAST
2332 && peer->afc[afi][SAFI_LABELED_UNICAST])
2333 || (safi == SAFI_LABELED_UNICAST
2334 && peer->afc[afi][SAFI_UNICAST]))
2335 return BGP_ERR_PEER_SAFI_CONFLICT;
2336
2337 peer->afc[afi][safi] = 1;
2338 group = peer->group;
2339
2340 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
2341 ret |= peer_activate_af(tmp_peer, afi, safi);
2342 }
2343 } else {
2344 ret |= peer_activate_af(peer, afi, safi);
2345 }
2346
2347 /* If this is the first peer to be activated for this
2348 * afi/labeled-unicast recalc bestpaths to trigger label allocation */
2349 if (ret != BGP_ERR_PEER_SAFI_CONFLICT && safi == SAFI_LABELED_UNICAST
2350 && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) {
2351
2352 if (BGP_DEBUG(zebra, ZEBRA))
2353 zlog_debug(
2354 "peer(s) are now active for labeled-unicast, allocate MPLS labels");
2355
2356 bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 1;
2357 bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
2358 }
2359
2360 if (safi == SAFI_FLOWSPEC) {
2361 /* connect to table manager */
2362 bgp_zebra_init_tm_connect(bgp);
2363 }
2364 return ret;
2365 }
2366
2367 static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi,
2368 safi_t safi)
2369 {
2370 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2371 flog_err(EC_BGP_PEER_GROUP, "%s was called for peer-group %s",
2372 __func__, peer->host);
2373 return true;
2374 }
2375
2376 /* Nothing to do if we've already deactivated this peer */
2377 if (!peer->afc[afi][safi])
2378 return false;
2379
2380 /* De-activate the address family configuration. */
2381 peer->afc[afi][safi] = 0;
2382
2383 if (peer_af_delete(peer, afi, safi) != 0) {
2384 flog_err(EC_BGP_PEER_DELETE,
2385 "couldn't delete af structure for peer %s(%s, %s)",
2386 peer->host, afi2str(afi), safi2str(safi));
2387 return true;
2388 }
2389
2390 if (peer_established(peer)) {
2391 if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) {
2392 peer->afc_adv[afi][safi] = 0;
2393 peer->afc_nego[afi][safi] = 0;
2394
2395 if (peer_active_nego(peer)) {
2396 bgp_capability_send(peer, afi, safi,
2397 CAPABILITY_CODE_MP,
2398 CAPABILITY_ACTION_UNSET);
2399 bgp_clear_route(peer, afi, safi);
2400 peer->pcount[afi][safi] = 0;
2401 } else {
2402 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2403 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2404 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2405 }
2406 } else {
2407 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2408 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2409 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2410 }
2411 }
2412
2413 return false;
2414 }
2415
2416 int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi)
2417 {
2418 int ret = 0;
2419 struct peer_group *group;
2420 struct peer *tmp_peer;
2421 struct listnode *node, *nnode;
2422 struct bgp *bgp;
2423
2424 /* Nothing to do if we've already de-activated this peer */
2425 if (!peer->afc[afi][safi])
2426 return ret;
2427
2428 /* This is a peer-group so de-activate all of the members of the
2429 * peer-group as well */
2430 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
2431 peer->afc[afi][safi] = 0;
2432 group = peer->group;
2433
2434 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
2435 ret |= non_peergroup_deactivate_af(tmp_peer, afi, safi);
2436 }
2437 } else {
2438 ret |= non_peergroup_deactivate_af(peer, afi, safi);
2439 }
2440
2441 bgp = peer->bgp;
2442
2443 /* If this is the last peer to be deactivated for this
2444 * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
2445 if (safi == SAFI_LABELED_UNICAST
2446 && bgp->allocate_mpls_labels[afi][SAFI_UNICAST]
2447 && !bgp_afi_safi_peer_exists(bgp, afi, safi)) {
2448
2449 if (BGP_DEBUG(zebra, ZEBRA))
2450 zlog_debug(
2451 "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels");
2452
2453 bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 0;
2454 bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
2455 }
2456 return ret;
2457 }
2458
2459 void peer_nsf_stop(struct peer *peer)
2460 {
2461 afi_t afi;
2462 safi_t safi;
2463
2464 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
2465 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2466
2467 FOREACH_AFI_SAFI_NSF (afi, safi) {
2468 peer->nsf[afi][safi] = 0;
2469 THREAD_OFF(peer->t_llgr_stale[afi][safi]);
2470 }
2471
2472 if (peer->t_gr_restart) {
2473 THREAD_OFF(peer->t_gr_restart);
2474 if (bgp_debug_neighbor_events(peer))
2475 zlog_debug("%pBP graceful restart timer stopped", peer);
2476 }
2477 if (peer->t_gr_stale) {
2478 THREAD_OFF(peer->t_gr_stale);
2479 if (bgp_debug_neighbor_events(peer))
2480 zlog_debug(
2481 "%pBP graceful restart stalepath timer stopped",
2482 peer);
2483 }
2484 bgp_clear_route_all(peer);
2485 }
2486
2487 /* Delete peer from confguration.
2488 *
2489 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2490 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2491 *
2492 * This function /should/ take care to be idempotent, to guard against
2493 * it being called multiple times through stray events that come in
2494 * that happen to result in this function being called again. That
2495 * said, getting here for a "Deleted" peer is a bug in the neighbour
2496 * FSM.
2497 */
2498 int peer_delete(struct peer *peer)
2499 {
2500 int i;
2501 afi_t afi;
2502 safi_t safi;
2503 struct bgp *bgp;
2504 struct bgp_filter *filter;
2505 struct listnode *pn;
2506 int accept_peer;
2507
2508 assert(peer->status != Deleted);
2509
2510 bgp = peer->bgp;
2511 accept_peer = CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
2512
2513 bgp_soft_reconfig_table_task_cancel(bgp, NULL, peer);
2514
2515 bgp_keepalives_off(peer);
2516 bgp_reads_off(peer);
2517 bgp_writes_off(peer);
2518 thread_cancel_event_ready(bm->master, peer);
2519 FOREACH_AFI_SAFI (afi, safi)
2520 THREAD_OFF(peer->t_revalidate_all[afi][safi]);
2521 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
2522 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
2523 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON));
2524
2525 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
2526 peer_nsf_stop(peer);
2527
2528 SET_FLAG(peer->flags, PEER_FLAG_DELETE);
2529
2530 /* Remove BFD settings. */
2531 if (peer->bfd_config)
2532 bgp_peer_remove_bfd_config(peer);
2533
2534 /* If this peer belongs to peer group, clear up the
2535 relationship. */
2536 if (peer->group) {
2537 if (peer_dynamic_neighbor(peer))
2538 peer_drop_dynamic_neighbor(peer);
2539
2540 if ((pn = listnode_lookup(peer->group->peer, peer))) {
2541 peer = peer_unlock(
2542 peer); /* group->peer list reference */
2543 list_delete_node(peer->group->peer, pn);
2544 }
2545 peer->group = NULL;
2546 }
2547
2548 /* Withdraw all information from routing table. We can not use
2549 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2550 * executed after peer structure is deleted.
2551 */
2552 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2553 bgp_stop(peer);
2554 UNSET_FLAG(peer->flags, PEER_FLAG_DELETE);
2555
2556 if (peer->doppelganger) {
2557 peer->doppelganger->doppelganger = NULL;
2558 peer->doppelganger = NULL;
2559 }
2560
2561 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
2562 bgp_fsm_change_status(peer, Deleted);
2563
2564 /* Remove from NHT */
2565 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
2566 bgp_unlink_nexthop_by_peer(peer);
2567
2568 /* Password configuration */
2569 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)) {
2570 XFREE(MTYPE_PEER_PASSWORD, peer->password);
2571 if (!accept_peer && !BGP_PEER_SU_UNSPEC(peer)
2572 && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
2573 && !CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR))
2574 bgp_md5_unset(peer);
2575 }
2576
2577 bgp_timer_set(peer); /* stops all timers for Deleted */
2578
2579 /* Delete from all peer list. */
2580 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
2581 && (pn = listnode_lookup(bgp->peer, peer))) {
2582 /*
2583 * Removing from the list node first because
2584 * peer_unlock *can* call peer_delete( I know,
2585 * I know ). So let's remove it and in
2586 * the su recalculate function we'll ensure
2587 * it's in there or not.
2588 */
2589 list_delete_node(bgp->peer, pn);
2590 hash_release(bgp->peerhash, peer);
2591 peer_unlock(peer); /* bgp peer list reference */
2592 }
2593
2594 /* Buffers. */
2595 if (peer->ibuf) {
2596 stream_fifo_free(peer->ibuf);
2597 peer->ibuf = NULL;
2598 }
2599
2600 if (peer->obuf) {
2601 stream_fifo_free(peer->obuf);
2602 peer->obuf = NULL;
2603 }
2604
2605 if (peer->ibuf_work) {
2606 ringbuf_del(peer->ibuf_work);
2607 peer->ibuf_work = NULL;
2608 }
2609
2610 if (peer->obuf_work) {
2611 stream_free(peer->obuf_work);
2612 peer->obuf_work = NULL;
2613 }
2614
2615 if (peer->scratch) {
2616 stream_free(peer->scratch);
2617 peer->scratch = NULL;
2618 }
2619
2620 /* Local and remote addresses. */
2621 if (peer->su_local) {
2622 sockunion_free(peer->su_local);
2623 peer->su_local = NULL;
2624 }
2625
2626 if (peer->su_remote) {
2627 sockunion_free(peer->su_remote);
2628 peer->su_remote = NULL;
2629 }
2630
2631 /* Free filter related memory. */
2632 FOREACH_AFI_SAFI (afi, safi) {
2633 filter = &peer->filter[afi][safi];
2634
2635 for (i = FILTER_IN; i < FILTER_MAX; i++) {
2636 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[i].name);
2637 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[i].name);
2638 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name);
2639 }
2640
2641 for (i = RMAP_IN; i < RMAP_MAX; i++) {
2642 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[i].name);
2643 }
2644
2645 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
2646 XFREE(MTYPE_ROUTE_MAP_NAME, peer->default_rmap[afi][safi].name);
2647 ecommunity_free(&peer->soo[afi][safi]);
2648 }
2649
2650 FOREACH_AFI_SAFI (afi, safi)
2651 peer_af_delete(peer, afi, safi);
2652
2653 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
2654 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
2655 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
2656
2657 peer_unlock(peer); /* initial reference */
2658
2659 return 0;
2660 }
2661
2662 static int peer_group_cmp(struct peer_group *g1, struct peer_group *g2)
2663 {
2664 return strcmp(g1->name, g2->name);
2665 }
2666
2667 /* Peer group cofiguration. */
2668 static struct peer_group *peer_group_new(void)
2669 {
2670 return XCALLOC(MTYPE_PEER_GROUP, sizeof(struct peer_group));
2671 }
2672
2673 static void peer_group_free(struct peer_group *group)
2674 {
2675 XFREE(MTYPE_PEER_GROUP, group);
2676 }
2677
2678 struct peer_group *peer_group_lookup(struct bgp *bgp, const char *name)
2679 {
2680 struct peer_group *group;
2681 struct listnode *node, *nnode;
2682
2683 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
2684 if (strcmp(group->name, name) == 0)
2685 return group;
2686 }
2687 return NULL;
2688 }
2689
2690 struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
2691 {
2692 struct peer_group *group;
2693 afi_t afi;
2694 safi_t safi;
2695
2696 group = peer_group_lookup(bgp, name);
2697 if (group)
2698 return group;
2699
2700 group = peer_group_new();
2701 group->bgp = bgp;
2702 XFREE(MTYPE_PEER_GROUP_HOST, group->name);
2703 group->name = XSTRDUP(MTYPE_PEER_GROUP_HOST, name);
2704 group->peer = list_new();
2705 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2706 group->listen_range[afi] = list_new();
2707 group->conf = peer_new(bgp);
2708 FOREACH_AFI_SAFI (afi, safi) {
2709 if (bgp->default_af[afi][safi])
2710 group->conf->afc[afi][safi] = 1;
2711 }
2712 XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
2713 group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name);
2714 group->conf->group = group;
2715 group->conf->as = 0;
2716 group->conf->ttl = BGP_DEFAULT_TTL;
2717 group->conf->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
2718 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
2719 SET_FLAG(group->conf->sflags, PEER_STATUS_GROUP);
2720 listnode_add_sort(bgp->group, group);
2721
2722 return group;
2723 }
2724
2725 static void peer_group2peer_config_copy(struct peer_group *group,
2726 struct peer *peer)
2727 {
2728 uint32_t flags_tmp;
2729 struct peer *conf;
2730 bool config_node = !!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
2731
2732 conf = group->conf;
2733
2734 /* remote-as */
2735 if (conf->as)
2736 peer->as = conf->as;
2737
2738 /* local-as */
2739 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_LOCAL_AS))
2740 peer->change_local_as = conf->change_local_as;
2741
2742 /* If peer-group has configured TTL then override it */
2743 if (conf->ttl != BGP_DEFAULT_TTL)
2744 peer->ttl = conf->ttl;
2745
2746 /* GTSM hops */
2747 peer->gtsm_hops = conf->gtsm_hops;
2748
2749 /* peer flags apply */
2750 flags_tmp = conf->flags & ~peer->flags_override;
2751 flags_tmp ^= conf->flags_invert ^ peer->flags_invert;
2752 flags_tmp &= ~peer->flags_override;
2753
2754 UNSET_FLAG(peer->flags, ~peer->flags_override);
2755 SET_FLAG(peer->flags, flags_tmp);
2756 SET_FLAG(peer->flags_invert, conf->flags_invert);
2757
2758 if (config_node)
2759 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
2760
2761 /* peer timers apply */
2762 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER)) {
2763 PEER_ATTR_INHERIT(peer, group, holdtime);
2764 PEER_ATTR_INHERIT(peer, group, keepalive);
2765 }
2766
2767 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_CONNECT)) {
2768 PEER_ATTR_INHERIT(peer, group, connect);
2769 if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_CONNECT))
2770 peer->v_connect = conf->connect;
2771 else
2772 peer->v_connect = peer->bgp->default_connect_retry;
2773 }
2774
2775 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_DELAYOPEN)) {
2776 PEER_ATTR_INHERIT(peer, group, delayopen);
2777 if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_DELAYOPEN))
2778 peer->v_delayopen = conf->delayopen;
2779 else
2780 peer->v_delayopen = peer->bgp->default_delayopen;
2781 }
2782
2783 /* advertisement-interval apply */
2784 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_ROUTEADV)) {
2785 PEER_ATTR_INHERIT(peer, group, routeadv);
2786 if (CHECK_FLAG(conf->flags, PEER_FLAG_ROUTEADV))
2787 peer->v_routeadv = conf->routeadv;
2788 else
2789 peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
2790 ? BGP_DEFAULT_IBGP_ROUTEADV
2791 : BGP_DEFAULT_EBGP_ROUTEADV;
2792 }
2793
2794 /* capability extended-nexthop apply */
2795 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE))
2796 if (CHECK_FLAG(conf->flags, PEER_FLAG_CAPABILITY_ENHE))
2797 SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
2798
2799 /* capability software-version apply */
2800 if (!CHECK_FLAG(peer->flags_override,
2801 PEER_FLAG_CAPABILITY_SOFT_VERSION))
2802 if (CHECK_FLAG(conf->flags, PEER_FLAG_CAPABILITY_SOFT_VERSION))
2803 SET_FLAG(peer->flags,
2804 PEER_FLAG_CAPABILITY_SOFT_VERSION);
2805
2806 /* password apply */
2807 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_PASSWORD))
2808 PEER_STR_ATTR_INHERIT(peer, group, password,
2809 MTYPE_PEER_PASSWORD);
2810
2811 if (!BGP_PEER_SU_UNSPEC(peer))
2812 bgp_md5_set(peer);
2813
2814 /* update-source apply */
2815 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_UPDATE_SOURCE)) {
2816 if (conf->update_source) {
2817 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2818 PEER_SU_ATTR_INHERIT(peer, group, update_source);
2819 } else if (conf->update_if) {
2820 sockunion_free(peer->update_source);
2821 PEER_STR_ATTR_INHERIT(peer, group, update_if,
2822 MTYPE_PEER_UPDATE_SOURCE);
2823 }
2824 }
2825
2826 /* role */
2827 PEER_ATTR_INHERIT(peer, group, local_role);
2828
2829 /* Update GR flags for the peer. */
2830 bgp_peer_gr_flags_update(peer);
2831
2832 /* Apply BFD settings from group to peer if it exists. */
2833 if (conf->bfd_config) {
2834 bgp_peer_configure_bfd(peer, false);
2835 bgp_peer_config_apply(peer, group);
2836 }
2837 }
2838
2839 /* Peer group's remote AS configuration. */
2840 int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
2841 int as_type, const char *as_str)
2842 {
2843 struct peer_group *group;
2844 struct peer *peer;
2845 struct listnode *node, *nnode;
2846
2847 group = peer_group_lookup(bgp, group_name);
2848 if (!group)
2849 return -1;
2850
2851 if ((as_type == group->conf->as_type) && (group->conf->as == *as))
2852 return 0;
2853
2854
2855 /* When we setup peer-group AS number all peer group member's AS
2856 number must be updated to same number. */
2857 peer_as_change(group->conf, *as, as_type, as_str);
2858
2859 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2860 if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
2861 || (peer->as_type != as_type))
2862 peer_as_change(peer, *as, as_type, as_str);
2863 }
2864
2865 return 0;
2866 }
2867
2868 void peer_notify_unconfig(struct peer *peer)
2869 {
2870 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2871 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2872 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
2873 }
2874
2875 static void peer_notify_shutdown(struct peer *peer)
2876 {
2877 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
2878 if (bgp_debug_neighbor_events(peer))
2879 zlog_debug(
2880 "%pBP configured Graceful-Restart, skipping shutdown notification",
2881 peer);
2882 return;
2883 }
2884
2885 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2886 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2887 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2888 }
2889
2890 void peer_group_notify_unconfig(struct peer_group *group)
2891 {
2892 struct peer *peer, *other;
2893 struct listnode *node, *nnode;
2894
2895 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2896 other = peer->doppelganger;
2897 if (other && other->status != Deleted) {
2898 other->group = NULL;
2899 peer_notify_unconfig(other);
2900 } else
2901 peer_notify_unconfig(peer);
2902 }
2903 }
2904
2905 int peer_group_delete(struct peer_group *group)
2906 {
2907 struct bgp *bgp;
2908 struct peer *peer;
2909 struct prefix *prefix;
2910 struct peer *other;
2911 struct listnode *node, *nnode;
2912 afi_t afi;
2913
2914 bgp = group->bgp;
2915
2916 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2917 other = peer->doppelganger;
2918
2919 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
2920 bgp_zebra_terminate_radv(bgp, peer);
2921
2922 peer_delete(peer);
2923 if (other && other->status != Deleted) {
2924 other->group = NULL;
2925 peer_delete(other);
2926 }
2927 }
2928 list_delete(&group->peer);
2929
2930 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2931 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
2932 prefix)) {
2933 prefix_free(&prefix);
2934 }
2935 list_delete(&group->listen_range[afi]);
2936 }
2937
2938 XFREE(MTYPE_PEER_GROUP_HOST, group->name);
2939 group->name = NULL;
2940
2941 if (group->conf->bfd_config)
2942 bgp_peer_remove_bfd_config(group->conf);
2943
2944 group->conf->group = NULL;
2945 peer_delete(group->conf);
2946
2947 /* Delete from all peer_group list. */
2948 listnode_delete(bgp->group, group);
2949
2950 peer_group_free(group);
2951
2952 return 0;
2953 }
2954
2955 int peer_group_remote_as_delete(struct peer_group *group)
2956 {
2957 struct peer *peer, *other;
2958 struct listnode *node, *nnode;
2959
2960 if ((group->conf->as_type == AS_UNSPECIFIED)
2961 || ((!group->conf->as) && (group->conf->as_type == AS_SPECIFIED)))
2962 return 0;
2963
2964 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2965 other = peer->doppelganger;
2966
2967 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
2968 bgp_zebra_terminate_radv(peer->bgp, peer);
2969
2970 peer_delete(peer);
2971
2972 if (other && other->status != Deleted) {
2973 other->group = NULL;
2974 peer_delete(other);
2975 }
2976 }
2977 list_delete_all_node(group->peer);
2978
2979 group->conf->as = 0;
2980 group->conf->as_type = AS_UNSPECIFIED;
2981
2982 return 0;
2983 }
2984
2985 int peer_group_listen_range_add(struct peer_group *group, struct prefix *range)
2986 {
2987 struct prefix *prefix;
2988 struct listnode *node, *nnode;
2989 afi_t afi;
2990
2991 afi = family2afi(range->family);
2992
2993 /* Group needs remote AS configured. */
2994 if (group->conf->as_type == AS_UNSPECIFIED)
2995 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
2996
2997 /* Ensure no duplicates. Currently we don't care about overlaps. */
2998 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) {
2999 if (prefix_same(range, prefix))
3000 return 0;
3001 }
3002
3003 prefix = prefix_new();
3004 prefix_copy(prefix, range);
3005 listnode_add(group->listen_range[afi], prefix);
3006
3007 /* Update passwords for new ranges */
3008 if (group->conf->password)
3009 bgp_md5_set_prefix(group->bgp, prefix, group->conf->password);
3010
3011 return 0;
3012 }
3013
3014 int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
3015 {
3016 struct prefix *prefix, prefix2;
3017 struct listnode *node, *nnode;
3018 struct peer *peer;
3019 afi_t afi;
3020
3021 afi = family2afi(range->family);
3022
3023 /* Identify the listen range. */
3024 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) {
3025 if (prefix_same(range, prefix))
3026 break;
3027 }
3028
3029 if (!prefix)
3030 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND;
3031
3032 /* Dispose off any dynamic neighbors that exist due to this listen range
3033 */
3034 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
3035 if (!peer_dynamic_neighbor(peer))
3036 continue;
3037
3038 if (sockunion2hostprefix(&peer->su, &prefix2)
3039 && prefix_match(prefix, &prefix2)) {
3040 if (bgp_debug_neighbor_events(peer))
3041 zlog_debug(
3042 "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX",
3043 peer->host, group->name, prefix);
3044 peer_delete(peer);
3045 }
3046 }
3047
3048 /* Get rid of the listen range */
3049 listnode_delete(group->listen_range[afi], prefix);
3050
3051 /* Remove passwords for deleted ranges */
3052 if (group->conf->password)
3053 bgp_md5_unset_prefix(group->bgp, prefix);
3054
3055 return 0;
3056 }
3057
3058 /* Bind specified peer to peer group. */
3059 int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
3060 struct peer_group *group, as_t *as)
3061 {
3062 int first_member = 0;
3063 afi_t afi;
3064 safi_t safi;
3065 enum bgp_peer_sort ptype, gtype;
3066
3067 /* Lookup the peer. */
3068 if (!peer)
3069 peer = peer_lookup(bgp, su);
3070
3071 /* The peer exist, bind it to the peer-group */
3072 if (peer) {
3073 /* When the peer already belongs to a peer-group, check the
3074 * consistency. */
3075 if (peer_group_active(peer)) {
3076
3077 /* The peer is already bound to the peer-group,
3078 * nothing to do
3079 */
3080 if (strcmp(peer->group->name, group->name) == 0)
3081 return 0;
3082 else
3083 return BGP_ERR_PEER_GROUP_CANT_CHANGE;
3084 }
3085
3086 /* The peer has not specified a remote-as, inherit it from the
3087 * peer-group */
3088 if (peer->as_type == AS_UNSPECIFIED) {
3089 peer->as_type = group->conf->as_type;
3090 peer->as = group->conf->as;
3091 peer->sort = group->conf->sort;
3092 }
3093
3094 ptype = peer_sort(peer);
3095 if (!group->conf->as && ptype != BGP_PEER_UNSPECIFIED) {
3096 gtype = peer_sort(group->conf);
3097 if ((gtype != BGP_PEER_INTERNAL) && (gtype != ptype)) {
3098 if (as)
3099 *as = peer->as;
3100 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
3101 }
3102
3103 if (gtype == BGP_PEER_INTERNAL)
3104 first_member = 1;
3105 }
3106
3107 peer_group2peer_config_copy(group, peer);
3108
3109 FOREACH_AFI_SAFI (afi, safi) {
3110 if (group->conf->afc[afi][safi]) {
3111 peer->afc[afi][safi] = 1;
3112
3113 if (peer_af_find(peer, afi, safi)
3114 || peer_af_create(peer, afi, safi)) {
3115 peer_group2peer_config_copy_af(
3116 group, peer, afi, safi);
3117 }
3118 } else if (peer->afc[afi][safi])
3119 peer_deactivate(peer, afi, safi);
3120 }
3121
3122 if (peer->group) {
3123 assert(group && peer->group == group);
3124 } else {
3125 listnode_delete(bgp->peer, peer);
3126
3127 peer->group = group;
3128 listnode_add_sort(bgp->peer, peer);
3129
3130 peer = peer_lock(peer); /* group->peer list reference */
3131 listnode_add(group->peer, peer);
3132 }
3133
3134 if (first_member) {
3135 gtype = peer_sort(group->conf);
3136 /* Advertisement-interval reset */
3137 if (!CHECK_FLAG(group->conf->flags,
3138 PEER_FLAG_ROUTEADV)) {
3139 group->conf->v_routeadv =
3140 (gtype == BGP_PEER_IBGP)
3141 ? BGP_DEFAULT_IBGP_ROUTEADV
3142 : BGP_DEFAULT_EBGP_ROUTEADV;
3143 }
3144
3145 /* ebgp-multihop reset */
3146 if (gtype == BGP_PEER_IBGP)
3147 group->conf->ttl = MAXTTL;
3148 }
3149
3150 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
3151
3152 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
3153 peer->last_reset = PEER_DOWN_RMAP_BIND;
3154 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3155 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3156 } else {
3157 bgp_session_reset(peer);
3158 }
3159 }
3160
3161 /* Create a new peer. */
3162 else {
3163 if ((group->conf->as_type == AS_SPECIFIED)
3164 && (!group->conf->as)) {
3165 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
3166 }
3167
3168 peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
3169 group->conf->as_type, group, true, NULL);
3170
3171 peer = peer_lock(peer); /* group->peer list reference */
3172 listnode_add(group->peer, peer);
3173
3174 peer_group2peer_config_copy(group, peer);
3175
3176 /* If the peer-group is active for this afi/safi then activate
3177 * for this peer */
3178 FOREACH_AFI_SAFI (afi, safi) {
3179 if (group->conf->afc[afi][safi]) {
3180 peer->afc[afi][safi] = 1;
3181
3182 if (!peer_af_find(peer, afi, safi))
3183 peer_af_create(peer, afi, safi);
3184
3185 peer_group2peer_config_copy_af(group, peer, afi,
3186 safi);
3187 } else if (peer->afc[afi][safi])
3188 peer_deactivate(peer, afi, safi);
3189 }
3190
3191 /* Set up peer's events and timers. */
3192 if (peer_active(peer))
3193 bgp_timer_set(peer);
3194 }
3195
3196 return 0;
3197 }
3198
3199 static void bgp_startup_timer_expire(struct thread *thread)
3200 {
3201 struct bgp *bgp;
3202
3203 bgp = THREAD_ARG(thread);
3204 bgp->t_startup = NULL;
3205 }
3206
3207 /*
3208 * On shutdown we call the cleanup function which
3209 * does a free of the link list nodes, free up
3210 * the data we are pointing at too.
3211 */
3212 static void bgp_vrf_string_name_delete(void *data)
3213 {
3214 char *vname = data;
3215
3216 XFREE(MTYPE_TMP, vname);
3217 }
3218
3219 /* BGP instance creation by `router bgp' commands. */
3220 static struct bgp *bgp_create(as_t *as, const char *name,
3221 enum bgp_instance_type inst_type,
3222 const char *as_pretty,
3223 enum asnotation_mode asnotation)
3224 {
3225 struct bgp *bgp;
3226 afi_t afi;
3227 safi_t safi;
3228
3229 bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp));
3230 bgp->as = *as;
3231 if (as_pretty)
3232 bgp->as_pretty = XSTRDUP(MTYPE_BGP, as_pretty);
3233 else
3234 bgp->as_pretty = XSTRDUP(MTYPE_BGP, asn_asn2asplain(*as));
3235
3236 if (asnotation != ASNOTATION_UNDEFINED) {
3237 bgp->asnotation = asnotation;
3238 SET_FLAG(bgp->config, BGP_CONFIG_ASNOTATION);
3239 } else
3240 asn_str2asn_notation(bgp->as_pretty, NULL, &bgp->asnotation);
3241
3242 if (BGP_DEBUG(zebra, ZEBRA)) {
3243 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3244 zlog_debug("Creating Default VRF, AS %s",
3245 bgp->as_pretty);
3246 else
3247 zlog_debug("Creating %s %s, AS %s",
3248 (inst_type == BGP_INSTANCE_TYPE_VRF)
3249 ? "VRF"
3250 : "VIEW",
3251 name, bgp->as_pretty);
3252 }
3253
3254 /* Default the EVPN VRF to the default one */
3255 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !bgp_master.bgp_evpn) {
3256 bgp_lock(bgp);
3257 bm->bgp_evpn = bgp;
3258 }
3259
3260 bgp_lock(bgp);
3261
3262 bgp->allow_martian = false;
3263 bgp_process_queue_init(bgp);
3264 bgp->heuristic_coalesce = true;
3265 bgp->inst_type = inst_type;
3266 bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
3267 : VRF_UNKNOWN;
3268 bgp->peer_self = peer_new(bgp);
3269 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
3270 bgp->peer_self->host =
3271 XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
3272 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->hostname);
3273 if (cmd_hostname_get())
3274 bgp->peer_self->hostname =
3275 XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_hostname_get());
3276
3277 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->domainname);
3278 if (cmd_domainname_get())
3279 bgp->peer_self->domainname =
3280 XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get());
3281 bgp->peer = list_new();
3282 bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
3283 bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same,
3284 "BGP Peer Hash");
3285 bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
3286
3287 bgp->group = list_new();
3288 bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
3289
3290 FOREACH_AFI_SAFI (afi, safi) {
3291 bgp->route[afi][safi] = bgp_table_init(bgp, afi, safi);
3292 bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi, safi);
3293 bgp->rib[afi][safi] = bgp_table_init(bgp, afi, safi);
3294
3295 /* Enable maximum-paths */
3296 bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
3297 multipath_num, 0);
3298 bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
3299 multipath_num, 0);
3300 /* Initialize graceful restart info */
3301 bgp->gr_info[afi][safi].eor_required = 0;
3302 bgp->gr_info[afi][safi].eor_received = 0;
3303 bgp->gr_info[afi][safi].t_select_deferral = NULL;
3304 bgp->gr_info[afi][safi].t_route_select = NULL;
3305 bgp->gr_info[afi][safi].gr_deferred = 0;
3306 }
3307
3308 bgp->v_update_delay = bm->v_update_delay;
3309 bgp->v_establish_wait = bm->v_establish_wait;
3310 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
3311 bgp->default_subgroup_pkt_queue_max =
3312 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
3313 bgp_tcp_keepalive_unset(bgp);
3314 bgp_timers_unset(bgp);
3315 bgp->default_min_holdtime = 0;
3316 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
3317 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
3318 bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME;
3319 bgp->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME;
3320 bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
3321 bgp->dynamic_neighbors_count = 0;
3322 bgp->lb_ref_bw = BGP_LINK_BW_REF_BW;
3323 bgp->lb_handling = BGP_LINK_BW_ECMP;
3324 bgp->reject_as_sets = false;
3325 bgp->condition_check_period = DEFAULT_CONDITIONAL_ROUTES_POLL_TIME;
3326 bgp_addpath_init_bgp_data(&bgp->tx_addpath);
3327 bgp->fast_convergence = false;
3328 bgp->llgr_stale_time = BGP_DEFAULT_LLGR_STALE_TIME;
3329
3330 #ifdef ENABLE_BGP_VNC
3331 if (inst_type != BGP_INSTANCE_TYPE_VRF) {
3332 bgp->rfapi = bgp_rfapi_new(bgp);
3333 assert(bgp->rfapi);
3334 assert(bgp->rfapi_cfg);
3335 }
3336 #endif /* ENABLE_BGP_VNC */
3337
3338 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3339 bgp->vpn_policy[afi].bgp = bgp;
3340 bgp->vpn_policy[afi].afi = afi;
3341 bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
3342 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent =
3343 MPLS_LABEL_NONE;
3344
3345 bgp->vpn_policy[afi].import_vrf = list_new();
3346 bgp->vpn_policy[afi].import_vrf->del =
3347 bgp_vrf_string_name_delete;
3348 bgp->vpn_policy[afi].export_vrf = list_new();
3349 bgp->vpn_policy[afi].export_vrf->del =
3350 bgp_vrf_string_name_delete;
3351 SET_FLAG(bgp->af_flags[afi][SAFI_MPLS_VPN],
3352 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL);
3353 }
3354 if (name)
3355 bgp->name = XSTRDUP(MTYPE_BGP, name);
3356
3357 thread_add_timer(bm->master, bgp_startup_timer_expire, bgp,
3358 bgp->restart_time, &bgp->t_startup);
3359
3360 /* printable name we can use in debug messages */
3361 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
3362 bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
3363 } else {
3364 const char *n;
3365 int len;
3366
3367 if (bgp->name)
3368 n = bgp->name;
3369 else
3370 n = "?";
3371
3372 len = 4 + 1 + strlen(n) + 1; /* "view foo\0" */
3373
3374 bgp->name_pretty = XCALLOC(MTYPE_BGP, len);
3375 snprintf(bgp->name_pretty, len, "%s %s",
3376 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3377 ? "VRF"
3378 : "VIEW",
3379 n);
3380 }
3381
3382 atomic_store_explicit(&bgp->wpkt_quanta, BGP_WRITE_PACKET_MAX,
3383 memory_order_relaxed);
3384 atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
3385 memory_order_relaxed);
3386 bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
3387 bgp->default_af[AFI_IP][SAFI_UNICAST] = true;
3388
3389 QOBJ_REG(bgp, bgp);
3390
3391 update_bgp_group_init(bgp);
3392
3393 /* assign a unique rd id for auto derivation of vrf's RD */
3394 bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
3395
3396 bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO,
3397 sizeof(struct bgp_evpn_info));
3398 bgp_evpn_init(bgp);
3399 bgp_evpn_vrf_es_init(bgp);
3400 bgp_pbr_init(bgp);
3401 bgp_srv6_init(bgp);
3402
3403 /*initilize global GR FSM */
3404 bgp_global_gr_init(bgp);
3405
3406 memset(&bgp->ebgprequirespolicywarning, 0,
3407 sizeof(bgp->ebgprequirespolicywarning));
3408
3409 return bgp;
3410 }
3411
3412 /* Return the "default VRF" instance of BGP. */
3413 struct bgp *bgp_get_default(void)
3414 {
3415 struct bgp *bgp;
3416 struct listnode *node, *nnode;
3417
3418 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3419 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3420 return bgp;
3421 return NULL;
3422 }
3423
3424 /* Lookup BGP entry. */
3425 struct bgp *bgp_lookup(as_t as, const char *name)
3426 {
3427 struct bgp *bgp;
3428 struct listnode *node, *nnode;
3429
3430 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3431 if (bgp->as == as
3432 && ((bgp->name == NULL && name == NULL)
3433 || (bgp->name && name && strcmp(bgp->name, name) == 0)))
3434 return bgp;
3435 return NULL;
3436 }
3437
3438 /* Lookup BGP structure by view name. */
3439 struct bgp *bgp_lookup_by_name(const char *name)
3440 {
3441 struct bgp *bgp;
3442 struct listnode *node, *nnode;
3443
3444 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3445 if ((bgp->name == NULL && name == NULL)
3446 || (bgp->name && name && strcmp(bgp->name, name) == 0))
3447 return bgp;
3448 return NULL;
3449 }
3450
3451 /* Lookup BGP instance based on VRF id. */
3452 /* Note: Only to be used for incoming messages from Zebra. */
3453 struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
3454 {
3455 struct vrf *vrf;
3456
3457 /* Lookup VRF (in tree) and follow link. */
3458 vrf = vrf_lookup_by_id(vrf_id);
3459 if (!vrf)
3460 return NULL;
3461 return (vrf->info) ? (struct bgp *)vrf->info : NULL;
3462 }
3463
3464 /* Sets the BGP instance where EVPN is enabled */
3465 void bgp_set_evpn(struct bgp *bgp)
3466 {
3467 if (bm->bgp_evpn == bgp)
3468 return;
3469
3470 /* First, release the reference count we hold on the instance */
3471 if (bm->bgp_evpn)
3472 bgp_unlock(bm->bgp_evpn);
3473
3474 bm->bgp_evpn = bgp;
3475
3476 /* Increase the reference count on this new VRF */
3477 if (bm->bgp_evpn)
3478 bgp_lock(bm->bgp_evpn);
3479 }
3480
3481 /* Returns the BGP instance where EVPN is enabled, if any */
3482 struct bgp *bgp_get_evpn(void)
3483 {
3484 return bm->bgp_evpn;
3485 }
3486
3487 /* handle socket creation or deletion, if necessary
3488 * this is called for all new BGP instances
3489 */
3490 int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
3491 bool create)
3492 {
3493 struct listnode *node;
3494 char *address;
3495
3496 /* Create BGP server socket, if listen mode not disabled */
3497 if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
3498 return 0;
3499 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3500 /*
3501 * suppress vrf socket
3502 */
3503 if (!create) {
3504 bgp_close_vrf_socket(bgp);
3505 return 0;
3506 }
3507 if (vrf == NULL)
3508 return BGP_ERR_INVALID_VALUE;
3509 /* do nothing
3510 * if vrf_id did not change
3511 */
3512 if (vrf->vrf_id == old_vrf_id)
3513 return 0;
3514 if (old_vrf_id != VRF_UNKNOWN) {
3515 /* look for old socket. close it. */
3516 bgp_close_vrf_socket(bgp);
3517 }
3518 /* if backend is not yet identified ( VRF_UNKNOWN) then
3519 * creation will be done later
3520 */
3521 if (vrf->vrf_id == VRF_UNKNOWN)
3522 return 0;
3523 if (list_isempty(bm->addresses)) {
3524 if (bgp_socket(bgp, bm->port, NULL) < 0)
3525 return BGP_ERR_INVALID_VALUE;
3526 } else {
3527 for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address))
3528 if (bgp_socket(bgp, bm->port, address) < 0)
3529 return BGP_ERR_INVALID_VALUE;
3530 }
3531 return 0;
3532 } else
3533 return bgp_check_main_socket(create, bgp);
3534 }
3535
3536 int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name,
3537 enum bgp_instance_type inst_type)
3538 {
3539 struct bgp *bgp;
3540
3541 /* Multiple instance check. */
3542 if (name)
3543 bgp = bgp_lookup_by_name(name);
3544 else
3545 bgp = bgp_get_default();
3546
3547 if (bgp) {
3548 *bgp_val = bgp;
3549 if (bgp->as != *as) {
3550 *as = bgp->as;
3551 return BGP_ERR_AS_MISMATCH;
3552 }
3553 if (bgp->inst_type != inst_type)
3554 return BGP_ERR_INSTANCE_MISMATCH;
3555 return BGP_SUCCESS;
3556 }
3557 *bgp_val = NULL;
3558
3559 return BGP_SUCCESS;
3560 }
3561
3562 /* Called from VTY commands. */
3563 int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
3564 enum bgp_instance_type inst_type, const char *as_pretty,
3565 enum asnotation_mode asnotation)
3566 {
3567 struct bgp *bgp;
3568 struct vrf *vrf = NULL;
3569 int ret = 0;
3570
3571 ret = bgp_lookup_by_as_name_type(bgp_val, as, name, inst_type);
3572 if (ret || *bgp_val)
3573 return ret;
3574
3575 bgp = bgp_create(as, name, inst_type, as_pretty, asnotation);
3576
3577 /*
3578 * view instances will never work inside of a vrf
3579 * as such they must always be in the VRF_DEFAULT
3580 * Also we must set this to something useful because
3581 * of the vrf socket code needing an actual useful
3582 * default value to send to the underlying OS.
3583 *
3584 * This code is currently ignoring vrf based
3585 * code using the -Z option( and that is probably
3586 * best addressed elsewhere in the code )
3587 */
3588 if (inst_type == BGP_INSTANCE_TYPE_VIEW)
3589 bgp->vrf_id = VRF_DEFAULT;
3590
3591 bgp_router_id_set(bgp, &bgp->router_id_zebra, true);
3592 bgp_address_init(bgp);
3593 bgp_tip_hash_init(bgp);
3594 bgp_scan_init(bgp);
3595 *bgp_val = bgp;
3596
3597 bgp->t_rmap_def_originate_eval = NULL;
3598
3599 /* If Default instance or VRF, link to the VRF structure, if present. */
3600 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
3601 || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3602 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3603 if (vrf)
3604 bgp_vrf_link(bgp, vrf);
3605 }
3606 /* BGP server socket already processed if BGP instance
3607 * already part of the list
3608 */
3609 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, true);
3610 listnode_add(bm->bgp, bgp);
3611
3612 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3613 if (BGP_DEBUG(zebra, ZEBRA))
3614 zlog_debug("%s: Registering BGP instance %s to zebra",
3615 __func__, bgp->name_pretty);
3616 bgp_zebra_instance_register(bgp);
3617 }
3618
3619 return BGP_CREATED;
3620 }
3621
3622 static void bgp_zclient_set_redist(afi_t afi, int type, unsigned short instance,
3623 vrf_id_t vrf_id, bool set)
3624 {
3625 if (instance) {
3626 if (set)
3627 redist_add_instance(&zclient->mi_redist[afi][type],
3628 instance);
3629 else
3630 redist_del_instance(&zclient->mi_redist[afi][type],
3631 instance);
3632 } else {
3633 if (set)
3634 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3635 else
3636 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3637 }
3638 }
3639
3640 static void bgp_set_redist_vrf_bitmaps(struct bgp *bgp, bool set)
3641 {
3642 afi_t afi;
3643 int i;
3644 struct list *red_list;
3645 struct listnode *node;
3646 struct bgp_redist *red;
3647
3648 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3649 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
3650
3651 red_list = bgp->redist[afi][i];
3652 if (!red_list)
3653 continue;
3654
3655 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
3656 bgp_zclient_set_redist(afi, i, red->instance,
3657 bgp->vrf_id, set);
3658 }
3659 }
3660 }
3661
3662 /*
3663 * Make BGP instance "up". Applies only to VRFs (non-default) and
3664 * implies the VRF has been learnt from Zebra.
3665 */
3666 void bgp_instance_up(struct bgp *bgp)
3667 {
3668 struct peer *peer;
3669 struct listnode *node, *next;
3670
3671 bgp_set_redist_vrf_bitmaps(bgp, true);
3672
3673 /* Register with zebra. */
3674 bgp_zebra_instance_register(bgp);
3675
3676 /* Kick off any peers that may have been configured. */
3677 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3678 if (!BGP_PEER_START_SUPPRESSED(peer))
3679 BGP_EVENT_ADD(peer, BGP_Start);
3680 }
3681
3682 /* Process any networks that have been configured. */
3683 bgp_static_add(bgp);
3684 }
3685
3686 /*
3687 * Make BGP instance "down". Applies only to VRFs (non-default) and
3688 * implies the VRF has been deleted by Zebra.
3689 */
3690 void bgp_instance_down(struct bgp *bgp)
3691 {
3692 struct peer *peer;
3693 struct listnode *node;
3694 struct listnode *next;
3695
3696 /* Stop timers. */
3697 if (bgp->t_rmap_def_originate_eval) {
3698 THREAD_OFF(bgp->t_rmap_def_originate_eval);
3699 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3700 why? */
3701 }
3702
3703 /* Bring down peers, so corresponding routes are purged. */
3704 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3705 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3706 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3707 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3708 else
3709 bgp_session_reset(peer);
3710 }
3711
3712 /* Purge network and redistributed routes. */
3713 bgp_purge_static_redist_routes(bgp);
3714
3715 /* Cleanup registered nexthops (flags) */
3716 bgp_cleanup_nexthops(bgp);
3717
3718 bgp_zebra_instance_deregister(bgp);
3719
3720 bgp_set_redist_vrf_bitmaps(bgp, false);
3721 }
3722
3723 /* Delete BGP instance. */
3724 int bgp_delete(struct bgp *bgp)
3725 {
3726 struct peer *peer;
3727 struct peer_group *group;
3728 struct listnode *node, *next;
3729 struct vrf *vrf;
3730 afi_t afi;
3731 safi_t safi;
3732 int i;
3733 struct graceful_restart_info *gr_info;
3734
3735 assert(bgp);
3736
3737 bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL);
3738
3739 /* make sure we withdraw any exported routes */
3740 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP, bgp_get_default(),
3741 bgp);
3742 vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, AFI_IP6, bgp_get_default(),
3743 bgp);
3744
3745 bgp_vpn_leak_unimport(bgp);
3746
3747 hook_call(bgp_inst_delete, bgp);
3748
3749 FOREACH_AFI_SAFI (afi, safi)
3750 THREAD_OFF(bgp->t_revalidate[afi][safi]);
3751
3752 THREAD_OFF(bgp->t_condition_check);
3753 THREAD_OFF(bgp->t_startup);
3754 THREAD_OFF(bgp->t_maxmed_onstartup);
3755 THREAD_OFF(bgp->t_update_delay);
3756 THREAD_OFF(bgp->t_establish_wait);
3757
3758 /* Set flag indicating bgp instance delete in progress */
3759 SET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS);
3760
3761 /* Delete the graceful restart info */
3762 FOREACH_AFI_SAFI (afi, safi) {
3763 struct thread *t;
3764
3765 gr_info = &bgp->gr_info[afi][safi];
3766 if (!gr_info)
3767 continue;
3768 t = gr_info->t_select_deferral;
3769 if (t) {
3770 void *info = THREAD_ARG(t);
3771
3772 XFREE(MTYPE_TMP, info);
3773 }
3774 THREAD_OFF(gr_info->t_select_deferral);
3775
3776 t = gr_info->t_route_select;
3777 if (t) {
3778 void *info = THREAD_ARG(t);
3779
3780 XFREE(MTYPE_TMP, info);
3781 }
3782 THREAD_OFF(gr_info->t_route_select);
3783 }
3784
3785 if (BGP_DEBUG(zebra, ZEBRA)) {
3786 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3787 zlog_debug("Deleting Default VRF");
3788 else
3789 zlog_debug("Deleting %s %s",
3790 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3791 ? "VRF"
3792 : "VIEW",
3793 bgp->name);
3794 }
3795
3796 /* unmap from RT list */
3797 bgp_evpn_vrf_delete(bgp);
3798
3799 /* unmap bgp vrf label */
3800 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
3801 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
3802
3803 /* Stop timers. */
3804 if (bgp->t_rmap_def_originate_eval) {
3805 THREAD_OFF(bgp->t_rmap_def_originate_eval);
3806 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3807 why? */
3808 }
3809
3810 /* Inform peers we're going down. */
3811 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
3812 peer_notify_shutdown(peer);
3813
3814 /* Delete static routes (networks). */
3815 bgp_static_delete(bgp);
3816
3817 /* Unset redistribution. */
3818 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3819 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3820 if (i != ZEBRA_ROUTE_BGP)
3821 bgp_redistribute_unset(bgp, afi, i, 0);
3822
3823 /* Free peers and peer-groups. */
3824 for (ALL_LIST_ELEMENTS(bgp->group, node, next, group))
3825 peer_group_delete(group);
3826
3827 while (listcount(bgp->peer)) {
3828 peer = listnode_head(bgp->peer);
3829 peer_delete(peer);
3830 }
3831
3832 if (bgp->peer_self) {
3833 peer_delete(bgp->peer_self);
3834 bgp->peer_self = NULL;
3835 }
3836
3837 update_bgp_group_free(bgp);
3838
3839 /* TODO - Other memory may need to be freed - e.g., NHT */
3840
3841 #ifdef ENABLE_BGP_VNC
3842 rfapi_delete(bgp);
3843 #endif
3844 bgp_cleanup_routes(bgp);
3845
3846 for (afi = 0; afi < AFI_MAX; ++afi) {
3847 if (!bgp->vpn_policy[afi].import_redirect_rtlist)
3848 continue;
3849 ecommunity_free(
3850 &bgp->vpn_policy[afi]
3851 .import_redirect_rtlist);
3852 bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
3853 }
3854
3855 /* Free any memory allocated to holding routemap references */
3856 for (afi = 0; afi < AFI_MAX; ++afi) {
3857 for (enum vpn_policy_direction dir = 0;
3858 dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
3859 if (bgp->vpn_policy[afi].rmap_name[dir])
3860 XFREE(MTYPE_ROUTE_MAP_NAME,
3861 bgp->vpn_policy[afi].rmap_name[dir]);
3862 bgp->vpn_policy[afi].rmap[dir] = NULL;
3863 }
3864 }
3865
3866 /* Deregister from Zebra, if needed */
3867 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3868 if (BGP_DEBUG(zebra, ZEBRA))
3869 zlog_debug(
3870 "%s: deregistering this bgp %s instance from zebra",
3871 __func__, bgp->name);
3872 bgp_zebra_instance_deregister(bgp);
3873 }
3874
3875 /* Remove visibility via the master list - there may however still be
3876 * routes to be processed still referencing the struct bgp.
3877 */
3878 listnode_delete(bm->bgp, bgp);
3879
3880 /* Free interfaces in this instance. */
3881 bgp_if_finish(bgp);
3882
3883 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3884 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
3885 if (vrf)
3886 bgp_vrf_unlink(bgp, vrf);
3887
3888 /* Update EVPN VRF pointer */
3889 if (bm->bgp_evpn == bgp) {
3890 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3891 bgp_set_evpn(NULL);
3892 else
3893 bgp_set_evpn(bgp_get_default());
3894 }
3895
3896 if (bgp->process_queue)
3897 work_queue_free_and_null(&bgp->process_queue);
3898
3899 thread_master_free_unused(bm->master);
3900 bgp_unlock(bgp); /* initial reference */
3901
3902 return 0;
3903 }
3904
3905 void bgp_free(struct bgp *bgp)
3906 {
3907 afi_t afi;
3908 safi_t safi;
3909 struct bgp_table *table;
3910 struct bgp_dest *dest;
3911 struct bgp_rmap *rmap;
3912
3913 QOBJ_UNREG(bgp);
3914
3915 list_delete(&bgp->group);
3916 list_delete(&bgp->peer);
3917
3918 if (bgp->peerhash) {
3919 hash_free(bgp->peerhash);
3920 bgp->peerhash = NULL;
3921 }
3922
3923 FOREACH_AFI_SAFI (afi, safi) {
3924 /* Special handling for 2-level routing tables. */
3925 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
3926 || safi == SAFI_EVPN) {
3927 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
3928 dest = bgp_route_next(dest)) {
3929 table = bgp_dest_get_bgp_table_info(dest);
3930 bgp_table_finish(&table);
3931 }
3932 }
3933 if (bgp->route[afi][safi])
3934 bgp_table_finish(&bgp->route[afi][safi]);
3935 if (bgp->aggregate[afi][safi])
3936 bgp_table_finish(&bgp->aggregate[afi][safi]);
3937 if (bgp->rib[afi][safi])
3938 bgp_table_finish(&bgp->rib[afi][safi]);
3939 rmap = &bgp->table_map[afi][safi];
3940 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
3941 }
3942
3943 bgp_scan_finish(bgp);
3944 bgp_address_destroy(bgp);
3945 bgp_tip_hash_destroy(bgp);
3946
3947 /* release the auto RD id */
3948 bf_release_index(bm->rd_idspace, bgp->vrf_rd_id);
3949
3950 bgp_evpn_cleanup(bgp);
3951 bgp_pbr_cleanup(bgp);
3952 bgp_srv6_cleanup(bgp);
3953 XFREE(MTYPE_BGP_EVPN_INFO, bgp->evpn_info);
3954
3955 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3956 enum vpn_policy_direction dir;
3957
3958 if (bgp->vpn_policy[afi].import_vrf)
3959 list_delete(&bgp->vpn_policy[afi].import_vrf);
3960 if (bgp->vpn_policy[afi].export_vrf)
3961 list_delete(&bgp->vpn_policy[afi].export_vrf);
3962
3963 dir = BGP_VPN_POLICY_DIR_FROMVPN;
3964 if (bgp->vpn_policy[afi].rtlist[dir])
3965 ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3966 dir = BGP_VPN_POLICY_DIR_TOVPN;
3967 if (bgp->vpn_policy[afi].rtlist[dir])
3968 ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3969 if (bgp->vpn_policy[afi].tovpn_rd_pretty)
3970 XFREE(MTYPE_BGP, bgp->vpn_policy[afi].tovpn_rd_pretty);
3971 }
3972
3973 bgp_confederation_id_unset(bgp);
3974
3975 XFREE(MTYPE_BGP, bgp->as_pretty);
3976 XFREE(MTYPE_BGP, bgp->name);
3977 XFREE(MTYPE_BGP, bgp->name_pretty);
3978 XFREE(MTYPE_BGP, bgp->snmp_stats);
3979
3980 XFREE(MTYPE_BGP, bgp);
3981 }
3982
3983 struct peer *peer_lookup_by_conf_if(struct bgp *bgp, const char *conf_if)
3984 {
3985 struct peer *peer;
3986 struct listnode *node, *nnode;
3987
3988 if (!conf_if)
3989 return NULL;
3990
3991 if (bgp != NULL) {
3992 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3993 if (peer->conf_if && !strcmp(peer->conf_if, conf_if)
3994 && !CHECK_FLAG(peer->sflags,
3995 PEER_STATUS_ACCEPT_PEER))
3996 return peer;
3997 } else if (bm->bgp != NULL) {
3998 struct listnode *bgpnode, *nbgpnode;
3999
4000 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
4001 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4002 if (peer->conf_if
4003 && !strcmp(peer->conf_if, conf_if)
4004 && !CHECK_FLAG(peer->sflags,
4005 PEER_STATUS_ACCEPT_PEER))
4006 return peer;
4007 }
4008 return NULL;
4009 }
4010
4011 struct peer *peer_lookup_by_hostname(struct bgp *bgp, const char *hostname)
4012 {
4013 struct peer *peer;
4014 struct listnode *node, *nnode;
4015
4016 if (!hostname)
4017 return NULL;
4018
4019 if (bgp != NULL) {
4020 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4021 if (peer->hostname && !strcmp(peer->hostname, hostname)
4022 && !CHECK_FLAG(peer->sflags,
4023 PEER_STATUS_ACCEPT_PEER))
4024 return peer;
4025 } else if (bm->bgp != NULL) {
4026 struct listnode *bgpnode, *nbgpnode;
4027
4028 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
4029 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
4030 if (peer->hostname
4031 && !strcmp(peer->hostname, hostname)
4032 && !CHECK_FLAG(peer->sflags,
4033 PEER_STATUS_ACCEPT_PEER))
4034 return peer;
4035 }
4036 return NULL;
4037 }
4038
4039 struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
4040 {
4041 struct peer *peer = NULL;
4042 struct peer tmp_peer;
4043
4044 memset(&tmp_peer, 0, sizeof(struct peer));
4045
4046 /*
4047 * We do not want to find the doppelganger peer so search for the peer
4048 * in
4049 * the hash that has PEER_FLAG_CONFIG_NODE
4050 */
4051 SET_FLAG(tmp_peer.flags, PEER_FLAG_CONFIG_NODE);
4052
4053 tmp_peer.su = *su;
4054
4055 if (bgp != NULL) {
4056 peer = hash_lookup(bgp->peerhash, &tmp_peer);
4057 } else if (bm->bgp != NULL) {
4058 struct listnode *bgpnode, *nbgpnode;
4059
4060 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp)) {
4061 peer = hash_lookup(bgp->peerhash, &tmp_peer);
4062 if (peer)
4063 break;
4064 }
4065 }
4066
4067 return peer;
4068 }
4069
4070 struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
4071 union sockunion *su,
4072 struct peer_group *group)
4073 {
4074 struct peer *peer;
4075 afi_t afi;
4076 safi_t safi;
4077
4078 /* Create peer first; we've already checked group config is valid. */
4079 peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
4080 group->conf->as_type, group, true, NULL);
4081 if (!peer)
4082 return NULL;
4083
4084 /* Link to group */
4085 peer = peer_lock(peer);
4086 listnode_add(group->peer, peer);
4087
4088 peer_group2peer_config_copy(group, peer);
4089
4090 /*
4091 * Bind peer for all AFs configured for the group. We don't call
4092 * peer_group_bind as that is sub-optimal and does some stuff we don't
4093 * want.
4094 */
4095 FOREACH_AFI_SAFI (afi, safi) {
4096 if (!group->conf->afc[afi][safi])
4097 continue;
4098 peer->afc[afi][safi] = 1;
4099
4100 if (!peer_af_find(peer, afi, safi))
4101 peer_af_create(peer, afi, safi);
4102
4103 peer_group2peer_config_copy_af(group, peer, afi, safi);
4104 }
4105
4106 /* Mark as dynamic, but also as a "config node" for other things to
4107 * work. */
4108 SET_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR);
4109
4110 return peer;
4111 }
4112
4113 struct prefix *
4114 peer_group_lookup_dynamic_neighbor_range(struct peer_group *group,
4115 struct prefix *prefix)
4116 {
4117 struct listnode *node, *nnode;
4118 struct prefix *range;
4119 afi_t afi;
4120
4121 afi = family2afi(prefix->family);
4122
4123 if (group->listen_range[afi])
4124 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
4125 range))
4126 if (prefix_match(range, prefix))
4127 return range;
4128
4129 return NULL;
4130 }
4131
4132 struct peer_group *
4133 peer_group_lookup_dynamic_neighbor(struct bgp *bgp, struct prefix *prefix,
4134 struct prefix **listen_range)
4135 {
4136 struct prefix *range = NULL;
4137 struct peer_group *group = NULL;
4138 struct listnode *node, *nnode;
4139
4140 *listen_range = NULL;
4141 if (bgp != NULL) {
4142 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
4143 if ((range = peer_group_lookup_dynamic_neighbor_range(
4144 group, prefix)))
4145 break;
4146 } else if (bm->bgp != NULL) {
4147 struct listnode *bgpnode, *nbgpnode;
4148
4149 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
4150 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
4151 if ((range = peer_group_lookup_dynamic_neighbor_range(
4152 group, prefix)))
4153 goto found_range;
4154 }
4155
4156 found_range:
4157 *listen_range = range;
4158 return (group && range) ? group : NULL;
4159 }
4160
4161 struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
4162 {
4163 struct peer_group *group;
4164 struct bgp *gbgp;
4165 struct peer *peer;
4166 struct prefix prefix;
4167 struct prefix *listen_range;
4168 int dncount;
4169
4170 if (!sockunion2hostprefix(su, &prefix))
4171 return NULL;
4172
4173 /* See if incoming connection matches a configured listen range. */
4174 group = peer_group_lookup_dynamic_neighbor(bgp, &prefix, &listen_range);
4175
4176 if (!group)
4177 return NULL;
4178
4179
4180 gbgp = group->bgp;
4181
4182 if (!gbgp)
4183 return NULL;
4184
4185 if (bgp_debug_neighbor_events(NULL))
4186 zlog_debug(
4187 "Dynamic Neighbor %pFX matches group %s listen range %pFX",
4188 &prefix, group->name, listen_range);
4189
4190 /* Are we within the listen limit? */
4191 dncount = gbgp->dynamic_neighbors_count;
4192
4193 if (dncount >= gbgp->dynamic_neighbors_limit) {
4194 if (bgp_debug_neighbor_events(NULL))
4195 zlog_debug(
4196 "Dynamic Neighbor %pFX rejected - at limit %d",
4197 &prefix, gbgp->dynamic_neighbors_limit);
4198 return NULL;
4199 }
4200
4201 /* Ensure group is not disabled. */
4202 if (CHECK_FLAG(group->conf->flags, PEER_FLAG_SHUTDOWN)) {
4203 if (bgp_debug_neighbor_events(NULL))
4204 zlog_debug(
4205 "Dynamic Neighbor %pFX rejected - group %s disabled",
4206 &prefix, group->name);
4207 return NULL;
4208 }
4209
4210 /* Check that at least one AF is activated for the group. */
4211 if (!peer_group_af_configured(group)) {
4212 if (bgp_debug_neighbor_events(NULL))
4213 zlog_debug(
4214 "Dynamic Neighbor %pFX rejected - no AF activated for group %s",
4215 &prefix, group->name);
4216 return NULL;
4217 }
4218
4219 /* Create dynamic peer and bind to associated group. */
4220 peer = peer_create_bind_dynamic_neighbor(gbgp, su, group);
4221 assert(peer);
4222
4223 gbgp->dynamic_neighbors_count = ++dncount;
4224
4225 if (bgp_debug_neighbor_events(peer))
4226 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
4227 peer->host, group->name, dncount);
4228
4229 return peer;
4230 }
4231
4232 static void peer_drop_dynamic_neighbor(struct peer *peer)
4233 {
4234 int dncount = -1;
4235 if (peer->group->bgp) {
4236 dncount = peer->group->bgp->dynamic_neighbors_count;
4237 if (dncount)
4238 peer->group->bgp->dynamic_neighbors_count = --dncount;
4239 }
4240 if (bgp_debug_neighbor_events(peer))
4241 zlog_debug("%s dropped from group %s, count %d", peer->host,
4242 peer->group->name, dncount);
4243 }
4244
4245 bool bgp_path_attribute_discard(struct peer *peer, char *buf, size_t size)
4246 {
4247 if (!buf)
4248 return false;
4249
4250 buf[0] = '\0';
4251
4252 for (unsigned int i = 0; i < BGP_ATTR_MAX; i++) {
4253 if (peer->discard_attrs[i])
4254 snprintf(buf + strlen(buf), size - strlen(buf), "%s%d",
4255 (strlen(buf) > 0) ? " " : "", i);
4256 }
4257
4258 if (strlen(buf) > 0)
4259 return true;
4260
4261 return false;
4262 }
4263
4264 bool bgp_path_attribute_treat_as_withdraw(struct peer *peer, char *buf,
4265 size_t size)
4266 {
4267 if (!buf)
4268 return false;
4269
4270 buf[0] = '\0';
4271
4272 for (unsigned int i = 0; i < BGP_ATTR_MAX; i++) {
4273 if (peer->withdraw_attrs[i])
4274 snprintf(buf + strlen(buf), size - strlen(buf), "%s%d",
4275 (strlen(buf) > 0) ? " " : "", i);
4276 }
4277
4278 if (strlen(buf) > 0)
4279 return true;
4280
4281 return false;
4282 }
4283
4284 /* If peer is configured at least one address family return 1. */
4285 bool peer_active(struct peer *peer)
4286 {
4287 if (BGP_PEER_SU_UNSPEC(peer))
4288 return false;
4289 if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
4290 || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
4291 || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
4292 || peer->afc[AFI_IP][SAFI_FLOWSPEC]
4293 || peer->afc[AFI_IP6][SAFI_UNICAST]
4294 || peer->afc[AFI_IP6][SAFI_MULTICAST]
4295 || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
4296 || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
4297 || peer->afc[AFI_IP6][SAFI_ENCAP]
4298 || peer->afc[AFI_IP6][SAFI_FLOWSPEC]
4299 || peer->afc[AFI_L2VPN][SAFI_EVPN])
4300 return true;
4301 return false;
4302 }
4303
4304 /* If peer is negotiated at least one address family return 1. */
4305 bool peer_active_nego(struct peer *peer)
4306 {
4307 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
4308 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
4309 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
4310 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
4311 || peer->afc_nego[AFI_IP][SAFI_ENCAP]
4312 || peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
4313 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
4314 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
4315 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
4316 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
4317 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]
4318 || peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
4319 || peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
4320 return true;
4321 return false;
4322 }
4323
4324 /* If peer received at least one address family MP, return true */
4325 bool peer_afc_received(struct peer *peer)
4326 {
4327 afi_t afi;
4328 safi_t safi;
4329
4330 FOREACH_AFI_SAFI (afi, safi)
4331 if (peer->afc_recv[afi][safi])
4332 return true;
4333
4334 return false;
4335 }
4336
4337 /* If peer advertised at least one address family MP, return true */
4338 bool peer_afc_advertised(struct peer *peer)
4339 {
4340 afi_t afi;
4341 safi_t safi;
4342
4343 FOREACH_AFI_SAFI (afi, safi)
4344 if (peer->afc_adv[afi][safi])
4345 return true;
4346
4347 return false;
4348 }
4349
4350 void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
4351 enum peer_change_type type)
4352 {
4353 struct peer_af *paf;
4354
4355 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4356 return;
4357
4358 if (!peer_established(peer))
4359 return;
4360
4361 if (type == peer_change_reset) {
4362 /* If we're resetting session, we've to delete both peer struct
4363 */
4364 if ((peer->doppelganger)
4365 && (peer->doppelganger->status != Deleted)
4366 && (!CHECK_FLAG(peer->doppelganger->flags,
4367 PEER_FLAG_CONFIG_NODE)))
4368 peer_delete(peer->doppelganger);
4369
4370 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4371 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4372 } else if (type == peer_change_reset_in) {
4373 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4374 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4375 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0,
4376 BGP_ROUTE_REFRESH_NORMAL);
4377 else {
4378 if ((peer->doppelganger)
4379 && (peer->doppelganger->status != Deleted)
4380 && (!CHECK_FLAG(peer->doppelganger->flags,
4381 PEER_FLAG_CONFIG_NODE)))
4382 peer_delete(peer->doppelganger);
4383
4384 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4385 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4386 }
4387 } else if (type == peer_change_reset_out) {
4388 paf = peer_af_find(peer, afi, safi);
4389 if (paf && paf->subgroup)
4390 SET_FLAG(paf->subgroup->sflags,
4391 SUBGRP_STATUS_FORCE_UPDATES);
4392
4393 update_group_adjust_peer(paf);
4394 bgp_announce_route(peer, afi, safi, false);
4395 }
4396 }
4397
4398 struct peer_flag_action {
4399 /* Peer's flag. */
4400 uint64_t flag;
4401
4402 /* This flag can be set for peer-group member. */
4403 uint8_t not_for_member;
4404
4405 /* Action when the flag is changed. */
4406 enum peer_change_type type;
4407 };
4408
4409 static const struct peer_flag_action peer_flag_action_list[] = {
4410 {PEER_FLAG_PASSIVE, 0, peer_change_reset},
4411 {PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
4412 {PEER_FLAG_RTT_SHUTDOWN, 0, peer_change_none},
4413 {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
4414 {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
4415 {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
4416 {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset},
4417 {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset},
4418 {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset},
4419 {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in},
4420 {PEER_FLAG_IFPEER_V6ONLY, 0, peer_change_reset},
4421 {PEER_FLAG_ROUTEADV, 0, peer_change_none},
4422 {PEER_FLAG_TIMER, 0, peer_change_none},
4423 {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
4424 {PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none},
4425 {PEER_FLAG_PASSWORD, 0, peer_change_none},
4426 {PEER_FLAG_LOCAL_AS, 0, peer_change_reset},
4427 {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset},
4428 {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset},
4429 {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none},
4430 {PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none},
4431 {PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset},
4432 {PEER_FLAG_ROLE_STRICT_MODE, 0, peer_change_reset},
4433 {PEER_FLAG_ROLE, 0, peer_change_reset},
4434 {PEER_FLAG_PORT, 0, peer_change_reset},
4435 {PEER_FLAG_AIGP, 0, peer_change_none},
4436 {PEER_FLAG_GRACEFUL_SHUTDOWN, 0, peer_change_none},
4437 {PEER_FLAG_CAPABILITY_SOFT_VERSION, 0, peer_change_reset},
4438 {0, 0, 0}};
4439
4440 static const struct peer_flag_action peer_af_flag_action_list[] = {
4441 {PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out},
4442 {PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out},
4443 {PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out},
4444 {PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out},
4445 {PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset},
4446 {PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset},
4447 {PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in},
4448 {PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out},
4449 {PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out},
4450 {PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out},
4451 {PEER_FLAG_DEFAULT_ORIGINATE, 0, peer_change_none},
4452 {PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out},
4453 {PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in},
4454 {PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in},
4455 {PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset},
4456 {PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset},
4457 {PEER_FLAG_MAX_PREFIX, 0, peer_change_none},
4458 {PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none},
4459 {PEER_FLAG_MAX_PREFIX_FORCE, 0, peer_change_none},
4460 {PEER_FLAG_MAX_PREFIX_OUT, 0, peer_change_none},
4461 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out},
4462 {PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out},
4463 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out},
4464 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out},
4465 {PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out},
4466 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out},
4467 {PEER_FLAG_WEIGHT, 0, peer_change_reset_in},
4468 {PEER_FLAG_DISABLE_ADDPATH_RX, 0, peer_change_reset},
4469 {PEER_FLAG_SOO, 0, peer_change_reset},
4470 {PEER_FLAG_ACCEPT_OWN, 0, peer_change_reset},
4471 {0, 0, 0}};
4472
4473 /* Proper action set. */
4474 static int peer_flag_action_set(const struct peer_flag_action *action_list,
4475 int size, struct peer_flag_action *action,
4476 uint64_t flag)
4477 {
4478 int i;
4479 int found = 0;
4480 int reset_in = 0;
4481 int reset_out = 0;
4482 const struct peer_flag_action *match = NULL;
4483
4484 /* Check peer's frag action. */
4485 for (i = 0; i < size; i++) {
4486 match = &action_list[i];
4487
4488 if (match->flag == 0)
4489 break;
4490
4491 if (match->flag & flag) {
4492 found = 1;
4493
4494 if (match->type == peer_change_reset_in)
4495 reset_in = 1;
4496 if (match->type == peer_change_reset_out)
4497 reset_out = 1;
4498 if (match->type == peer_change_reset) {
4499 reset_in = 1;
4500 reset_out = 1;
4501 }
4502 if (match->not_for_member)
4503 action->not_for_member = 1;
4504 }
4505 }
4506
4507 /* Set peer clear type. */
4508 if (reset_in && reset_out)
4509 action->type = peer_change_reset;
4510 else if (reset_in)
4511 action->type = peer_change_reset_in;
4512 else if (reset_out)
4513 action->type = peer_change_reset_out;
4514 else
4515 action->type = peer_change_none;
4516
4517 return found;
4518 }
4519
4520 static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
4521 {
4522 if (flag == PEER_FLAG_SHUTDOWN) {
4523 if (CHECK_FLAG(peer->flags, flag)) {
4524 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
4525 peer_nsf_stop(peer);
4526
4527 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4528
4529 if (peer->t_pmax_restart) {
4530 THREAD_OFF(peer->t_pmax_restart);
4531 if (bgp_debug_neighbor_events(peer))
4532 zlog_debug(
4533 "%pBP Maximum-prefix restart timer canceled",
4534 peer);
4535 }
4536
4537 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4538 char *msg = peer->tx_shutdown_message;
4539 size_t msglen;
4540 uint8_t msgbuf[BGP_ADMIN_SHUTDOWN_MSG_LEN + 1];
4541
4542 if (!msg && peer_group_active(peer))
4543 msg = peer->group->conf
4544 ->tx_shutdown_message;
4545 msglen = msg ? strlen(msg) : 0;
4546 if (msglen > BGP_ADMIN_SHUTDOWN_MSG_LEN)
4547 msglen = BGP_ADMIN_SHUTDOWN_MSG_LEN;
4548
4549 if (msglen) {
4550 msgbuf[0] = msglen;
4551 memcpy(msgbuf + 1, msg, msglen);
4552
4553 bgp_notify_send_with_data(
4554 peer, BGP_NOTIFY_CEASE,
4555 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
4556 msgbuf, msglen + 1);
4557 } else
4558 bgp_notify_send(
4559 peer, BGP_NOTIFY_CEASE,
4560 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
4561 } else
4562 bgp_session_reset(peer);
4563 } else {
4564 peer->v_start = BGP_INIT_START_TIMER;
4565 BGP_EVENT_ADD(peer, BGP_Stop);
4566 }
4567 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4568 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
4569 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4570 else if (flag == PEER_FLAG_PASSIVE)
4571 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
4572 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
4573 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
4574
4575 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4576 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4577 } else
4578 bgp_session_reset(peer);
4579 }
4580
4581 /* Enable global administrative shutdown of all peers of BGP instance */
4582 void bgp_shutdown_enable(struct bgp *bgp, const char *msg)
4583 {
4584 struct peer *peer;
4585 struct listnode *node;
4586 /* length(1) + message(N) */
4587 uint8_t data[BGP_ADMIN_SHUTDOWN_MSG_LEN + 1];
4588
4589 /* do nothing if already shut down */
4590 if (CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
4591 return;
4592
4593 /* informational log message */
4594 zlog_info("Enabled administrative shutdown on BGP instance AS %u",
4595 bgp->as);
4596
4597 /* iterate through peers of BGP instance */
4598 for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
4599 /* continue, if peer is already in administrative shutdown. */
4600 if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN))
4601 continue;
4602
4603 /* send a RFC 4486 notification message if necessary */
4604 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4605 if (msg) {
4606 size_t datalen = strlen(msg);
4607
4608 if (datalen > BGP_ADMIN_SHUTDOWN_MSG_LEN)
4609 datalen = BGP_ADMIN_SHUTDOWN_MSG_LEN;
4610
4611 data[0] = datalen;
4612 memcpy(data + 1, msg, datalen);
4613
4614 bgp_notify_send_with_data(
4615 peer, BGP_NOTIFY_CEASE,
4616 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN, data,
4617 datalen + 1);
4618 } else {
4619 bgp_notify_send(
4620 peer, BGP_NOTIFY_CEASE,
4621 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
4622 }
4623 }
4624
4625 /* reset start timer to initial value */
4626 peer->v_start = BGP_INIT_START_TIMER;
4627
4628 /* trigger a RFC 4271 ManualStop event */
4629 BGP_EVENT_ADD(peer, BGP_Stop);
4630 }
4631
4632 /* set the BGP instances shutdown flag */
4633 SET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN);
4634 }
4635
4636 /* Disable global administrative shutdown of all peers of BGP instance */
4637 void bgp_shutdown_disable(struct bgp *bgp)
4638 {
4639 const struct listnode *node;
4640 struct peer *peer;
4641
4642 /* do nothing if not shut down. */
4643 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN))
4644 return;
4645
4646 /* informational log message */
4647 zlog_info("Disabled administrative shutdown on BGP instance AS %u",
4648 bgp->as);
4649
4650 /* clear the BGP instances shutdown flag */
4651 UNSET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN);
4652
4653 for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer))
4654 bgp_timer_set(peer);
4655 }
4656
4657 /* Change specified peer flag. */
4658 static int peer_flag_modify(struct peer *peer, uint64_t flag, int set)
4659 {
4660 int found;
4661 int size;
4662 bool invert, member_invert;
4663 struct peer *member;
4664 struct listnode *node, *nnode;
4665 struct peer_flag_action action;
4666
4667 memset(&action, 0, sizeof(struct peer_flag_action));
4668 size = sizeof(peer_flag_action_list) / sizeof(struct peer_flag_action);
4669
4670 invert = CHECK_FLAG(peer->flags_invert, flag);
4671 found = peer_flag_action_set(peer_flag_action_list, size, &action,
4672 flag);
4673
4674 /* Abort if no flag action exists. */
4675 if (!found)
4676 return BGP_ERR_INVALID_FLAG;
4677
4678 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4679 if (set && CHECK_FLAG(peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
4680 && CHECK_FLAG(peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
4681 return BGP_ERR_PEER_FLAG_CONFLICT;
4682
4683 /* Handle flag updates where desired state matches current state. */
4684 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4685 if (set && CHECK_FLAG(peer->flags, flag)) {
4686 COND_FLAG(peer->flags_override, flag, !invert);
4687 return 0;
4688 }
4689
4690 if (!set && !CHECK_FLAG(peer->flags, flag)) {
4691 COND_FLAG(peer->flags_override, flag, invert);
4692 return 0;
4693 }
4694 }
4695
4696 /* Inherit from peer-group or set/unset flags accordingly. */
4697 if (peer_group_active(peer) && set == invert)
4698 peer_flag_inherit(peer, flag);
4699 else
4700 COND_FLAG(peer->flags, flag, set);
4701
4702 /* Check if handling a regular peer. */
4703 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4704 /* Update flag override state accordingly. */
4705 COND_FLAG(peer->flags_override, flag, set != invert);
4706
4707 /*
4708 * For the extended next-hop encoding flag we need to turn RAs
4709 * on if flag is being set, but only turn RAs off if the flag
4710 * is being unset on this peer and if this peer is a member of a
4711 * peer-group, the peer-group also doesn't have the flag set.
4712 */
4713 if (flag == PEER_FLAG_CAPABILITY_ENHE) {
4714 if (set) {
4715 bgp_zebra_initiate_radv(peer->bgp, peer);
4716 } else if (peer_group_active(peer)) {
4717 if (!CHECK_FLAG(peer->group->conf->flags,
4718 flag) &&
4719 !peer->conf_if)
4720 bgp_zebra_terminate_radv(peer->bgp,
4721 peer);
4722 } else
4723 bgp_zebra_terminate_radv(peer->bgp, peer);
4724 }
4725
4726 /* Execute flag action on peer. */
4727 if (action.type == peer_change_reset)
4728 peer_flag_modify_action(peer, flag);
4729
4730 /* Skip peer-group mechanics for regular peers. */
4731 return 0;
4732 }
4733
4734 /*
4735 * Update peer-group members, unless they are explicitly overriding
4736 * peer-group configuration.
4737 */
4738 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4739 /* Skip peers with overridden configuration. */
4740 if (CHECK_FLAG(member->flags_override, flag))
4741 continue;
4742
4743 /* Check if only member without group is inverted. */
4744 member_invert =
4745 CHECK_FLAG(member->flags_invert, flag) && !invert;
4746
4747 /* Skip peers with equivalent configuration. */
4748 if (set != member_invert && CHECK_FLAG(member->flags, flag))
4749 continue;
4750
4751 if (set == member_invert && !CHECK_FLAG(member->flags, flag))
4752 continue;
4753
4754 /* Update flag on peer-group member. */
4755 COND_FLAG(member->flags, flag, set != member_invert);
4756
4757 if (flag == PEER_FLAG_CAPABILITY_ENHE && !member->conf_if)
4758 set ? bgp_zebra_initiate_radv(member->bgp, member)
4759 : bgp_zebra_terminate_radv(member->bgp, member);
4760
4761 /* Execute flag action on peer-group member. */
4762 if (action.type == peer_change_reset)
4763 peer_flag_modify_action(member, flag);
4764 }
4765
4766 return 0;
4767 }
4768
4769 int peer_flag_set(struct peer *peer, uint64_t flag)
4770 {
4771 return peer_flag_modify(peer, flag, 1);
4772 }
4773
4774 int peer_flag_unset(struct peer *peer, uint64_t flag)
4775 {
4776 return peer_flag_modify(peer, flag, 0);
4777 }
4778
4779 static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
4780 uint64_t flag, bool set)
4781 {
4782 int found;
4783 int size;
4784 bool invert, member_invert;
4785 struct peer *member;
4786 struct listnode *node, *nnode;
4787 struct peer_flag_action action;
4788 enum bgp_peer_sort ptype;
4789
4790 memset(&action, 0, sizeof(struct peer_flag_action));
4791 size = sizeof(peer_af_flag_action_list)
4792 / sizeof(struct peer_flag_action);
4793
4794 invert = CHECK_FLAG(peer->af_flags_invert[afi][safi], flag);
4795 found = peer_flag_action_set(peer_af_flag_action_list, size, &action,
4796 flag);
4797
4798 /* Abort if flag action exists. */
4799 if (!found)
4800 return BGP_ERR_INVALID_FLAG;
4801
4802 ptype = peer_sort(peer);
4803 /* Special check for reflector client. */
4804 if (flag & PEER_FLAG_REFLECTOR_CLIENT && ptype != BGP_PEER_IBGP)
4805 return BGP_ERR_NOT_INTERNAL_PEER;
4806
4807 /* Special check for remove-private-AS. */
4808 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS && ptype == BGP_PEER_IBGP)
4809 return BGP_ERR_REMOVE_PRIVATE_AS;
4810
4811 /* as-override is not allowed for IBGP peers */
4812 if (flag & PEER_FLAG_AS_OVERRIDE && ptype == BGP_PEER_IBGP)
4813 return BGP_ERR_AS_OVERRIDE;
4814
4815 /* Handle flag updates where desired state matches current state. */
4816 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4817 if (set && CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4818 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4819 !invert);
4820 return 0;
4821 }
4822
4823 if (!set && !CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4824 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4825 invert);
4826 return 0;
4827 }
4828 }
4829
4830 /*
4831 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4832 * if we are setting/unsetting flags which conflict with this flag
4833 * handle accordingly
4834 */
4835 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
4836 if (set) {
4837
4838 /*
4839 * if we are setting NEXTHOP_SELF, we need to unset the
4840 * NEXTHOP_UNCHANGED flag
4841 */
4842 if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4843 CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4844 UNSET_FLAG(peer->af_flags[afi][safi],
4845 PEER_FLAG_NEXTHOP_UNCHANGED);
4846 } else {
4847
4848 /*
4849 * if we are unsetting NEXTHOP_SELF, we need to set the
4850 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4851 */
4852 if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4853 CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4854 SET_FLAG(peer->af_flags[afi][safi],
4855 PEER_FLAG_NEXTHOP_UNCHANGED);
4856 }
4857 }
4858
4859 /*
4860 * If the peer is a route server client let's not
4861 * muck with the nexthop on the way out the door
4862 */
4863 if (flag & PEER_FLAG_RSERVER_CLIENT) {
4864 if (set)
4865 SET_FLAG(peer->af_flags[afi][safi],
4866 PEER_FLAG_NEXTHOP_UNCHANGED);
4867 else
4868 UNSET_FLAG(peer->af_flags[afi][safi],
4869 PEER_FLAG_NEXTHOP_UNCHANGED);
4870 }
4871
4872 /* Inherit from peer-group or set/unset flags accordingly. */
4873 if (peer_group_active(peer) && set == invert)
4874 peer_af_flag_inherit(peer, afi, safi, flag);
4875 else
4876 COND_FLAG(peer->af_flags[afi][safi], flag, set);
4877
4878 /* Execute action when peer is established. */
4879 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4880 && peer_established(peer)) {
4881 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4882 bgp_clear_adj_in(peer, afi, safi);
4883 else {
4884 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4885 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
4886 else if (flag == PEER_FLAG_RSERVER_CLIENT)
4887 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
4888 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
4889 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4890 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
4891 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4892
4893 peer_change_action(peer, afi, safi, action.type);
4894 }
4895 }
4896
4897 /* Check if handling a regular peer. */
4898 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4899 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4900 set != invert);
4901 } else {
4902 /*
4903 * Update peer-group members, unless they are explicitly
4904 * overriding peer-group configuration.
4905 */
4906 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode,
4907 member)) {
4908 /* Skip peers with overridden configuration. */
4909 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4910 flag))
4911 continue;
4912
4913 /* Check if only member without group is inverted. */
4914 member_invert =
4915 CHECK_FLAG(member->af_flags_invert[afi][safi],
4916 flag)
4917 && !invert;
4918
4919 /* Skip peers with equivalent configuration. */
4920 if (set != member_invert
4921 && CHECK_FLAG(member->af_flags[afi][safi], flag))
4922 continue;
4923
4924 if (set == member_invert
4925 && !CHECK_FLAG(member->af_flags[afi][safi], flag))
4926 continue;
4927
4928 /* Update flag on peer-group member. */
4929 COND_FLAG(member->af_flags[afi][safi], flag,
4930 set != member_invert);
4931
4932 /* Execute flag action on peer-group member. */
4933 if (peer_established(member)) {
4934 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4935 bgp_clear_adj_in(member, afi, safi);
4936 else {
4937 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4938 member->last_reset =
4939 PEER_DOWN_RR_CLIENT_CHANGE;
4940 else if (flag
4941 == PEER_FLAG_RSERVER_CLIENT)
4942 member->last_reset =
4943 PEER_DOWN_RS_CLIENT_CHANGE;
4944 else if (flag
4945 == PEER_FLAG_ORF_PREFIX_SM)
4946 member->last_reset =
4947 PEER_DOWN_CAPABILITY_CHANGE;
4948 else if (flag
4949 == PEER_FLAG_ORF_PREFIX_RM)
4950 member->last_reset =
4951 PEER_DOWN_CAPABILITY_CHANGE;
4952
4953 peer_change_action(member, afi, safi,
4954 action.type);
4955 }
4956 }
4957 }
4958 }
4959
4960 return 0;
4961 }
4962
4963 int peer_af_flag_set(struct peer *peer, afi_t afi, safi_t safi, uint64_t flag)
4964 {
4965 return peer_af_flag_modify(peer, afi, safi, flag, 1);
4966 }
4967
4968 int peer_af_flag_unset(struct peer *peer, afi_t afi, safi_t safi, uint64_t flag)
4969 {
4970 return peer_af_flag_modify(peer, afi, safi, flag, 0);
4971 }
4972
4973
4974 void peer_tx_shutdown_message_set(struct peer *peer, const char *msg)
4975 {
4976 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4977 peer->tx_shutdown_message =
4978 msg ? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG, msg) : NULL;
4979 }
4980
4981 void peer_tx_shutdown_message_unset(struct peer *peer)
4982 {
4983 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4984 }
4985
4986
4987 /* EBGP multihop configuration. */
4988 int peer_ebgp_multihop_set(struct peer *peer, int ttl)
4989 {
4990 struct peer_group *group;
4991 struct listnode *node, *nnode;
4992 struct peer *peer1;
4993
4994 if (peer->sort == BGP_PEER_IBGP || peer->conf_if)
4995 return 0;
4996
4997 /* is there anything to do? */
4998 if (peer->ttl == ttl)
4999 return 0;
5000
5001 /* see comment in peer_ttl_security_hops_set() */
5002 if (ttl != MAXTTL) {
5003 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5004 group = peer->group;
5005 if (group->conf->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
5006 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5007
5008 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
5009 peer1)) {
5010 if (peer1->sort == BGP_PEER_IBGP)
5011 continue;
5012
5013 if (peer1->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
5014 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5015 }
5016 } else {
5017 if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
5018 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5019 }
5020 }
5021
5022 peer->ttl = ttl;
5023
5024 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5025 if (peer->sort != BGP_PEER_IBGP) {
5026 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5027 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5028 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5029 else
5030 bgp_session_reset(peer);
5031
5032 /* Reconfigure BFD peer with new TTL. */
5033 if (peer->bfd_config)
5034 bgp_peer_bfd_update_source(peer);
5035 }
5036 } else {
5037 group = peer->group;
5038 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5039 if (peer->sort == BGP_PEER_IBGP)
5040 continue;
5041
5042 peer->ttl = group->conf->ttl;
5043
5044 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5045 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5046 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5047 else
5048 bgp_session_reset(peer);
5049
5050 /* Reconfigure BFD peer with new TTL. */
5051 if (peer->bfd_config)
5052 bgp_peer_bfd_update_source(peer);
5053 }
5054 }
5055 return 0;
5056 }
5057
5058 int peer_ebgp_multihop_unset(struct peer *peer)
5059 {
5060 struct peer_group *group;
5061 struct listnode *node, *nnode;
5062 int ttl;
5063
5064 if (peer->sort == BGP_PEER_IBGP)
5065 return 0;
5066
5067 if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED && peer->ttl != MAXTTL)
5068 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
5069
5070 if (peer_group_active(peer))
5071 ttl = peer->group->conf->ttl;
5072 else
5073 ttl = BGP_DEFAULT_TTL;
5074
5075 if (ttl == peer->ttl)
5076 return 0;
5077
5078 peer->ttl = ttl;
5079
5080 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5081 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5082 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5083 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5084 else
5085 bgp_session_reset(peer);
5086
5087 /* Reconfigure BFD peer with new TTL. */
5088 if (peer->bfd_config)
5089 bgp_peer_bfd_update_source(peer);
5090 } else {
5091 group = peer->group;
5092 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5093 if (peer->sort == BGP_PEER_IBGP)
5094 continue;
5095
5096 peer->ttl = BGP_DEFAULT_TTL;
5097
5098 if (peer->fd >= 0) {
5099 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5100 bgp_notify_send(
5101 peer, BGP_NOTIFY_CEASE,
5102 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5103 else
5104 bgp_session_reset(peer);
5105 }
5106
5107 /* Reconfigure BFD peer with new TTL. */
5108 if (peer->bfd_config)
5109 bgp_peer_bfd_update_source(peer);
5110 }
5111 }
5112 return 0;
5113 }
5114
5115 /* Set Open Policy Role and check its correctness */
5116 int peer_role_set(struct peer *peer, uint8_t role, bool strict_mode)
5117 {
5118 struct peer *member;
5119 struct listnode *node, *nnode;
5120
5121 peer_flag_set(peer, PEER_FLAG_ROLE);
5122
5123 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5124 if (peer->sort != BGP_PEER_EBGP)
5125 return BGP_ERR_INVALID_INTERNAL_ROLE;
5126
5127 if (peer->local_role == role) {
5128 if (CHECK_FLAG(peer->flags,
5129 PEER_FLAG_ROLE_STRICT_MODE) &&
5130 !strict_mode)
5131 /* TODO: Is session restart needed if it was
5132 * down?
5133 */
5134 UNSET_FLAG(peer->flags,
5135 PEER_FLAG_ROLE_STRICT_MODE);
5136 if (!CHECK_FLAG(peer->flags,
5137 PEER_FLAG_ROLE_STRICT_MODE) &&
5138 strict_mode) {
5139 SET_FLAG(peer->flags,
5140 PEER_FLAG_ROLE_STRICT_MODE);
5141 /* Restart session to throw Role Mismatch
5142 * Notification
5143 */
5144 if (peer->remote_role == ROLE_UNDEFINED)
5145 bgp_session_reset(peer);
5146 }
5147 } else {
5148 peer->local_role = role;
5149 if (strict_mode)
5150 SET_FLAG(peer->flags,
5151 PEER_FLAG_ROLE_STRICT_MODE);
5152 else
5153 UNSET_FLAG(peer->flags,
5154 PEER_FLAG_ROLE_STRICT_MODE);
5155 bgp_session_reset(peer);
5156 }
5157
5158 return CMD_SUCCESS;
5159 }
5160
5161 peer->local_role = role;
5162 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5163 if (member->sort != BGP_PEER_EBGP)
5164 return BGP_ERR_INVALID_INTERNAL_ROLE;
5165
5166 if (member->local_role == role) {
5167 if (CHECK_FLAG(member->flags,
5168 PEER_FLAG_ROLE_STRICT_MODE) &&
5169 !strict_mode)
5170 /* TODO: Is session restart needed if it was
5171 * down?
5172 */
5173 UNSET_FLAG(member->flags,
5174 PEER_FLAG_ROLE_STRICT_MODE);
5175 if (!CHECK_FLAG(member->flags,
5176 PEER_FLAG_ROLE_STRICT_MODE) &&
5177 strict_mode) {
5178 SET_FLAG(peer->flags,
5179 PEER_FLAG_ROLE_STRICT_MODE);
5180 SET_FLAG(member->flags,
5181 PEER_FLAG_ROLE_STRICT_MODE);
5182 /* Restart session to throw Role Mismatch
5183 * Notification
5184 */
5185 if (member->remote_role == ROLE_UNDEFINED)
5186 bgp_session_reset(member);
5187 }
5188 } else {
5189 member->local_role = role;
5190
5191 if (strict_mode) {
5192 SET_FLAG(peer->flags,
5193 PEER_FLAG_ROLE_STRICT_MODE);
5194 SET_FLAG(member->flags,
5195 PEER_FLAG_ROLE_STRICT_MODE);
5196 } else {
5197 UNSET_FLAG(member->flags,
5198 PEER_FLAG_ROLE_STRICT_MODE);
5199 }
5200 bgp_session_reset(member);
5201 }
5202 }
5203
5204 return CMD_SUCCESS;
5205 }
5206
5207 int peer_role_unset(struct peer *peer)
5208 {
5209 struct peer *member;
5210 struct listnode *node, *nnode;
5211
5212 peer_flag_unset(peer, PEER_FLAG_ROLE);
5213
5214 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5215 return peer_role_set(peer, ROLE_UNDEFINED, 0);
5216
5217 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member))
5218 peer_role_set(member, ROLE_UNDEFINED, 0);
5219
5220 return CMD_SUCCESS;
5221 }
5222
5223 /* Neighbor description. */
5224 void peer_description_set(struct peer *peer, const char *desc)
5225 {
5226 XFREE(MTYPE_PEER_DESC, peer->desc);
5227
5228 peer->desc = XSTRDUP(MTYPE_PEER_DESC, desc);
5229 }
5230
5231 void peer_description_unset(struct peer *peer)
5232 {
5233 XFREE(MTYPE_PEER_DESC, peer->desc);
5234 }
5235
5236 /* Neighbor update-source. */
5237 int peer_update_source_if_set(struct peer *peer, const char *ifname)
5238 {
5239 struct peer *member;
5240 struct listnode *node, *nnode;
5241
5242 /* Set flag and configuration on peer. */
5243 peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
5244 if (peer->update_if) {
5245 if (strcmp(peer->update_if, ifname) == 0)
5246 return 0;
5247 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
5248 }
5249 peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
5250 sockunion_free(peer->update_source);
5251 peer->update_source = NULL;
5252
5253 /* Check if handling a regular peer. */
5254 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5255 /* Send notification or reset peer depending on state. */
5256 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5257 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5258 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5259 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5260 } else
5261 bgp_session_reset(peer);
5262
5263 /* Apply new source configuration to BFD session. */
5264 if (peer->bfd_config)
5265 bgp_peer_bfd_update_source(peer);
5266
5267 /* Skip peer-group mechanics for regular peers. */
5268 return 0;
5269 }
5270
5271 /*
5272 * Set flag and configuration on all peer-group members, unless they are
5273 * explicitly overriding peer-group configuration.
5274 */
5275 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5276 /* Skip peers with overridden configuration. */
5277 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
5278 continue;
5279
5280 /* Skip peers with the same configuration. */
5281 if (member->update_if) {
5282 if (strcmp(member->update_if, ifname) == 0)
5283 continue;
5284 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
5285 }
5286
5287 /* Set flag and configuration on peer-group member. */
5288 SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
5289 member->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
5290 sockunion_free(member->update_source);
5291 member->update_source = NULL;
5292
5293 /* Send notification or reset peer depending on state. */
5294 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5295 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5296 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5297 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5298 } else
5299 bgp_session_reset(member);
5300
5301 /* Apply new source configuration to BFD session. */
5302 if (member->bfd_config)
5303 bgp_peer_bfd_update_source(member);
5304 }
5305
5306 return 0;
5307 }
5308
5309 void peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
5310 {
5311 struct peer *member;
5312 struct listnode *node, *nnode;
5313
5314 /* Set flag and configuration on peer. */
5315 peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
5316 if (peer->update_source) {
5317 if (sockunion_cmp(peer->update_source, su) == 0)
5318 return;
5319 sockunion_free(peer->update_source);
5320 }
5321 peer->update_source = sockunion_dup(su);
5322 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
5323
5324 /* Check if handling a regular peer. */
5325 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5326 /* Send notification or reset peer depending on state. */
5327 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5328 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5329 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5330 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5331 } else
5332 bgp_session_reset(peer);
5333
5334 /* Apply new source configuration to BFD session. */
5335 if (peer->bfd_config)
5336 bgp_peer_bfd_update_source(peer);
5337
5338 /* Skip peer-group mechanics for regular peers. */
5339 return;
5340 }
5341
5342 /*
5343 * Set flag and configuration on all peer-group members, unless they are
5344 * explicitly overriding peer-group configuration.
5345 */
5346 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5347 /* Skip peers with overridden configuration. */
5348 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
5349 continue;
5350
5351 /* Skip peers with the same configuration. */
5352 if (member->update_source) {
5353 if (sockunion_cmp(member->update_source, su) == 0)
5354 continue;
5355 sockunion_free(member->update_source);
5356 }
5357
5358 /* Set flag and configuration on peer-group member. */
5359 SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
5360 member->update_source = sockunion_dup(su);
5361 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
5362
5363 /* Send notification or reset peer depending on state. */
5364 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5365 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5366 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5367 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5368 } else
5369 bgp_session_reset(member);
5370
5371 /* Apply new source configuration to BFD session. */
5372 if (member->bfd_config)
5373 bgp_peer_bfd_update_source(member);
5374 }
5375 }
5376
5377 void peer_update_source_unset(struct peer *peer)
5378 {
5379 struct peer *member;
5380 struct listnode *node, *nnode;
5381
5382 if (!CHECK_FLAG(peer->flags, PEER_FLAG_UPDATE_SOURCE))
5383 return;
5384
5385 /* Inherit configuration from peer-group if peer is member. */
5386 if (peer_group_active(peer)) {
5387 peer_flag_inherit(peer, PEER_FLAG_UPDATE_SOURCE);
5388 PEER_SU_ATTR_INHERIT(peer, peer->group, update_source);
5389 PEER_STR_ATTR_INHERIT(peer, peer->group, update_if,
5390 MTYPE_PEER_UPDATE_SOURCE);
5391 } else {
5392 /* Otherwise remove flag and configuration from peer. */
5393 peer_flag_unset(peer, PEER_FLAG_UPDATE_SOURCE);
5394 sockunion_free(peer->update_source);
5395 peer->update_source = NULL;
5396 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
5397 }
5398
5399 /* Check if handling a regular peer. */
5400 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5401 /* Send notification or reset peer depending on state. */
5402 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5403 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5404 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5405 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5406 } else
5407 bgp_session_reset(peer);
5408
5409 /* Apply new source configuration to BFD session. */
5410 if (peer->bfd_config)
5411 bgp_peer_bfd_update_source(peer);
5412
5413 /* Skip peer-group mechanics for regular peers. */
5414 return;
5415 }
5416
5417 /*
5418 * Set flag and configuration on all peer-group members, unless they are
5419 * explicitly overriding peer-group configuration.
5420 */
5421 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5422 /* Skip peers with overridden configuration. */
5423 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
5424 continue;
5425
5426 /* Skip peers with the same configuration. */
5427 if (!CHECK_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE)
5428 && !member->update_source && !member->update_if)
5429 continue;
5430
5431 /* Remove flag and configuration on peer-group member. */
5432 UNSET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
5433 sockunion_free(member->update_source);
5434 member->update_source = NULL;
5435 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
5436
5437 /* Send notification or reset peer depending on state. */
5438 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5439 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
5440 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5441 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5442 } else
5443 bgp_session_reset(member);
5444
5445 /* Apply new source configuration to BFD session. */
5446 if (member->bfd_config)
5447 bgp_peer_bfd_update_source(member);
5448 }
5449 }
5450
5451 int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
5452 const char *rmap, struct route_map *route_map)
5453 {
5454 struct peer *member;
5455 struct listnode *node, *nnode;
5456 struct update_subgroup *subgrp;
5457
5458 /* Set flag and configuration on peer. */
5459 peer_af_flag_set(peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE);
5460
5461 subgrp = peer_subgroup(peer, afi, safi);
5462
5463 if (rmap) {
5464 if (!peer->default_rmap[afi][safi].name
5465 || strcmp(rmap, peer->default_rmap[afi][safi].name) != 0) {
5466 if (peer->default_rmap[afi][safi].name)
5467 XFREE(MTYPE_ROUTE_MAP_NAME,
5468 peer->default_rmap[afi][safi].name);
5469
5470 /*
5471 * When there is a change in route-map policy,
5472 * this flow gets triggered. Since, the default
5473 * route is already originated, the flag is set.
5474 * The flag should be unset here,
5475 * to trigger the flow of sending update message.
5476 */
5477 if (subgrp)
5478 UNSET_FLAG(subgrp->sflags,
5479 SUBGRP_STATUS_DEFAULT_ORIGINATE);
5480
5481 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
5482 peer->default_rmap[afi][safi].name =
5483 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5484 peer->default_rmap[afi][safi].map = route_map;
5485 route_map_counter_increment(route_map);
5486 }
5487 } else if (!rmap) {
5488 if (peer->default_rmap[afi][safi].name)
5489 XFREE(MTYPE_ROUTE_MAP_NAME,
5490 peer->default_rmap[afi][safi].name);
5491
5492 /*
5493 * This is triggered in case of route-map deletion.
5494 * The flag needs to be unset, to trigger the flow
5495 * of sending an update message.
5496 */
5497 if (subgrp)
5498 UNSET_FLAG(subgrp->sflags,
5499 SUBGRP_STATUS_DEFAULT_ORIGINATE);
5500
5501 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
5502 peer->default_rmap[afi][safi].name = NULL;
5503 peer->default_rmap[afi][safi].map = NULL;
5504 }
5505
5506 /* Check if handling a regular peer. */
5507 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5508 /* Update peer route announcements. */
5509 if (peer_established(peer) && peer->afc_nego[afi][safi]) {
5510 update_group_adjust_peer(peer_af_find(peer, afi, safi));
5511 bgp_default_originate(peer, afi, safi, 0);
5512 bgp_announce_route(peer, afi, safi, false);
5513 }
5514
5515 /* Skip peer-group mechanics for regular peers. */
5516 return 0;
5517 }
5518
5519 /*
5520 * Set flag and configuration on all peer-group members, unless they are
5521 * explicitly overriding peer-group configuration.
5522 */
5523 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5524 /* Skip peers with overridden configuration. */
5525 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5526 PEER_FLAG_DEFAULT_ORIGINATE))
5527 continue;
5528
5529 /* Set flag and configuration on peer-group member. */
5530 SET_FLAG(member->af_flags[afi][safi],
5531 PEER_FLAG_DEFAULT_ORIGINATE);
5532 if (rmap) {
5533 if (member->default_rmap[afi][safi].name)
5534 XFREE(MTYPE_ROUTE_MAP_NAME,
5535 member->default_rmap[afi][safi].name);
5536 route_map_counter_decrement(
5537 member->default_rmap[afi][safi].map);
5538 member->default_rmap[afi][safi].name =
5539 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5540 member->default_rmap[afi][safi].map = route_map;
5541 route_map_counter_increment(route_map);
5542 }
5543
5544 /* Update peer route announcements. */
5545 if (peer_established(member) && member->afc_nego[afi][safi]) {
5546 update_group_adjust_peer(
5547 peer_af_find(member, afi, safi));
5548 bgp_default_originate(member, afi, safi, 0);
5549 bgp_announce_route(member, afi, safi, false);
5550 }
5551 }
5552
5553 return 0;
5554 }
5555
5556 int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi)
5557 {
5558 struct peer *member;
5559 struct listnode *node, *nnode;
5560
5561 /* Inherit configuration from peer-group if peer is member. */
5562 if (peer_group_active(peer)) {
5563 peer_af_flag_inherit(peer, afi, safi,
5564 PEER_FLAG_DEFAULT_ORIGINATE);
5565 PEER_STR_ATTR_INHERIT(peer, peer->group,
5566 default_rmap[afi][safi].name,
5567 MTYPE_ROUTE_MAP_NAME);
5568 PEER_ATTR_INHERIT(peer, peer->group,
5569 default_rmap[afi][safi].map);
5570 } else {
5571 /* Otherwise remove flag and configuration from peer. */
5572 peer_af_flag_unset(peer, afi, safi,
5573 PEER_FLAG_DEFAULT_ORIGINATE);
5574 if (peer->default_rmap[afi][safi].name)
5575 XFREE(MTYPE_ROUTE_MAP_NAME,
5576 peer->default_rmap[afi][safi].name);
5577 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
5578 peer->default_rmap[afi][safi].name = NULL;
5579 peer->default_rmap[afi][safi].map = NULL;
5580 }
5581
5582 /* Check if handling a regular peer. */
5583 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5584 /* Update peer route announcements. */
5585 if (peer_established(peer) && peer->afc_nego[afi][safi]) {
5586 update_group_adjust_peer(peer_af_find(peer, afi, safi));
5587 bgp_default_originate(peer, afi, safi, 1);
5588 bgp_announce_route(peer, afi, safi, false);
5589 }
5590
5591 /* Skip peer-group mechanics for regular peers. */
5592 return 0;
5593 }
5594
5595 /*
5596 * Remove flag and configuration from all peer-group members, unless
5597 * they are explicitly overriding peer-group configuration.
5598 */
5599 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5600 /* Skip peers with overridden configuration. */
5601 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5602 PEER_FLAG_DEFAULT_ORIGINATE))
5603 continue;
5604
5605 /* Remove flag and configuration on peer-group member. */
5606 UNSET_FLAG(member->af_flags[afi][safi],
5607 PEER_FLAG_DEFAULT_ORIGINATE);
5608 if (member->default_rmap[afi][safi].name)
5609 XFREE(MTYPE_ROUTE_MAP_NAME,
5610 member->default_rmap[afi][safi].name);
5611 route_map_counter_decrement(member->default_rmap[afi][safi].map);
5612 member->default_rmap[afi][safi].name = NULL;
5613 member->default_rmap[afi][safi].map = NULL;
5614
5615 /* Update peer route announcements. */
5616 if (peer_established(member) && member->afc_nego[afi][safi]) {
5617 update_group_adjust_peer(peer_af_find(member, afi, safi));
5618 bgp_default_originate(member, afi, safi, 1);
5619 bgp_announce_route(member, afi, safi, false);
5620 }
5621 }
5622
5623 return 0;
5624 }
5625
5626 void peer_port_set(struct peer *peer, uint16_t port)
5627 {
5628 peer->port = port;
5629 peer_flag_set(peer, PEER_FLAG_PORT);
5630 }
5631
5632 void peer_port_unset(struct peer *peer)
5633 {
5634 peer->port = BGP_PORT_DEFAULT;
5635 peer_flag_unset(peer, PEER_FLAG_PORT);
5636 }
5637
5638 /* Set the TCP-MSS value in the peer structure,
5639 * This gets applied only after connection reset
5640 * So this value will be used in bgp_connect.
5641 */
5642 void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss)
5643 {
5644 peer->tcp_mss = tcp_mss;
5645 SET_FLAG(peer->flags, PEER_FLAG_TCP_MSS);
5646 }
5647
5648 /* Reset the TCP-MSS value in the peer structure,
5649 * This gets applied only after connection reset
5650 * So this value will be used in bgp_connect.
5651 */
5652 void peer_tcp_mss_unset(struct peer *peer)
5653 {
5654 UNSET_FLAG(peer->flags, PEER_FLAG_TCP_MSS);
5655 peer->tcp_mss = 0;
5656 }
5657
5658 /*
5659 * Helper function that is called after the name of the policy
5660 * being used by a peer has changed (AF specific). Automatically
5661 * initiates inbound or outbound processing as needed.
5662 */
5663 void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
5664 int outbound)
5665 {
5666 if (outbound) {
5667 update_group_adjust_peer(peer_af_find(peer, afi, safi));
5668 if (peer_established(peer))
5669 bgp_announce_route(peer, afi, safi, false);
5670 } else {
5671 if (!peer_established(peer))
5672 return;
5673
5674 if (bgp_soft_reconfig_in(peer, afi, safi))
5675 return;
5676
5677 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) ||
5678 CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV)) {
5679 if (CHECK_FLAG(peer->af_cap[afi][safi],
5680 PEER_CAP_ORF_PREFIX_SM_ADV) &&
5681 (CHECK_FLAG(peer->af_cap[afi][safi],
5682 PEER_CAP_ORF_PREFIX_RM_RCV) ||
5683 CHECK_FLAG(peer->af_cap[afi][safi],
5684 PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
5685 peer_clear_soft(peer, afi, safi,
5686 BGP_CLEAR_SOFT_IN_ORF_PREFIX);
5687 else
5688 bgp_route_refresh_send(
5689 peer, afi, safi, 0, 0, 0,
5690 BGP_ROUTE_REFRESH_NORMAL);
5691 }
5692 }
5693 }
5694
5695
5696 /* neighbor weight. */
5697 int peer_weight_set(struct peer *peer, afi_t afi, safi_t safi, uint16_t weight)
5698 {
5699 struct peer *member;
5700 struct listnode *node, *nnode;
5701
5702 /* Set flag and configuration on peer. */
5703 peer_af_flag_set(peer, afi, safi, PEER_FLAG_WEIGHT);
5704 if (peer->weight[afi][safi] != weight) {
5705 peer->weight[afi][safi] = weight;
5706 peer_on_policy_change(peer, afi, safi, 0);
5707 }
5708
5709 /* Skip peer-group mechanics for regular peers. */
5710 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5711 return 0;
5712
5713 /*
5714 * Set flag and configuration on all peer-group members, unless they are
5715 * explicitly overriding peer-group configuration.
5716 */
5717 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5718 /* Skip peers with overridden configuration. */
5719 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5720 PEER_FLAG_WEIGHT))
5721 continue;
5722
5723 /* Set flag and configuration on peer-group member. */
5724 SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
5725 if (member->weight[afi][safi] != weight) {
5726 member->weight[afi][safi] = weight;
5727 peer_on_policy_change(member, afi, safi, 0);
5728 }
5729 }
5730
5731 return 0;
5732 }
5733
5734 int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi)
5735 {
5736 struct peer *member;
5737 struct listnode *node, *nnode;
5738
5739 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
5740 return 0;
5741
5742 /* Inherit configuration from peer-group if peer is member. */
5743 if (peer_group_active(peer)) {
5744 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_WEIGHT);
5745 PEER_ATTR_INHERIT(peer, peer->group, weight[afi][safi]);
5746
5747 peer_on_policy_change(peer, afi, safi, 0);
5748 return 0;
5749 }
5750
5751 /* Remove flag and configuration from peer. */
5752 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_WEIGHT);
5753 peer->weight[afi][safi] = 0;
5754 peer_on_policy_change(peer, afi, safi, 0);
5755
5756 /* Skip peer-group mechanics for regular peers. */
5757 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5758 return 0;
5759
5760 /*
5761 * Remove flag and configuration from all peer-group members, unless
5762 * they are explicitly overriding peer-group configuration.
5763 */
5764 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5765 /* Skip peers with overridden configuration. */
5766 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5767 PEER_FLAG_WEIGHT))
5768 continue;
5769
5770 /* Skip peers where flag is already disabled. */
5771 if (!CHECK_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT))
5772 continue;
5773
5774 /* Remove flag and configuration on peer-group member. */
5775 UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
5776 member->weight[afi][safi] = 0;
5777 peer_on_policy_change(member, afi, safi, 0);
5778 }
5779
5780 return 0;
5781 }
5782
5783 int peer_timers_set(struct peer *peer, uint32_t keepalive, uint32_t holdtime)
5784 {
5785 struct peer *member;
5786 struct listnode *node, *nnode;
5787
5788 if (keepalive > UINT16_MAX)
5789 return BGP_ERR_INVALID_VALUE;
5790
5791 if (holdtime > UINT16_MAX)
5792 return BGP_ERR_INVALID_VALUE;
5793
5794 if (holdtime < 3 && holdtime != 0)
5795 return BGP_ERR_INVALID_VALUE;
5796
5797 /* Set flag and configuration on peer. */
5798 peer_flag_set(peer, PEER_FLAG_TIMER);
5799 peer->holdtime = holdtime;
5800 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
5801
5802 /* Skip peer-group mechanics for regular peers. */
5803 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5804 return 0;
5805
5806 /*
5807 * Set flag and configuration on all peer-group members, unless they are
5808 * explicitly overriding peer-group configuration.
5809 */
5810 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5811 /* Skip peers with overridden configuration. */
5812 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
5813 continue;
5814
5815 /* Set flag and configuration on peer-group member. */
5816 SET_FLAG(member->flags, PEER_FLAG_TIMER);
5817 PEER_ATTR_INHERIT(member, peer->group, holdtime);
5818 PEER_ATTR_INHERIT(member, peer->group, keepalive);
5819 }
5820
5821 return 0;
5822 }
5823
5824 int peer_timers_unset(struct peer *peer)
5825 {
5826 struct peer *member;
5827 struct listnode *node, *nnode;
5828
5829 /* Inherit configuration from peer-group if peer is member. */
5830 if (peer_group_active(peer)) {
5831 peer_flag_inherit(peer, PEER_FLAG_TIMER);
5832 PEER_ATTR_INHERIT(peer, peer->group, holdtime);
5833 PEER_ATTR_INHERIT(peer, peer->group, keepalive);
5834 } else {
5835 /* Otherwise remove flag and configuration from peer. */
5836 peer_flag_unset(peer, PEER_FLAG_TIMER);
5837 peer->holdtime = 0;
5838 peer->keepalive = 0;
5839 }
5840
5841 /* Skip peer-group mechanics for regular peers. */
5842 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5843 return 0;
5844
5845 /*
5846 * Remove flag and configuration from all peer-group members, unless
5847 * they are explicitly overriding peer-group configuration.
5848 */
5849 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5850 /* Skip peers with overridden configuration. */
5851 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
5852 continue;
5853
5854 /* Remove flag and configuration on peer-group member. */
5855 UNSET_FLAG(member->flags, PEER_FLAG_TIMER);
5856 member->holdtime = 0;
5857 member->keepalive = 0;
5858 }
5859
5860 return 0;
5861 }
5862
5863 int peer_timers_connect_set(struct peer *peer, uint32_t connect)
5864 {
5865 struct peer *member;
5866 struct listnode *node, *nnode;
5867
5868 if (connect > UINT16_MAX)
5869 return BGP_ERR_INVALID_VALUE;
5870
5871 /* Set flag and configuration on peer. */
5872 peer_flag_set(peer, PEER_FLAG_TIMER_CONNECT);
5873 peer->connect = connect;
5874 peer->v_connect = connect;
5875
5876 /* Skip peer-group mechanics for regular peers. */
5877 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5878 if (!peer_established(peer)) {
5879 if (peer_active(peer))
5880 BGP_EVENT_ADD(peer, BGP_Stop);
5881 BGP_EVENT_ADD(peer, BGP_Start);
5882 }
5883 return 0;
5884 }
5885 /*
5886 * Set flag and configuration on all peer-group members, unless they are
5887 * explicitly overriding peer-group configuration.
5888 */
5889 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5890 /* Skip peers with overridden configuration. */
5891 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5892 continue;
5893
5894 /* Set flag and configuration on peer-group member. */
5895 SET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5896 member->connect = connect;
5897 member->v_connect = connect;
5898
5899 if (!peer_established(member)) {
5900 if (peer_active(member))
5901 BGP_EVENT_ADD(member, BGP_Stop);
5902 BGP_EVENT_ADD(member, BGP_Start);
5903 }
5904 }
5905
5906 return 0;
5907 }
5908
5909 int peer_timers_connect_unset(struct peer *peer)
5910 {
5911 struct peer *member;
5912 struct listnode *node, *nnode;
5913
5914 /* Inherit configuration from peer-group if peer is member. */
5915 if (peer_group_active(peer)) {
5916 peer_flag_inherit(peer, PEER_FLAG_TIMER_CONNECT);
5917 PEER_ATTR_INHERIT(peer, peer->group, connect);
5918 } else {
5919 /* Otherwise remove flag and configuration from peer. */
5920 peer_flag_unset(peer, PEER_FLAG_TIMER_CONNECT);
5921 peer->connect = 0;
5922 }
5923
5924 /* Set timer with fallback to default value. */
5925 if (peer->connect)
5926 peer->v_connect = peer->connect;
5927 else
5928 peer->v_connect = peer->bgp->default_connect_retry;
5929
5930 /* Skip peer-group mechanics for regular peers. */
5931 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5932 if (!peer_established(peer)) {
5933 if (peer_active(peer))
5934 BGP_EVENT_ADD(peer, BGP_Stop);
5935 BGP_EVENT_ADD(peer, BGP_Start);
5936 }
5937 return 0;
5938 }
5939 /*
5940 * Remove flag and configuration from all peer-group members, unless
5941 * they are explicitly overriding peer-group configuration.
5942 */
5943 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5944 /* Skip peers with overridden configuration. */
5945 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5946 continue;
5947
5948 /* Remove flag and configuration on peer-group member. */
5949 UNSET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5950 member->connect = 0;
5951 member->v_connect = peer->bgp->default_connect_retry;
5952
5953 if (!peer_established(member)) {
5954 if (peer_active(member))
5955 BGP_EVENT_ADD(member, BGP_Stop);
5956 BGP_EVENT_ADD(member, BGP_Start);
5957 }
5958 }
5959
5960 return 0;
5961 }
5962
5963 int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv)
5964 {
5965 struct peer *member;
5966 struct listnode *node, *nnode;
5967
5968 if (routeadv > 600)
5969 return BGP_ERR_INVALID_VALUE;
5970
5971 /* Set flag and configuration on peer. */
5972 peer_flag_set(peer, PEER_FLAG_ROUTEADV);
5973 peer->routeadv = routeadv;
5974 peer->v_routeadv = routeadv;
5975
5976 /* Check if handling a regular peer. */
5977 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5978 /* Update peer route announcements. */
5979 update_group_adjust_peer_afs(peer);
5980 if (peer_established(peer))
5981 bgp_announce_route_all(peer);
5982
5983 /* Skip peer-group mechanics for regular peers. */
5984 return 0;
5985 }
5986
5987 /*
5988 * Set flag and configuration on all peer-group members, unless they are
5989 * explicitly overriding peer-group configuration.
5990 */
5991 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5992 /* Skip peers with overridden configuration. */
5993 if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
5994 continue;
5995
5996 /* Set flag and configuration on peer-group member. */
5997 SET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
5998 member->routeadv = routeadv;
5999 member->v_routeadv = routeadv;
6000
6001 /* Update peer route announcements. */
6002 update_group_adjust_peer_afs(member);
6003 if (peer_established(member))
6004 bgp_announce_route_all(member);
6005 }
6006
6007 return 0;
6008 }
6009
6010 int peer_advertise_interval_unset(struct peer *peer)
6011 {
6012 struct peer *member;
6013 struct listnode *node, *nnode;
6014
6015 /* Inherit configuration from peer-group if peer is member. */
6016 if (peer_group_active(peer)) {
6017 peer_flag_inherit(peer, PEER_FLAG_ROUTEADV);
6018 PEER_ATTR_INHERIT(peer, peer->group, routeadv);
6019 } else {
6020 /* Otherwise remove flag and configuration from peer. */
6021 peer_flag_unset(peer, PEER_FLAG_ROUTEADV);
6022 peer->routeadv = 0;
6023 }
6024
6025 /* Set timer with fallback to default value. */
6026 if (peer->routeadv)
6027 peer->v_routeadv = peer->routeadv;
6028 else
6029 peer->v_routeadv = (peer->sort == BGP_PEER_IBGP)
6030 ? BGP_DEFAULT_IBGP_ROUTEADV
6031 : BGP_DEFAULT_EBGP_ROUTEADV;
6032
6033 /* Check if handling a regular peer. */
6034 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6035 /* Update peer route announcements. */
6036 update_group_adjust_peer_afs(peer);
6037 if (peer_established(peer))
6038 bgp_announce_route_all(peer);
6039
6040 /* Skip peer-group mechanics for regular peers. */
6041 return 0;
6042 }
6043
6044 /*
6045 * Remove flag and configuration from all peer-group members, unless
6046 * they are explicitly overriding peer-group configuration.
6047 */
6048 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6049 /* Skip peers with overridden configuration. */
6050 if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
6051 continue;
6052
6053 /* Remove flag and configuration on peer-group member. */
6054 UNSET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
6055 member->routeadv = 0;
6056 member->v_routeadv = (member->sort == BGP_PEER_IBGP)
6057 ? BGP_DEFAULT_IBGP_ROUTEADV
6058 : BGP_DEFAULT_EBGP_ROUTEADV;
6059
6060 /* Update peer route announcements. */
6061 update_group_adjust_peer_afs(member);
6062 if (peer_established(member))
6063 bgp_announce_route_all(member);
6064 }
6065
6066 return 0;
6067 }
6068
6069 /* set the peers RFC 4271 DelayOpen session attribute flag and DelayOpenTimer
6070 * interval
6071 */
6072 int peer_timers_delayopen_set(struct peer *peer, uint32_t delayopen)
6073 {
6074 struct peer *member;
6075 struct listnode *node;
6076
6077 /* Set peers session attribute flag and timer interval. */
6078 peer_flag_set(peer, PEER_FLAG_TIMER_DELAYOPEN);
6079 peer->delayopen = delayopen;
6080 peer->v_delayopen = delayopen;
6081
6082 /* Skip group mechanics for regular peers. */
6083 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6084 return 0;
6085
6086 /* Set flag and configuration on all peer-group members, unless they are
6087 * explicitly overriding peer-group configuration.
6088 */
6089 for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
6090 /* Skip peers with overridden configuration. */
6091 if (CHECK_FLAG(member->flags_override,
6092 PEER_FLAG_TIMER_DELAYOPEN))
6093 continue;
6094
6095 /* Set session attribute flag and timer intervals on peer-group
6096 * member.
6097 */
6098 SET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN);
6099 member->delayopen = delayopen;
6100 member->v_delayopen = delayopen;
6101 }
6102
6103 return 0;
6104 }
6105
6106 /* unset the peers RFC 4271 DelayOpen session attribute flag and reset the
6107 * DelayOpenTimer interval to the default value.
6108 */
6109 int peer_timers_delayopen_unset(struct peer *peer)
6110 {
6111 struct peer *member;
6112 struct listnode *node;
6113
6114 /* Inherit configuration from peer-group if peer is member. */
6115 if (peer_group_active(peer)) {
6116 peer_flag_inherit(peer, PEER_FLAG_TIMER_DELAYOPEN);
6117 PEER_ATTR_INHERIT(peer, peer->group, delayopen);
6118 } else {
6119 /* Otherwise remove session attribute flag and set timer
6120 * interval to default value.
6121 */
6122 peer_flag_unset(peer, PEER_FLAG_TIMER_DELAYOPEN);
6123 peer->delayopen = peer->bgp->default_delayopen;
6124 }
6125
6126 /* Set timer value to zero */
6127 peer->v_delayopen = 0;
6128
6129 /* Skip peer-group mechanics for regular peers. */
6130 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6131 return 0;
6132
6133 /* Remove flag and configuration from all peer-group members, unless
6134 * they are explicitly overriding peer-group configuration.
6135 */
6136 for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
6137 /* Skip peers with overridden configuration. */
6138 if (CHECK_FLAG(member->flags_override,
6139 PEER_FLAG_TIMER_DELAYOPEN))
6140 continue;
6141
6142 /* Remove session attribute flag, reset the timer interval to
6143 * the default value and set the timer value to zero.
6144 */
6145 UNSET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN);
6146 member->delayopen = peer->bgp->default_delayopen;
6147 member->v_delayopen = 0;
6148 }
6149
6150 return 0;
6151 }
6152
6153 /* neighbor interface */
6154 void peer_interface_set(struct peer *peer, const char *str)
6155 {
6156 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
6157 peer->ifname = XSTRDUP(MTYPE_BGP_PEER_IFNAME, str);
6158 }
6159
6160 void peer_interface_unset(struct peer *peer)
6161 {
6162 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
6163 }
6164
6165 /* Allow-as in. */
6166 int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
6167 int allow_num, int origin)
6168 {
6169 struct peer *member;
6170 struct listnode *node, *nnode;
6171
6172 if (!origin && (allow_num < 1 || allow_num > 10))
6173 return BGP_ERR_INVALID_VALUE;
6174
6175 /* Set flag and configuration on peer. */
6176 peer_af_flag_set(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
6177 if (origin) {
6178 if (peer->allowas_in[afi][safi] != 0
6179 || !CHECK_FLAG(peer->af_flags[afi][safi],
6180 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6181 peer_af_flag_set(peer, afi, safi,
6182 PEER_FLAG_ALLOWAS_IN_ORIGIN);
6183 peer->allowas_in[afi][safi] = 0;
6184 peer_on_policy_change(peer, afi, safi, 0);
6185 }
6186 } else {
6187 if (peer->allowas_in[afi][safi] != allow_num
6188 || CHECK_FLAG(peer->af_flags[afi][safi],
6189 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6190
6191 peer_af_flag_unset(peer, afi, safi,
6192 PEER_FLAG_ALLOWAS_IN_ORIGIN);
6193 peer->allowas_in[afi][safi] = allow_num;
6194 peer_on_policy_change(peer, afi, safi, 0);
6195 }
6196 }
6197
6198 /* Skip peer-group mechanics for regular peers. */
6199 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6200 return 0;
6201
6202 /*
6203 * Set flag and configuration on all peer-group members, unless
6204 * they are explicitly overriding peer-group configuration.
6205 */
6206 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6207 /* Skip peers with overridden configuration. */
6208 if (CHECK_FLAG(member->af_flags_override[afi][safi],
6209 PEER_FLAG_ALLOWAS_IN))
6210 continue;
6211
6212 /* Set flag and configuration on peer-group member. */
6213 SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
6214 if (origin) {
6215 if (member->allowas_in[afi][safi] != 0
6216 || !CHECK_FLAG(member->af_flags[afi][safi],
6217 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6218 SET_FLAG(member->af_flags[afi][safi],
6219 PEER_FLAG_ALLOWAS_IN_ORIGIN);
6220 member->allowas_in[afi][safi] = 0;
6221 peer_on_policy_change(peer, afi, safi, 0);
6222 }
6223 } else {
6224 if (member->allowas_in[afi][safi] != allow_num
6225 || CHECK_FLAG(member->af_flags[afi][safi],
6226 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
6227 UNSET_FLAG(member->af_flags[afi][safi],
6228 PEER_FLAG_ALLOWAS_IN_ORIGIN);
6229 member->allowas_in[afi][safi] = allow_num;
6230 peer_on_policy_change(peer, afi, safi, 0);
6231 }
6232 }
6233 }
6234
6235 return 0;
6236 }
6237
6238 int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
6239 {
6240 struct peer *member;
6241 struct listnode *node, *nnode;
6242
6243 /* Skip peer if flag is already disabled. */
6244 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
6245 return 0;
6246
6247 /* Inherit configuration from peer-group if peer is member. */
6248 if (peer_group_active(peer)) {
6249 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
6250 peer_af_flag_inherit(peer, afi, safi,
6251 PEER_FLAG_ALLOWAS_IN_ORIGIN);
6252 PEER_ATTR_INHERIT(peer, peer->group, allowas_in[afi][safi]);
6253 peer_on_policy_change(peer, afi, safi, 0);
6254
6255 return 0;
6256 }
6257
6258 /* Remove flag and configuration from peer. */
6259 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
6260 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN);
6261 peer->allowas_in[afi][safi] = 0;
6262 peer_on_policy_change(peer, afi, safi, 0);
6263
6264 /* Skip peer-group mechanics if handling a regular peer. */
6265 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6266 return 0;
6267
6268 /*
6269 * Remove flags and configuration from all peer-group members, unless
6270 * they are explicitly overriding peer-group configuration.
6271 */
6272 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6273 /* Skip peers with overridden configuration. */
6274 if (CHECK_FLAG(member->af_flags_override[afi][safi],
6275 PEER_FLAG_ALLOWAS_IN))
6276 continue;
6277
6278 /* Remove flags and configuration on peer-group member. */
6279 UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
6280 UNSET_FLAG(member->af_flags[afi][safi],
6281 PEER_FLAG_ALLOWAS_IN_ORIGIN);
6282 member->allowas_in[afi][safi] = 0;
6283 peer_on_policy_change(member, afi, safi, 0);
6284 }
6285
6286 return 0;
6287 }
6288
6289 int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
6290 bool replace_as, const char *as_str)
6291 {
6292 bool old_no_prepend, old_replace_as;
6293 struct bgp *bgp = peer->bgp;
6294 struct peer *member;
6295 struct listnode *node, *nnode;
6296
6297 if (bgp->as == as)
6298 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
6299
6300 /* Save previous flag states. */
6301 old_no_prepend =
6302 !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6303 old_replace_as =
6304 !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6305
6306 /* Set flag and configuration on peer. */
6307 peer_flag_set(peer, PEER_FLAG_LOCAL_AS);
6308 peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND, no_prepend);
6309 peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as);
6310
6311 if (peer->change_local_as == as && old_no_prepend == no_prepend
6312 && old_replace_as == replace_as)
6313 return 0;
6314 peer->change_local_as = as;
6315 if (as_str)
6316 peer->change_local_as_pretty = XSTRDUP(MTYPE_BGP, as_str);
6317
6318 (void)peer_sort(peer);
6319
6320 /* Check if handling a regular peer. */
6321 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
6322 return 0;
6323
6324 /*
6325 * Set flag and configuration on all peer-group members, unless they are
6326 * explicitly overriding peer-group configuration.
6327 */
6328 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6329 /* Skip peers with overridden configuration. */
6330 if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
6331 continue;
6332
6333 /* Skip peers with the same configuration. */
6334 old_no_prepend = CHECK_FLAG(member->flags,
6335 PEER_FLAG_LOCAL_AS_NO_PREPEND);
6336 old_replace_as = CHECK_FLAG(member->flags,
6337 PEER_FLAG_LOCAL_AS_REPLACE_AS);
6338 if (member->change_local_as == as
6339 && CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS)
6340 && old_no_prepend == no_prepend
6341 && old_replace_as == replace_as)
6342 continue;
6343
6344 /* Set flag and configuration on peer-group member. */
6345 SET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
6346 COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND,
6347 no_prepend);
6348 COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
6349 replace_as);
6350 member->change_local_as = as;
6351 if (as_str)
6352 member->change_local_as_pretty =
6353 XSTRDUP(MTYPE_BGP, as_str);
6354 }
6355
6356 return 0;
6357 }
6358
6359 int peer_local_as_unset(struct peer *peer)
6360 {
6361 struct peer *member;
6362 struct listnode *node, *nnode;
6363
6364 if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS))
6365 return 0;
6366
6367 /* Inherit configuration from peer-group if peer is member. */
6368 if (peer_group_active(peer)) {
6369 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS);
6370 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6371 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6372 PEER_ATTR_INHERIT(peer, peer->group, change_local_as);
6373 } else {
6374 /* Otherwise remove flag and configuration from peer. */
6375 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS);
6376 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6377 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6378 peer->change_local_as = 0;
6379 XFREE(MTYPE_BGP, peer->change_local_as_pretty);
6380 }
6381
6382 /* Check if handling a regular peer. */
6383 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6384 /* Send notification or stop peer depending on state. */
6385 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
6386 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
6387 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6388 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6389 } else
6390 BGP_EVENT_ADD(peer, BGP_Stop);
6391
6392 /* Skip peer-group mechanics for regular peers. */
6393 return 0;
6394 }
6395
6396 /*
6397 * Remove flag and configuration from all peer-group members, unless
6398 * they are explicitly overriding peer-group configuration.
6399 */
6400 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6401 /* Skip peers with overridden configuration. */
6402 if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
6403 continue;
6404
6405 /* Remove flag and configuration on peer-group member. */
6406 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
6407 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
6408 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
6409 member->change_local_as = 0;
6410 XFREE(MTYPE_BGP, member->change_local_as_pretty);
6411
6412 /* Send notification or stop peer depending on state. */
6413 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
6414 member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
6415 bgp_notify_send(member, BGP_NOTIFY_CEASE,
6416 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6417 } else
6418 bgp_session_reset(member);
6419 }
6420
6421 return 0;
6422 }
6423
6424 /* Set password for authenticating with the peer. */
6425 int peer_password_set(struct peer *peer, const char *password)
6426 {
6427 struct peer *member;
6428 struct listnode *node, *nnode;
6429 int len = password ? strlen(password) : 0;
6430 int ret = BGP_SUCCESS;
6431
6432 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
6433 return BGP_ERR_INVALID_VALUE;
6434
6435 /* Set flag and configuration on peer. */
6436 peer_flag_set(peer, PEER_FLAG_PASSWORD);
6437 if (peer->password && strcmp(peer->password, password) == 0)
6438 return 0;
6439 XFREE(MTYPE_PEER_PASSWORD, peer->password);
6440 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
6441
6442 /* Check if handling a regular peer. */
6443 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6444 /* Send notification or reset peer depending on state. */
6445 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6446 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6447 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6448 else
6449 bgp_session_reset(peer);
6450
6451 /*
6452 * Attempt to install password on socket and skip peer-group
6453 * mechanics.
6454 */
6455 if (BGP_PEER_SU_UNSPEC(peer))
6456 return BGP_SUCCESS;
6457 return (bgp_md5_set(peer) >= 0) ? BGP_SUCCESS
6458 : BGP_ERR_TCPSIG_FAILED;
6459 }
6460
6461 /*
6462 * Set flag and configuration on all peer-group members, unless they are
6463 * explicitly overriding peer-group configuration.
6464 */
6465 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6466 /* Skip peers with overridden configuration. */
6467 if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
6468 continue;
6469
6470 /* Skip peers with the same password. */
6471 if (member->password && strcmp(member->password, password) == 0)
6472 continue;
6473
6474 /* Set flag and configuration on peer-group member. */
6475 SET_FLAG(member->flags, PEER_FLAG_PASSWORD);
6476 if (member->password)
6477 XFREE(MTYPE_PEER_PASSWORD, member->password);
6478 member->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
6479
6480 /* Send notification or reset peer depending on state. */
6481 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
6482 bgp_notify_send(member, BGP_NOTIFY_CEASE,
6483 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6484 else
6485 bgp_session_reset(member);
6486
6487 /* Attempt to install password on socket. */
6488 if (!BGP_PEER_SU_UNSPEC(member) && bgp_md5_set(member) < 0)
6489 ret = BGP_ERR_TCPSIG_FAILED;
6490 }
6491
6492 /* Set flag and configuration on all peer-group listen ranges */
6493 struct listnode *ln;
6494 struct prefix *lr;
6495
6496 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
6497 bgp_md5_set_prefix(peer->bgp, lr, password);
6498 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
6499 bgp_md5_set_prefix(peer->bgp, lr, password);
6500
6501 return ret;
6502 }
6503
6504 int peer_password_unset(struct peer *peer)
6505 {
6506 struct peer *member;
6507 struct listnode *node, *nnode;
6508
6509 if (!CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD))
6510 return 0;
6511
6512 /* Inherit configuration from peer-group if peer is member. */
6513 if (peer_group_active(peer)) {
6514 peer_flag_inherit(peer, PEER_FLAG_PASSWORD);
6515 PEER_STR_ATTR_INHERIT(peer, peer->group, password,
6516 MTYPE_PEER_PASSWORD);
6517 } else {
6518 /* Otherwise remove flag and configuration from peer. */
6519 peer_flag_unset(peer, PEER_FLAG_PASSWORD);
6520 XFREE(MTYPE_PEER_PASSWORD, peer->password);
6521 }
6522
6523 /* Check if handling a regular peer. */
6524 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6525 /* Send notification or reset peer depending on state. */
6526 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6527 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6528 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6529 else
6530 bgp_session_reset(peer);
6531
6532 /* Attempt to uninstall password on socket. */
6533 if (!BGP_PEER_SU_UNSPEC(peer))
6534 bgp_md5_unset(peer);
6535 /* Skip peer-group mechanics for regular peers. */
6536 return 0;
6537 }
6538
6539 /*
6540 * Remove flag and configuration from all peer-group members, unless
6541 * they are explicitly overriding peer-group configuration.
6542 */
6543 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6544 /* Skip peers with overridden configuration. */
6545 if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
6546 continue;
6547
6548 /* Remove flag and configuration on peer-group member. */
6549 UNSET_FLAG(member->flags, PEER_FLAG_PASSWORD);
6550 XFREE(MTYPE_PEER_PASSWORD, member->password);
6551
6552 /* Send notification or reset peer depending on state. */
6553 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
6554 bgp_notify_send(member, BGP_NOTIFY_CEASE,
6555 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
6556 else
6557 bgp_session_reset(member);
6558
6559 /* Attempt to uninstall password on socket. */
6560 if (!BGP_PEER_SU_UNSPEC(member))
6561 bgp_md5_unset(member);
6562 }
6563
6564 /* Set flag and configuration on all peer-group listen ranges */
6565 struct listnode *ln;
6566 struct prefix *lr;
6567
6568 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
6569 bgp_md5_unset_prefix(peer->bgp, lr);
6570 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
6571 bgp_md5_unset_prefix(peer->bgp, lr);
6572
6573 return 0;
6574 }
6575
6576
6577 /* Set distribute list to the peer. */
6578 int peer_distribute_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6579 const char *name)
6580 {
6581 struct peer *member;
6582 struct bgp_filter *filter;
6583 struct listnode *node, *nnode;
6584
6585 if (direct != FILTER_IN && direct != FILTER_OUT)
6586 return BGP_ERR_INVALID_VALUE;
6587
6588 /* Set configuration on peer. */
6589 filter = &peer->filter[afi][safi];
6590 if (filter->plist[direct].name)
6591 return BGP_ERR_PEER_FILTER_CONFLICT;
6592 if (filter->dlist[direct].name)
6593 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[direct].name);
6594 filter->dlist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6595 filter->dlist[direct].alist = access_list_lookup(afi, name);
6596
6597 /* Check if handling a regular peer. */
6598 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6599 /* Set override-flag and process peer route updates. */
6600 SET_FLAG(peer->filter_override[afi][safi][direct],
6601 PEER_FT_DISTRIBUTE_LIST);
6602 peer_on_policy_change(peer, afi, safi,
6603 (direct == FILTER_OUT) ? 1 : 0);
6604
6605 /* Skip peer-group mechanics for regular peers. */
6606 return 0;
6607 }
6608
6609 /*
6610 * Set configuration on all peer-group members, un less they are
6611 * explicitly overriding peer-group configuration.
6612 */
6613 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6614 /* Skip peers with overridden configuration. */
6615 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6616 PEER_FT_DISTRIBUTE_LIST))
6617 continue;
6618
6619 /* Set configuration on peer-group member. */
6620 filter = &member->filter[afi][safi];
6621 if (filter->dlist[direct].name)
6622 XFREE(MTYPE_BGP_FILTER_NAME,
6623 filter->dlist[direct].name);
6624 filter->dlist[direct].name =
6625 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6626 filter->dlist[direct].alist = access_list_lookup(afi, name);
6627
6628 /* Process peer route updates. */
6629 peer_on_policy_change(member, afi, safi,
6630 (direct == FILTER_OUT) ? 1 : 0);
6631 }
6632
6633 return 0;
6634 }
6635
6636 int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
6637 {
6638 struct peer *member;
6639 struct bgp_filter *filter;
6640 struct listnode *node, *nnode;
6641
6642 if (direct != FILTER_IN && direct != FILTER_OUT)
6643 return BGP_ERR_INVALID_VALUE;
6644
6645 /* Unset override-flag unconditionally. */
6646 UNSET_FLAG(peer->filter_override[afi][safi][direct],
6647 PEER_FT_DISTRIBUTE_LIST);
6648
6649 /* Inherit configuration from peer-group if peer is member. */
6650 if (peer_group_active(peer)) {
6651 PEER_STR_ATTR_INHERIT(peer, peer->group,
6652 filter[afi][safi].dlist[direct].name,
6653 MTYPE_BGP_FILTER_NAME);
6654 PEER_ATTR_INHERIT(peer, peer->group,
6655 filter[afi][safi].dlist[direct].alist);
6656 } else {
6657 /* Otherwise remove configuration from peer. */
6658 filter = &peer->filter[afi][safi];
6659 if (filter->dlist[direct].name)
6660 XFREE(MTYPE_BGP_FILTER_NAME,
6661 filter->dlist[direct].name);
6662 filter->dlist[direct].name = NULL;
6663 filter->dlist[direct].alist = NULL;
6664 }
6665
6666 /* Check if handling a regular peer. */
6667 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6668 /* Process peer route updates. */
6669 peer_on_policy_change(peer, afi, safi,
6670 (direct == FILTER_OUT) ? 1 : 0);
6671
6672 /* Skip peer-group mechanics for regular peers. */
6673 return 0;
6674 }
6675
6676 /*
6677 * Remove configuration on all peer-group members, unless they are
6678 * explicitly overriding peer-group configuration.
6679 */
6680 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6681 /* Skip peers with overridden configuration. */
6682 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6683 PEER_FT_DISTRIBUTE_LIST))
6684 continue;
6685
6686 /* Remove configuration on peer-group member. */
6687 filter = &member->filter[afi][safi];
6688 if (filter->dlist[direct].name)
6689 XFREE(MTYPE_BGP_FILTER_NAME,
6690 filter->dlist[direct].name);
6691 filter->dlist[direct].name = NULL;
6692 filter->dlist[direct].alist = NULL;
6693
6694 /* Process peer route updates. */
6695 peer_on_policy_change(member, afi, safi,
6696 (direct == FILTER_OUT) ? 1 : 0);
6697 }
6698
6699 return 0;
6700 }
6701
6702 /* Update distribute list. */
6703 static void peer_distribute_update(struct access_list *access)
6704 {
6705 afi_t afi;
6706 safi_t safi;
6707 int direct;
6708 struct listnode *mnode, *mnnode;
6709 struct listnode *node, *nnode;
6710 struct bgp *bgp;
6711 struct peer *peer;
6712 struct peer_group *group;
6713 struct bgp_filter *filter;
6714
6715 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
6716 if (access->name)
6717 update_group_policy_update(bgp,
6718 BGP_POLICY_DISTRIBUTE_LIST,
6719 access->name, true, 0);
6720 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
6721 FOREACH_AFI_SAFI (afi, safi) {
6722 filter = &peer->filter[afi][safi];
6723
6724 for (direct = FILTER_IN; direct < FILTER_MAX;
6725 direct++) {
6726 if (filter->dlist[direct].name)
6727 filter->dlist[direct]
6728 .alist = access_list_lookup(
6729 afi,
6730 filter->dlist[direct]
6731 .name);
6732 else
6733 filter->dlist[direct].alist =
6734 NULL;
6735 }
6736 }
6737 }
6738 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6739 FOREACH_AFI_SAFI (afi, safi) {
6740 filter = &group->conf->filter[afi][safi];
6741
6742 for (direct = FILTER_IN; direct < FILTER_MAX;
6743 direct++) {
6744 if (filter->dlist[direct].name)
6745 filter->dlist[direct]
6746 .alist = access_list_lookup(
6747 afi,
6748 filter->dlist[direct]
6749 .name);
6750 else
6751 filter->dlist[direct].alist =
6752 NULL;
6753 }
6754 }
6755 }
6756 #ifdef ENABLE_BGP_VNC
6757 vnc_prefix_list_update(bgp);
6758 #endif
6759 }
6760 }
6761
6762 /* Set prefix list to the peer. */
6763 int peer_prefix_list_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6764 const char *name)
6765 {
6766 struct peer *member;
6767 struct bgp_filter *filter;
6768 struct listnode *node, *nnode;
6769
6770 if (direct != FILTER_IN && direct != FILTER_OUT)
6771 return BGP_ERR_INVALID_VALUE;
6772
6773 /* Set configuration on peer. */
6774 filter = &peer->filter[afi][safi];
6775 if (filter->dlist[direct].name)
6776 return BGP_ERR_PEER_FILTER_CONFLICT;
6777 if (filter->plist[direct].name)
6778 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[direct].name);
6779 filter->plist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6780 filter->plist[direct].plist = prefix_list_lookup(afi, name);
6781
6782 /* Check if handling a regular peer. */
6783 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6784 /* Set override-flag and process peer route updates. */
6785 SET_FLAG(peer->filter_override[afi][safi][direct],
6786 PEER_FT_PREFIX_LIST);
6787 peer_on_policy_change(peer, afi, safi,
6788 (direct == FILTER_OUT) ? 1 : 0);
6789
6790 /* Skip peer-group mechanics for regular peers. */
6791 return 0;
6792 }
6793
6794 /*
6795 * Set configuration on all peer-group members, unless they are
6796 * explicitly overriding peer-group configuration.
6797 */
6798 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6799 /* Skip peers with overridden configuration. */
6800 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6801 PEER_FT_PREFIX_LIST))
6802 continue;
6803
6804 /* Set configuration on peer-group member. */
6805 filter = &member->filter[afi][safi];
6806 if (filter->plist[direct].name)
6807 XFREE(MTYPE_BGP_FILTER_NAME,
6808 filter->plist[direct].name);
6809 filter->plist[direct].name =
6810 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6811 filter->plist[direct].plist = prefix_list_lookup(afi, name);
6812
6813 /* Process peer route updates. */
6814 peer_on_policy_change(member, afi, safi,
6815 (direct == FILTER_OUT) ? 1 : 0);
6816 }
6817
6818 return 0;
6819 }
6820
6821 int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi,
6822 int direct)
6823 {
6824 struct peer *member;
6825 struct bgp_filter *filter;
6826 struct listnode *node, *nnode;
6827
6828 if (direct != FILTER_IN && direct != FILTER_OUT)
6829 return BGP_ERR_INVALID_VALUE;
6830
6831 /* Unset override-flag unconditionally. */
6832 UNSET_FLAG(peer->filter_override[afi][safi][direct],
6833 PEER_FT_PREFIX_LIST);
6834
6835 /* Inherit configuration from peer-group if peer is member. */
6836 if (peer_group_active(peer)) {
6837 PEER_STR_ATTR_INHERIT(peer, peer->group,
6838 filter[afi][safi].plist[direct].name,
6839 MTYPE_BGP_FILTER_NAME);
6840 PEER_ATTR_INHERIT(peer, peer->group,
6841 filter[afi][safi].plist[direct].plist);
6842 } else {
6843 /* Otherwise remove configuration from peer. */
6844 filter = &peer->filter[afi][safi];
6845 if (filter->plist[direct].name)
6846 XFREE(MTYPE_BGP_FILTER_NAME,
6847 filter->plist[direct].name);
6848 filter->plist[direct].name = NULL;
6849 filter->plist[direct].plist = NULL;
6850 }
6851
6852 /* Check if handling a regular peer. */
6853 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6854 /* Process peer route updates. */
6855 peer_on_policy_change(peer, afi, safi,
6856 (direct == FILTER_OUT) ? 1 : 0);
6857
6858 /* Skip peer-group mechanics for regular peers. */
6859 return 0;
6860 }
6861
6862 /*
6863 * Remove configuration on all peer-group members, unless they are
6864 * explicitly overriding peer-group configuration.
6865 */
6866 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6867 /* Skip peers with overridden configuration. */
6868 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6869 PEER_FT_PREFIX_LIST))
6870 continue;
6871
6872 /* Remove configuration on peer-group member. */
6873 filter = &member->filter[afi][safi];
6874 if (filter->plist[direct].name)
6875 XFREE(MTYPE_BGP_FILTER_NAME,
6876 filter->plist[direct].name);
6877 filter->plist[direct].name = NULL;
6878 filter->plist[direct].plist = NULL;
6879
6880 /* Process peer route updates. */
6881 peer_on_policy_change(member, afi, safi,
6882 (direct == FILTER_OUT) ? 1 : 0);
6883 }
6884
6885 return 0;
6886 }
6887
6888 /* Update prefix-list list. */
6889 static void peer_prefix_list_update(struct prefix_list *plist)
6890 {
6891 struct listnode *mnode, *mnnode;
6892 struct listnode *node, *nnode;
6893 struct bgp *bgp;
6894 struct peer *peer;
6895 struct peer_group *group;
6896 struct bgp_filter *filter;
6897 afi_t afi;
6898 safi_t safi;
6899 int direct;
6900
6901 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
6902
6903 /*
6904 * Update the prefix-list on update groups.
6905 */
6906 update_group_policy_update(
6907 bgp, BGP_POLICY_PREFIX_LIST,
6908 plist ? prefix_list_name(plist) : NULL, true, 0);
6909
6910 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
6911 FOREACH_AFI_SAFI (afi, safi) {
6912 filter = &peer->filter[afi][safi];
6913
6914 for (direct = FILTER_IN; direct < FILTER_MAX;
6915 direct++) {
6916 if (filter->plist[direct].name)
6917 filter->plist[direct]
6918 .plist = prefix_list_lookup(
6919 afi,
6920 filter->plist[direct]
6921 .name);
6922 else
6923 filter->plist[direct].plist =
6924 NULL;
6925 }
6926
6927 /* If we touch prefix-list, we need to process
6928 * new updates. This is important for ORF to
6929 * work correctly as well.
6930 */
6931 if (peer->afc_nego[afi][safi])
6932 peer_on_policy_change(peer, afi, safi,
6933 0);
6934 }
6935 }
6936 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6937 FOREACH_AFI_SAFI (afi, safi) {
6938 filter = &group->conf->filter[afi][safi];
6939
6940 for (direct = FILTER_IN; direct < FILTER_MAX;
6941 direct++) {
6942 if (filter->plist[direct].name)
6943 filter->plist[direct]
6944 .plist = prefix_list_lookup(
6945 afi,
6946 filter->plist[direct]
6947 .name);
6948 else
6949 filter->plist[direct].plist =
6950 NULL;
6951 }
6952 }
6953 }
6954 }
6955 }
6956
6957 int peer_aslist_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6958 const char *name)
6959 {
6960 struct peer *member;
6961 struct bgp_filter *filter;
6962 struct listnode *node, *nnode;
6963
6964 if (direct != FILTER_IN && direct != FILTER_OUT)
6965 return BGP_ERR_INVALID_VALUE;
6966
6967 /* Set configuration on peer. */
6968 filter = &peer->filter[afi][safi];
6969 if (filter->aslist[direct].name)
6970 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[direct].name);
6971 filter->aslist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6972 filter->aslist[direct].aslist = as_list_lookup(name);
6973
6974 /* Check if handling a regular peer. */
6975 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6976 /* Set override-flag and process peer route updates. */
6977 SET_FLAG(peer->filter_override[afi][safi][direct],
6978 PEER_FT_FILTER_LIST);
6979 peer_on_policy_change(peer, afi, safi,
6980 (direct == FILTER_OUT) ? 1 : 0);
6981
6982 /* Skip peer-group mechanics for regular peers. */
6983 return 0;
6984 }
6985
6986 /*
6987 * Set configuration on all peer-group members, unless they are
6988 * explicitly overriding peer-group configuration.
6989 */
6990 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6991 /* Skip peers with overridden configuration. */
6992 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6993 PEER_FT_FILTER_LIST))
6994 continue;
6995
6996 /* Set configuration on peer-group member. */
6997 filter = &member->filter[afi][safi];
6998 if (filter->aslist[direct].name)
6999 XFREE(MTYPE_BGP_FILTER_NAME,
7000 filter->aslist[direct].name);
7001 filter->aslist[direct].name =
7002 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7003 filter->aslist[direct].aslist = as_list_lookup(name);
7004
7005 /* Process peer route updates. */
7006 peer_on_policy_change(member, afi, safi,
7007 (direct == FILTER_OUT) ? 1 : 0);
7008 }
7009
7010 return 0;
7011 }
7012
7013 int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
7014 {
7015 struct peer *member;
7016 struct bgp_filter *filter;
7017 struct listnode *node, *nnode;
7018
7019 if (direct != FILTER_IN && direct != FILTER_OUT)
7020 return BGP_ERR_INVALID_VALUE;
7021
7022 /* Unset override-flag unconditionally. */
7023 UNSET_FLAG(peer->filter_override[afi][safi][direct],
7024 PEER_FT_FILTER_LIST);
7025
7026 /* Inherit configuration from peer-group if peer is member. */
7027 if (peer_group_active(peer)) {
7028 PEER_STR_ATTR_INHERIT(peer, peer->group,
7029 filter[afi][safi].aslist[direct].name,
7030 MTYPE_BGP_FILTER_NAME);
7031 PEER_ATTR_INHERIT(peer, peer->group,
7032 filter[afi][safi].aslist[direct].aslist);
7033 } else {
7034 /* Otherwise remove configuration from peer. */
7035 filter = &peer->filter[afi][safi];
7036 if (filter->aslist[direct].name)
7037 XFREE(MTYPE_BGP_FILTER_NAME,
7038 filter->aslist[direct].name);
7039 filter->aslist[direct].name = NULL;
7040 filter->aslist[direct].aslist = NULL;
7041 }
7042
7043 /* Check if handling a regular peer. */
7044 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7045 /* Process peer route updates. */
7046 peer_on_policy_change(peer, afi, safi,
7047 (direct == FILTER_OUT) ? 1 : 0);
7048
7049 /* Skip peer-group mechanics for regular peers. */
7050 return 0;
7051 }
7052
7053 /*
7054 * Remove configuration on all peer-group members, unless they are
7055 * explicitly overriding peer-group configuration.
7056 */
7057 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7058 /* Skip peers with overridden configuration. */
7059 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7060 PEER_FT_FILTER_LIST))
7061 continue;
7062
7063 /* Remove configuration on peer-group member. */
7064 filter = &member->filter[afi][safi];
7065 if (filter->aslist[direct].name)
7066 XFREE(MTYPE_BGP_FILTER_NAME,
7067 filter->aslist[direct].name);
7068 filter->aslist[direct].name = NULL;
7069 filter->aslist[direct].aslist = NULL;
7070
7071 /* Process peer route updates. */
7072 peer_on_policy_change(member, afi, safi,
7073 (direct == FILTER_OUT) ? 1 : 0);
7074 }
7075
7076 return 0;
7077 }
7078
7079 static void peer_aslist_update(const char *aslist_name)
7080 {
7081 afi_t afi;
7082 safi_t safi;
7083 int direct;
7084 struct listnode *mnode, *mnnode;
7085 struct listnode *node, *nnode;
7086 struct bgp *bgp;
7087 struct peer *peer;
7088 struct peer_group *group;
7089 struct bgp_filter *filter;
7090
7091 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
7092 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
7093 aslist_name, true, 0);
7094
7095 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7096 FOREACH_AFI_SAFI (afi, safi) {
7097 filter = &peer->filter[afi][safi];
7098
7099 for (direct = FILTER_IN; direct < FILTER_MAX;
7100 direct++) {
7101 if (filter->aslist[direct].name)
7102 filter->aslist[direct]
7103 .aslist = as_list_lookup(
7104 filter->aslist[direct]
7105 .name);
7106 else
7107 filter->aslist[direct].aslist =
7108 NULL;
7109 }
7110 }
7111 }
7112 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
7113 FOREACH_AFI_SAFI (afi, safi) {
7114 filter = &group->conf->filter[afi][safi];
7115
7116 for (direct = FILTER_IN; direct < FILTER_MAX;
7117 direct++) {
7118 if (filter->aslist[direct].name)
7119 filter->aslist[direct]
7120 .aslist = as_list_lookup(
7121 filter->aslist[direct]
7122 .name);
7123 else
7124 filter->aslist[direct].aslist =
7125 NULL;
7126 }
7127 }
7128 }
7129 }
7130 }
7131
7132 static void peer_aslist_add(char *aslist_name)
7133 {
7134 peer_aslist_update(aslist_name);
7135 route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_ADDED);
7136 }
7137
7138 static void peer_aslist_del(const char *aslist_name)
7139 {
7140 peer_aslist_update(aslist_name);
7141 route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_DELETED);
7142 }
7143
7144
7145 int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
7146 const char *name, struct route_map *route_map)
7147 {
7148 struct peer *member;
7149 struct bgp_filter *filter;
7150 struct listnode *node, *nnode;
7151
7152 if (direct != RMAP_IN && direct != RMAP_OUT)
7153 return BGP_ERR_INVALID_VALUE;
7154
7155 /* Set configuration on peer. */
7156 filter = &peer->filter[afi][safi];
7157 if (filter->map[direct].name) {
7158 /* If the neighbor is configured with the same route-map
7159 * again then, ignore the duplicate configuration.
7160 */
7161 if (strcmp(filter->map[direct].name, name) == 0)
7162 return 0;
7163
7164 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7165 }
7166 route_map_counter_decrement(filter->map[direct].map);
7167 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7168 filter->map[direct].map = route_map;
7169 route_map_counter_increment(route_map);
7170
7171 /* Check if handling a regular peer. */
7172 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7173 /* Set override-flag and process peer route updates. */
7174 SET_FLAG(peer->filter_override[afi][safi][direct],
7175 PEER_FT_ROUTE_MAP);
7176 peer_on_policy_change(peer, afi, safi,
7177 (direct == RMAP_OUT) ? 1 : 0);
7178
7179 /* Skip peer-group mechanics for regular peers. */
7180 return 0;
7181 }
7182
7183 /*
7184 * Set configuration on all peer-group members, unless they are
7185 * explicitly overriding peer-group configuration.
7186 */
7187 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7188 /* Skip peers with overridden configuration. */
7189 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7190 PEER_FT_ROUTE_MAP))
7191 continue;
7192
7193 /* Set configuration on peer-group member. */
7194 filter = &member->filter[afi][safi];
7195 if (filter->map[direct].name)
7196 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7197 route_map_counter_decrement(filter->map[direct].map);
7198 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7199 filter->map[direct].map = route_map;
7200 route_map_counter_increment(route_map);
7201
7202 /* Process peer route updates. */
7203 peer_on_policy_change(member, afi, safi,
7204 (direct == RMAP_OUT) ? 1 : 0);
7205 }
7206 return 0;
7207 }
7208
7209 /* Unset route-map from the peer. */
7210 int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
7211 {
7212 struct peer *member;
7213 struct bgp_filter *filter;
7214 struct listnode *node, *nnode;
7215
7216 if (direct != RMAP_IN && direct != RMAP_OUT)
7217 return BGP_ERR_INVALID_VALUE;
7218
7219 /* Unset override-flag unconditionally. */
7220 UNSET_FLAG(peer->filter_override[afi][safi][direct], PEER_FT_ROUTE_MAP);
7221
7222 /* Inherit configuration from peer-group if peer is member. */
7223 if (peer_group_active(peer)) {
7224 PEER_STR_ATTR_INHERIT(peer, peer->group,
7225 filter[afi][safi].map[direct].name,
7226 MTYPE_BGP_FILTER_NAME);
7227 PEER_ATTR_INHERIT(peer, peer->group,
7228 filter[afi][safi].map[direct].map);
7229 } else {
7230 /* Otherwise remove configuration from peer. */
7231 filter = &peer->filter[afi][safi];
7232 if (filter->map[direct].name)
7233 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7234 route_map_counter_decrement(filter->map[direct].map);
7235 filter->map[direct].name = NULL;
7236 filter->map[direct].map = NULL;
7237 }
7238
7239 /* Check if handling a regular peer. */
7240 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7241 /* Process peer route updates. */
7242 peer_on_policy_change(peer, afi, safi,
7243 (direct == RMAP_OUT) ? 1 : 0);
7244
7245 /* Skip peer-group mechanics for regular peers. */
7246 return 0;
7247 }
7248
7249 /*
7250 * Remove configuration on all peer-group members, unless they are
7251 * explicitly overriding peer-group configuration.
7252 */
7253 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7254 /* Skip peers with overridden configuration. */
7255 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
7256 PEER_FT_ROUTE_MAP))
7257 continue;
7258
7259 /* Remove configuration on peer-group member. */
7260 filter = &member->filter[afi][safi];
7261 if (filter->map[direct].name)
7262 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
7263 route_map_counter_decrement(filter->map[direct].map);
7264 filter->map[direct].name = NULL;
7265 filter->map[direct].map = NULL;
7266
7267 /* Process peer route updates. */
7268 peer_on_policy_change(member, afi, safi,
7269 (direct == RMAP_OUT) ? 1 : 0);
7270 }
7271
7272 return 0;
7273 }
7274
7275 /* Set unsuppress-map to the peer. */
7276 int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
7277 const char *name, struct route_map *route_map)
7278 {
7279 struct peer *member;
7280 struct bgp_filter *filter;
7281 struct listnode *node, *nnode;
7282
7283 /* Set configuration on peer. */
7284 filter = &peer->filter[afi][safi];
7285 if (filter->usmap.name)
7286 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7287 route_map_counter_decrement(filter->usmap.map);
7288 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7289 filter->usmap.map = route_map;
7290 route_map_counter_increment(route_map);
7291
7292 /* Check if handling a regular peer. */
7293 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7294 /* Set override-flag and process peer route updates. */
7295 SET_FLAG(peer->filter_override[afi][safi][0],
7296 PEER_FT_UNSUPPRESS_MAP);
7297 peer_on_policy_change(peer, afi, safi, 1);
7298
7299 /* Skip peer-group mechanics for regular peers. */
7300 return 0;
7301 }
7302
7303 /*
7304 * Set configuration on all peer-group members, unless they are
7305 * explicitly overriding peer-group configuration.
7306 */
7307 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7308 /* Skip peers with overridden configuration. */
7309 if (CHECK_FLAG(member->filter_override[afi][safi][0],
7310 PEER_FT_UNSUPPRESS_MAP))
7311 continue;
7312
7313 /* Set configuration on peer-group member. */
7314 filter = &member->filter[afi][safi];
7315 if (filter->usmap.name)
7316 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7317 route_map_counter_decrement(filter->usmap.map);
7318 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
7319 filter->usmap.map = route_map;
7320 route_map_counter_increment(route_map);
7321
7322 /* Process peer route updates. */
7323 peer_on_policy_change(member, afi, safi, 1);
7324 }
7325
7326 return 0;
7327 }
7328
7329 /* Unset route-map from the peer. */
7330 int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
7331 {
7332 struct peer *member;
7333 struct bgp_filter *filter;
7334 struct listnode *node, *nnode;
7335
7336 /* Unset override-flag unconditionally. */
7337 UNSET_FLAG(peer->filter_override[afi][safi][0], PEER_FT_UNSUPPRESS_MAP);
7338
7339 /* Inherit configuration from peer-group if peer is member. */
7340 if (peer_group_active(peer)) {
7341 PEER_STR_ATTR_INHERIT(peer, peer->group,
7342 filter[afi][safi].usmap.name,
7343 MTYPE_BGP_FILTER_NAME);
7344 PEER_ATTR_INHERIT(peer, peer->group,
7345 filter[afi][safi].usmap.map);
7346 } else {
7347 /* Otherwise remove configuration from peer. */
7348 filter = &peer->filter[afi][safi];
7349 if (filter->usmap.name)
7350 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7351 route_map_counter_decrement(filter->usmap.map);
7352 filter->usmap.name = NULL;
7353 filter->usmap.map = NULL;
7354 }
7355
7356 /* Check if handling a regular peer. */
7357 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7358 /* Process peer route updates. */
7359 peer_on_policy_change(peer, afi, safi, 1);
7360
7361 /* Skip peer-group mechanics for regular peers. */
7362 return 0;
7363 }
7364
7365 /*
7366 * Remove configuration on all peer-group members, unless they are
7367 * explicitly overriding peer-group configuration.
7368 */
7369 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7370 /* Skip peers with overridden configuration. */
7371 if (CHECK_FLAG(member->filter_override[afi][safi][0],
7372 PEER_FT_UNSUPPRESS_MAP))
7373 continue;
7374
7375 /* Remove configuration on peer-group member. */
7376 filter = &member->filter[afi][safi];
7377 if (filter->usmap.name)
7378 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
7379 route_map_counter_decrement(filter->usmap.map);
7380 filter->usmap.name = NULL;
7381 filter->usmap.map = NULL;
7382
7383 /* Process peer route updates. */
7384 peer_on_policy_change(member, afi, safi, 1);
7385 }
7386
7387 return 0;
7388 }
7389
7390 static bool peer_maximum_prefix_clear_overflow(struct peer *peer)
7391 {
7392 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
7393 return false;
7394
7395 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
7396 if (peer->t_pmax_restart) {
7397 THREAD_OFF(peer->t_pmax_restart);
7398 if (bgp_debug_neighbor_events(peer))
7399 zlog_debug(
7400 "%pBP Maximum-prefix restart timer cancelled",
7401 peer);
7402 }
7403 BGP_EVENT_ADD(peer, BGP_Start);
7404 return true;
7405 }
7406
7407 int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
7408 uint32_t max, uint8_t threshold, int warning,
7409 uint16_t restart, bool force)
7410 {
7411 struct peer *member;
7412 struct listnode *node, *nnode;
7413
7414 /* Set flags and configuration on peer. */
7415 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
7416
7417 if (force)
7418 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
7419 else
7420 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
7421
7422 if (warning)
7423 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
7424 else
7425 peer_af_flag_unset(peer, afi, safi,
7426 PEER_FLAG_MAX_PREFIX_WARNING);
7427
7428 peer->pmax[afi][safi] = max;
7429 peer->pmax_threshold[afi][safi] = threshold;
7430 peer->pmax_restart[afi][safi] = restart;
7431
7432 /* Check if handling a regular peer. */
7433 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7434 /* Re-check if peer violates maximum-prefix. */
7435 if ((peer_established(peer)) && (peer->afc[afi][safi]))
7436 bgp_maximum_prefix_overflow(peer, afi, safi, 1);
7437
7438 /* Skip peer-group mechanics for regular peers. */
7439 return 0;
7440 }
7441
7442 /*
7443 * Set flags and configuration on all peer-group members, unless they
7444 * are explicitly overriding peer-group configuration.
7445 */
7446 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7447 /* Skip peers with overridden configuration. */
7448 if (CHECK_FLAG(member->af_flags_override[afi][safi],
7449 PEER_FLAG_MAX_PREFIX))
7450 continue;
7451
7452 /* Set flag and configuration on peer-group member. */
7453 member->pmax[afi][safi] = max;
7454 member->pmax_threshold[afi][safi] = threshold;
7455 member->pmax_restart[afi][safi] = restart;
7456
7457 if (force)
7458 SET_FLAG(member->af_flags[afi][safi],
7459 PEER_FLAG_MAX_PREFIX_FORCE);
7460 else
7461 UNSET_FLAG(member->af_flags[afi][safi],
7462 PEER_FLAG_MAX_PREFIX_FORCE);
7463
7464 if (warning)
7465 SET_FLAG(member->af_flags[afi][safi],
7466 PEER_FLAG_MAX_PREFIX_WARNING);
7467 else
7468 UNSET_FLAG(member->af_flags[afi][safi],
7469 PEER_FLAG_MAX_PREFIX_WARNING);
7470
7471 /* Re-check if peer violates maximum-prefix. */
7472 if ((peer_established(member)) && (member->afc[afi][safi]))
7473 bgp_maximum_prefix_overflow(member, afi, safi, 1);
7474 }
7475
7476 return 0;
7477 }
7478
7479 int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
7480 {
7481 /* Inherit configuration from peer-group if peer is member. */
7482 if (peer_group_active(peer)) {
7483 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
7484 peer_af_flag_inherit(peer, afi, safi,
7485 PEER_FLAG_MAX_PREFIX_FORCE);
7486 peer_af_flag_inherit(peer, afi, safi,
7487 PEER_FLAG_MAX_PREFIX_WARNING);
7488 PEER_ATTR_INHERIT(peer, peer->group, pmax[afi][safi]);
7489 PEER_ATTR_INHERIT(peer, peer->group, pmax_threshold[afi][safi]);
7490 PEER_ATTR_INHERIT(peer, peer->group, pmax_restart[afi][safi]);
7491
7492 return 0;
7493 }
7494
7495 /* Remove flags and configuration from peer. */
7496 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
7497 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_FORCE);
7498 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
7499 peer->pmax[afi][safi] = 0;
7500 peer->pmax_threshold[afi][safi] = 0;
7501 peer->pmax_restart[afi][safi] = 0;
7502
7503 /*
7504 * Remove flags and configuration from all peer-group members, unless
7505 * they are explicitly overriding peer-group configuration.
7506 */
7507 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7508 struct peer *member;
7509 struct listnode *node;
7510
7511 for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
7512 /* Skip peers with overridden configuration. */
7513 if (CHECK_FLAG(member->af_flags_override[afi][safi],
7514 PEER_FLAG_MAX_PREFIX))
7515 continue;
7516
7517 /* Remove flag and configuration on peer-group member.
7518 */
7519 UNSET_FLAG(member->af_flags[afi][safi],
7520 PEER_FLAG_MAX_PREFIX);
7521 UNSET_FLAG(member->af_flags[afi][safi],
7522 PEER_FLAG_MAX_PREFIX_FORCE);
7523 UNSET_FLAG(member->af_flags[afi][safi],
7524 PEER_FLAG_MAX_PREFIX_WARNING);
7525 member->pmax[afi][safi] = 0;
7526 member->pmax_threshold[afi][safi] = 0;
7527 member->pmax_restart[afi][safi] = 0;
7528
7529 peer_maximum_prefix_clear_overflow(member);
7530 }
7531 } else {
7532 peer_maximum_prefix_clear_overflow(peer);
7533 }
7534
7535 return 0;
7536 }
7537
7538 void peer_maximum_prefix_out_refresh_routes(struct peer *peer, afi_t afi,
7539 safi_t safi)
7540 {
7541 update_group_adjust_peer(peer_af_find(peer, afi, safi));
7542
7543 if (peer_established(peer))
7544 bgp_announce_route(peer, afi, safi, false);
7545 }
7546
7547 int peer_maximum_prefix_out_set(struct peer *peer, afi_t afi, safi_t safi,
7548 uint32_t max)
7549 {
7550 struct peer *member;
7551 struct listnode *node, *nnode;
7552
7553 /* Set flag on peer and peer-group member if any */
7554 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT);
7555 /* Set configuration on peer. */
7556 peer->pmax_out[afi][safi] = max;
7557
7558 /* Check if handling a regular peer. */
7559 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7560 /* Skip peer-group mechanics for regular peers. */
7561 peer_maximum_prefix_out_refresh_routes(peer, afi, safi);
7562 return 0;
7563 }
7564
7565 /*
7566 * Set flag and configuration on all peer-group members, unless they
7567 * are explicitly overriding peer-group configuration.
7568 */
7569 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
7570 /* Skip peers with overridden configuration. */
7571 if (CHECK_FLAG(member->af_flags_override[afi][safi],
7572 PEER_FLAG_MAX_PREFIX_OUT))
7573 continue;
7574
7575 /* Set configuration on peer-group member. */
7576 member->pmax_out[afi][safi] = max;
7577
7578 peer_maximum_prefix_out_refresh_routes(member, afi, safi);
7579 }
7580 return 0;
7581 }
7582
7583 int peer_maximum_prefix_out_unset(struct peer *peer, afi_t afi, safi_t safi)
7584 {
7585 struct peer *member;
7586 struct listnode *node;
7587 /* Inherit configuration from peer-group if peer is member. */
7588 if (peer_group_active(peer)) {
7589 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT);
7590 PEER_ATTR_INHERIT(peer, peer->group, pmax_out[afi][safi]);
7591
7592 peer_maximum_prefix_out_refresh_routes(peer, afi, safi);
7593 return 0;
7594 }
7595
7596 /* Remove flag and configuration from peer. */
7597 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT);
7598 peer->pmax_out[afi][safi] = 0;
7599
7600 /* Check if handling a regular peer. */
7601 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7602 /* Skip peer-group mechanics for regular peers. */
7603 peer_maximum_prefix_out_refresh_routes(peer, afi, safi);
7604 return 0;
7605 }
7606
7607 /*
7608 * Remove flag and configuration from all peer-group members, unless
7609 * they are explicitly overriding peer-group configuration.
7610 */
7611 for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
7612 /* Skip peers with overridden configuration. */
7613 if (CHECK_FLAG(member->af_flags_override[afi][safi],
7614 PEER_FLAG_MAX_PREFIX_OUT))
7615 continue;
7616
7617 /* Remove flag and configuration on peer-group member.
7618 */
7619 UNSET_FLAG(member->af_flags[afi][safi],
7620 PEER_FLAG_MAX_PREFIX_OUT);
7621 member->pmax_out[afi][safi] = 0;
7622
7623 peer_maximum_prefix_out_refresh_routes(member, afi, safi);
7624 }
7625 return 0;
7626 }
7627
7628 int is_ebgp_multihop_configured(struct peer *peer)
7629 {
7630 struct peer_group *group;
7631 struct listnode *node, *nnode;
7632 struct peer *peer1;
7633
7634 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7635 group = peer->group;
7636 if ((peer_sort(peer) != BGP_PEER_IBGP)
7637 && (group->conf->ttl != BGP_DEFAULT_TTL))
7638 return 1;
7639
7640 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer1)) {
7641 if ((peer_sort(peer1) != BGP_PEER_IBGP)
7642 && (peer1->ttl != BGP_DEFAULT_TTL))
7643 return 1;
7644 }
7645 } else {
7646 if ((peer_sort(peer) != BGP_PEER_IBGP)
7647 && (peer->ttl != BGP_DEFAULT_TTL))
7648 return 1;
7649 }
7650 return 0;
7651 }
7652
7653 /* Set # of hops between us and BGP peer. */
7654 int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops)
7655 {
7656 struct peer_group *group;
7657 struct peer *gpeer;
7658 struct listnode *node, *nnode;
7659 int ret;
7660
7661 zlog_debug("%s: set gtsm_hops to %d for %s", __func__, gtsm_hops,
7662 peer->host);
7663
7664 /* We cannot configure ttl-security hops when ebgp-multihop is already
7665 set. For non peer-groups, the check is simple. For peer-groups,
7666 it's
7667 slightly messy, because we need to check both the peer-group
7668 structure
7669 and all peer-group members for any trace of ebgp-multihop
7670 configuration
7671 before actually applying the ttl-security rules. Cisco really made a
7672 mess of this configuration parameter, and OpenBGPD got it right.
7673 */
7674
7675 if ((peer->gtsm_hops == BGP_GTSM_HOPS_DISABLED)
7676 && (peer->sort != BGP_PEER_IBGP)) {
7677 if (is_ebgp_multihop_configured(peer))
7678 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
7679
7680 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7681 peer->gtsm_hops = gtsm_hops;
7682
7683 /* Calling ebgp multihop also resets the session.
7684 * On restart, NHT will get setup correctly as will the
7685 * min & max ttls on the socket. The return value is
7686 * irrelevant.
7687 */
7688 ret = peer_ebgp_multihop_set(peer, MAXTTL);
7689
7690 if (ret != 0)
7691 return ret;
7692 } else {
7693 group = peer->group;
7694 group->conf->gtsm_hops = gtsm_hops;
7695 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
7696 gpeer)) {
7697 gpeer->gtsm_hops = group->conf->gtsm_hops;
7698
7699 /* Calling ebgp multihop also resets the
7700 * session.
7701 * On restart, NHT will get setup correctly as
7702 * will the
7703 * min & max ttls on the socket. The return
7704 * value is
7705 * irrelevant.
7706 */
7707 peer_ebgp_multihop_set(gpeer, MAXTTL);
7708 }
7709 }
7710 } else {
7711 /* Post the first gtsm setup or if its ibgp, maxttl setting
7712 * isn't
7713 * necessary, just set the minttl.
7714 */
7715 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7716 peer->gtsm_hops = gtsm_hops;
7717
7718 if (peer->fd >= 0)
7719 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
7720 MAXTTL + 1 - gtsm_hops);
7721 if ((peer->status < Established) && peer->doppelganger
7722 && (peer->doppelganger->fd >= 0))
7723 sockopt_minttl(peer->su.sa.sa_family,
7724 peer->doppelganger->fd,
7725 MAXTTL + 1 - gtsm_hops);
7726 } else {
7727 group = peer->group;
7728 group->conf->gtsm_hops = gtsm_hops;
7729 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
7730 gpeer)) {
7731 gpeer->gtsm_hops = group->conf->gtsm_hops;
7732
7733 /* Change setting of existing peer
7734 * established then change value (may break
7735 * connectivity)
7736 * not established yet (teardown session and
7737 * restart)
7738 * no session then do nothing (will get
7739 * handled by next connection)
7740 */
7741 if (gpeer->fd >= 0
7742 && gpeer->gtsm_hops
7743 != BGP_GTSM_HOPS_DISABLED)
7744 sockopt_minttl(
7745 gpeer->su.sa.sa_family,
7746 gpeer->fd,
7747 MAXTTL + 1 - gpeer->gtsm_hops);
7748 if ((gpeer->status < Established)
7749 && gpeer->doppelganger
7750 && (gpeer->doppelganger->fd >= 0))
7751 sockopt_minttl(gpeer->su.sa.sa_family,
7752 gpeer->doppelganger->fd,
7753 MAXTTL + 1 - gtsm_hops);
7754 }
7755 }
7756 }
7757
7758 return 0;
7759 }
7760
7761 int peer_ttl_security_hops_unset(struct peer *peer)
7762 {
7763 struct peer_group *group;
7764 struct listnode *node, *nnode;
7765 int ret = 0;
7766
7767 zlog_debug("%s: set gtsm_hops to zero for %s", __func__, peer->host);
7768
7769 /* if a peer-group member, then reset to peer-group default rather than
7770 * 0 */
7771 if (peer_group_active(peer))
7772 peer->gtsm_hops = peer->group->conf->gtsm_hops;
7773 else
7774 peer->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
7775
7776 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7777 /* Invoking ebgp_multihop_set will set the TTL back to the
7778 * original
7779 * value as well as restting the NHT and such. The session is
7780 * reset.
7781 */
7782 if (peer->sort == BGP_PEER_EBGP)
7783 ret = peer_ebgp_multihop_unset(peer);
7784 else {
7785 if (peer->fd >= 0)
7786 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
7787 0);
7788
7789 if ((peer->status < Established) && peer->doppelganger
7790 && (peer->doppelganger->fd >= 0))
7791 sockopt_minttl(peer->su.sa.sa_family,
7792 peer->doppelganger->fd, 0);
7793 }
7794 } else {
7795 group = peer->group;
7796 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
7797 peer->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
7798 if (peer->sort == BGP_PEER_EBGP)
7799 ret = peer_ebgp_multihop_unset(peer);
7800 else {
7801 if (peer->fd >= 0)
7802 sockopt_minttl(peer->su.sa.sa_family,
7803 peer->fd, 0);
7804
7805 if ((peer->status < Established)
7806 && peer->doppelganger
7807 && (peer->doppelganger->fd >= 0))
7808 sockopt_minttl(peer->su.sa.sa_family,
7809 peer->doppelganger->fd,
7810 0);
7811 }
7812 }
7813 }
7814
7815 return ret;
7816 }
7817
7818 static void peer_reset_message_stats(struct peer *peer)
7819 {
7820 if (peer) {
7821 atomic_store_explicit(&peer->open_in, 0, memory_order_relaxed);
7822 atomic_store_explicit(&peer->open_out, 0, memory_order_relaxed);
7823 atomic_store_explicit(&peer->update_in, 0,
7824 memory_order_relaxed);
7825 atomic_store_explicit(&peer->update_out, 0,
7826 memory_order_relaxed);
7827 atomic_store_explicit(&peer->keepalive_in, 0,
7828 memory_order_relaxed);
7829 atomic_store_explicit(&peer->keepalive_out, 0,
7830 memory_order_relaxed);
7831 atomic_store_explicit(&peer->notify_in, 0,
7832 memory_order_relaxed);
7833 atomic_store_explicit(&peer->notify_out, 0,
7834 memory_order_relaxed);
7835 atomic_store_explicit(&peer->refresh_in, 0,
7836 memory_order_relaxed);
7837 atomic_store_explicit(&peer->refresh_out, 0,
7838 memory_order_relaxed);
7839 atomic_store_explicit(&peer->dynamic_cap_in, 0,
7840 memory_order_relaxed);
7841 atomic_store_explicit(&peer->dynamic_cap_out, 0,
7842 memory_order_relaxed);
7843 }
7844 }
7845
7846 /*
7847 * If peer clear is invoked in a loop for all peers on the BGP instance,
7848 * it may end up freeing the doppelganger, and if this was the next node
7849 * to the current node, we would end up accessing the freed next node.
7850 * Pass along additional parameter which can be updated if next node
7851 * is freed; only required when walking the peer list on BGP instance.
7852 */
7853 int peer_clear(struct peer *peer, struct listnode **nnode)
7854 {
7855 if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)
7856 || !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN)) {
7857 if (peer_maximum_prefix_clear_overflow(peer))
7858 return 0;
7859
7860 peer->v_start = BGP_INIT_START_TIMER;
7861 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
7862 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
7863 BGP_NOTIFY_CEASE_ADMIN_RESET);
7864 else
7865 bgp_session_reset_safe(peer, nnode);
7866 }
7867 return 0;
7868 }
7869
7870 int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi,
7871 enum bgp_clear_type stype)
7872 {
7873 struct peer_af *paf;
7874
7875 if (!peer_established(peer))
7876 return 0;
7877
7878 if (!peer->afc[afi][safi])
7879 return BGP_ERR_AF_UNCONFIGURED;
7880
7881 peer->rtt = sockopt_tcp_rtt(peer->fd);
7882
7883 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) {
7884 /* Clear the "neighbor x.x.x.x default-originate" flag */
7885 paf = peer_af_find(peer, afi, safi);
7886 if (paf && paf->subgroup
7887 && CHECK_FLAG(paf->subgroup->sflags,
7888 SUBGRP_STATUS_DEFAULT_ORIGINATE))
7889 UNSET_FLAG(paf->subgroup->sflags,
7890 SUBGRP_STATUS_DEFAULT_ORIGINATE);
7891
7892 bgp_announce_route(peer, afi, safi, false);
7893 }
7894
7895 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
7896 if (CHECK_FLAG(peer->af_cap[afi][safi],
7897 PEER_CAP_ORF_PREFIX_SM_ADV)
7898 && (CHECK_FLAG(peer->af_cap[afi][safi],
7899 PEER_CAP_ORF_PREFIX_RM_RCV)
7900 || CHECK_FLAG(peer->af_cap[afi][safi],
7901 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))) {
7902 struct bgp_filter *filter = &peer->filter[afi][safi];
7903 uint8_t prefix_type;
7904
7905 if (CHECK_FLAG(peer->af_cap[afi][safi],
7906 PEER_CAP_ORF_PREFIX_RM_RCV))
7907 prefix_type = ORF_TYPE_PREFIX;
7908 else
7909 prefix_type = ORF_TYPE_PREFIX_OLD;
7910
7911 if (filter->plist[FILTER_IN].plist) {
7912 if (CHECK_FLAG(peer->af_sflags[afi][safi],
7913 PEER_STATUS_ORF_PREFIX_SEND))
7914 bgp_route_refresh_send(
7915 peer, afi, safi, prefix_type,
7916 REFRESH_DEFER, 1,
7917 BGP_ROUTE_REFRESH_NORMAL);
7918 bgp_route_refresh_send(
7919 peer, afi, safi, prefix_type,
7920 REFRESH_IMMEDIATE, 0,
7921 BGP_ROUTE_REFRESH_NORMAL);
7922 } else {
7923 if (CHECK_FLAG(peer->af_sflags[afi][safi],
7924 PEER_STATUS_ORF_PREFIX_SEND))
7925 bgp_route_refresh_send(
7926 peer, afi, safi, prefix_type,
7927 REFRESH_IMMEDIATE, 1,
7928 BGP_ROUTE_REFRESH_NORMAL);
7929 else
7930 bgp_route_refresh_send(
7931 peer, afi, safi, 0, 0, 0,
7932 BGP_ROUTE_REFRESH_NORMAL);
7933 }
7934 return 0;
7935 }
7936 }
7937
7938 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
7939 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
7940 /* If neighbor has soft reconfiguration inbound flag.
7941 Use Adj-RIB-In database. */
7942 if (!bgp_soft_reconfig_in(peer, afi, safi)) {
7943 /* If neighbor has route refresh capability, send route
7944 refresh
7945 message to the peer. */
7946 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
7947 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
7948 bgp_route_refresh_send(
7949 peer, afi, safi, 0, 0, 0,
7950 BGP_ROUTE_REFRESH_NORMAL);
7951 else
7952 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
7953 }
7954 }
7955
7956 if (stype == BGP_CLEAR_MESSAGE_STATS)
7957 peer_reset_message_stats(peer);
7958
7959 return 0;
7960 }
7961
7962 /* Display peer uptime.*/
7963 char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
7964 json_object *json)
7965 {
7966 time_t uptime1, epoch_tbuf;
7967 struct tm tm;
7968
7969 /* If there is no connection has been done before print `never'. */
7970 if (uptime2 == 0) {
7971 if (use_json) {
7972 json_object_string_add(json, "peerUptime", "never");
7973 json_object_int_add(json, "peerUptimeMsec", 0);
7974 } else
7975 snprintf(buf, len, "never");
7976 return buf;
7977 }
7978
7979 /* Get current time. */
7980 uptime1 = monotime(NULL);
7981 uptime1 -= uptime2;
7982 gmtime_r(&uptime1, &tm);
7983
7984 if (uptime1 < ONE_DAY_SECOND)
7985 snprintf(buf, len, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min,
7986 tm.tm_sec);
7987 else if (uptime1 < ONE_WEEK_SECOND)
7988 snprintf(buf, len, "%dd%02dh%02dm", tm.tm_yday, tm.tm_hour,
7989 tm.tm_min);
7990 else if (uptime1 < ONE_YEAR_SECOND)
7991 snprintf(buf, len, "%02dw%dd%02dh", tm.tm_yday / 7,
7992 tm.tm_yday - ((tm.tm_yday / 7) * 7), tm.tm_hour);
7993 else
7994 snprintf(buf, len, "%02dy%02dw%dd", tm.tm_year - 70,
7995 tm.tm_yday / 7,
7996 tm.tm_yday - ((tm.tm_yday / 7) * 7));
7997
7998 if (use_json) {
7999 epoch_tbuf = time(NULL) - uptime1;
8000 json_object_string_add(json, "peerUptime", buf);
8001 json_object_int_add(json, "peerUptimeMsec", uptime1 * 1000);
8002 json_object_int_add(json, "peerUptimeEstablishedEpoch",
8003 epoch_tbuf);
8004 }
8005
8006 return buf;
8007 }
8008
8009 void bgp_master_init(struct thread_master *master, const int buffer_size,
8010 struct list *addresses)
8011 {
8012 qobj_init();
8013
8014 memset(&bgp_master, 0, sizeof(bgp_master));
8015
8016 bm = &bgp_master;
8017 bm->bgp = list_new();
8018 bm->listen_sockets = list_new();
8019 bm->port = BGP_PORT_DEFAULT;
8020 bm->addresses = addresses;
8021 bm->master = master;
8022 bm->start_time = monotime(NULL);
8023 bm->t_rmap_update = NULL;
8024 bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
8025 bm->v_update_delay = BGP_UPDATE_DELAY_DEF;
8026 bm->v_establish_wait = BGP_UPDATE_DELAY_DEF;
8027 bm->terminating = false;
8028 bm->socket_buffer = buffer_size;
8029 bm->wait_for_fib = false;
8030 bm->tcp_dscp = IPTOS_PREC_INTERNETCONTROL;
8031 bm->inq_limit = BM_DEFAULT_Q_LIMIT;
8032 bm->outq_limit = BM_DEFAULT_Q_LIMIT;
8033
8034 bgp_mac_init();
8035 /* init the rd id space.
8036 assign 0th index in the bitfield,
8037 so that we start with id 1
8038 */
8039 bf_init(bm->rd_idspace, UINT16_MAX);
8040 bf_assign_zero_index(bm->rd_idspace);
8041
8042 /* mpls label dynamic allocation pool */
8043 bgp_lp_init(bm->master, &bm->labelpool);
8044
8045 bgp_l3nhg_init();
8046 bgp_evpn_mh_init();
8047 QOBJ_REG(bm, bgp_master);
8048 }
8049
8050 /*
8051 * Free up connected routes and interfaces for a BGP instance. Invoked upon
8052 * instance delete (non-default only) or BGP exit.
8053 */
8054 static void bgp_if_finish(struct bgp *bgp)
8055 {
8056 struct vrf *vrf;
8057 struct interface *ifp;
8058
8059 vrf = bgp_vrf_lookup_by_instance_type(bgp);
8060
8061 if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW || !vrf)
8062 return;
8063
8064 FOR_ALL_INTERFACES (vrf, ifp) {
8065 struct listnode *c_node, *c_nnode;
8066 struct connected *c;
8067
8068 for (ALL_LIST_ELEMENTS(ifp->connected, c_node, c_nnode, c))
8069 bgp_connected_delete(bgp, c);
8070 }
8071 }
8072
8073 static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
8074 {
8075 struct vrf *vrf = NULL;
8076 struct listnode *next;
8077 struct bgp *bgp;
8078
8079 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
8080 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
8081
8082 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
8083 if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
8084 continue;
8085
8086 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bgp->name));
8087 }
8088 }
8089
8090 static void bgp_instasn_autocomplete(vector comps, struct cmd_token *token)
8091 {
8092 struct listnode *next, *next2;
8093 struct bgp *bgp, *bgp2;
8094 char buf[ASN_STRING_MAX_SIZE];
8095
8096 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
8097 /* deduplicate */
8098 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next2, bgp2)) {
8099 if (bgp2->as == bgp->as)
8100 break;
8101 if (bgp2 == bgp)
8102 break;
8103 }
8104 if (bgp2 != bgp)
8105 continue;
8106
8107 snprintf(buf, sizeof(buf), "%s", bgp->as_pretty);
8108 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, buf));
8109 }
8110 }
8111
8112 static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = {
8113 {.tokenname = "VIEWVRFNAME", .completions = bgp_viewvrf_autocomplete},
8114 {.varname = "instasn", .completions = bgp_instasn_autocomplete},
8115 {.completions = NULL},
8116 };
8117
8118 struct frr_pthread *bgp_pth_io;
8119 struct frr_pthread *bgp_pth_ka;
8120
8121 static void bgp_pthreads_init(void)
8122 {
8123 assert(!bgp_pth_io);
8124 assert(!bgp_pth_ka);
8125
8126 struct frr_pthread_attr io = {
8127 .start = frr_pthread_attr_default.start,
8128 .stop = frr_pthread_attr_default.stop,
8129 };
8130 struct frr_pthread_attr ka = {
8131 .start = bgp_keepalives_start,
8132 .stop = bgp_keepalives_stop,
8133 };
8134 bgp_pth_io = frr_pthread_new(&io, "BGP I/O thread", "bgpd_io");
8135 bgp_pth_ka = frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
8136 }
8137
8138 void bgp_pthreads_run(void)
8139 {
8140 frr_pthread_run(bgp_pth_io, NULL);
8141 frr_pthread_run(bgp_pth_ka, NULL);
8142
8143 /* Wait until threads are ready. */
8144 frr_pthread_wait_running(bgp_pth_io);
8145 frr_pthread_wait_running(bgp_pth_ka);
8146 }
8147
8148 void bgp_pthreads_finish(void)
8149 {
8150 frr_pthread_stop_all();
8151 }
8152
8153 static int peer_unshut_after_cfg(struct bgp *bgp)
8154 {
8155 struct listnode *node;
8156 struct peer *peer;
8157
8158 for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
8159 if (!peer->shut_during_cfg)
8160 continue;
8161
8162 if (bgp_debug_neighbor_events(peer))
8163 zlog_debug("%s: released from config-pending hold",
8164 peer->host);
8165
8166 peer->shut_during_cfg = false;
8167 if (peer_active(peer) && peer->status != Established) {
8168 if (peer->status != Idle)
8169 BGP_EVENT_ADD(peer, BGP_Stop);
8170 BGP_EVENT_ADD(peer, BGP_Start);
8171 }
8172 }
8173
8174 return 0;
8175 }
8176
8177 void bgp_init(unsigned short instance)
8178 {
8179 hook_register(bgp_config_end, peer_unshut_after_cfg);
8180
8181 /* allocates some vital data structures used by peer commands in
8182 * vty_init */
8183
8184 /* pre-init pthreads */
8185 bgp_pthreads_init();
8186
8187 /* Init zebra. */
8188 bgp_zebra_init(bm->master, instance);
8189
8190 #ifdef ENABLE_BGP_VNC
8191 vnc_zebra_init(bm->master);
8192 #endif
8193
8194 /* BGP VTY commands installation. */
8195 bgp_vty_init();
8196
8197 /* BGP inits. */
8198 bgp_attr_init();
8199 bgp_debug_init();
8200 bgp_community_alias_init();
8201 bgp_dump_init();
8202 bgp_route_init();
8203 bgp_route_map_init();
8204 bgp_scan_vty_init();
8205 bgp_mplsvpn_init();
8206 #ifdef ENABLE_BGP_VNC
8207 rfapi_init();
8208 #endif
8209 bgp_ethernetvpn_init();
8210 bgp_flowspec_vty_init();
8211
8212 /* Access list initialize. */
8213 access_list_init();
8214 access_list_add_hook(peer_distribute_update);
8215 access_list_delete_hook(peer_distribute_update);
8216
8217 /* Filter list initialize. */
8218 bgp_filter_init();
8219 as_list_add_hook(peer_aslist_add);
8220 as_list_delete_hook(peer_aslist_del);
8221
8222 /* Prefix list initialize.*/
8223 prefix_list_init();
8224 prefix_list_add_hook(peer_prefix_list_update);
8225 prefix_list_delete_hook(peer_prefix_list_update);
8226
8227 /* Community list initialize. */
8228 bgp_clist = community_list_init();
8229
8230 /* BFD init */
8231 bgp_bfd_init(bm->master);
8232
8233 bgp_lp_vty_init();
8234
8235 cmd_variable_handler_register(bgp_viewvrf_var_handlers);
8236 }
8237
8238 void bgp_terminate(void)
8239 {
8240 struct bgp *bgp;
8241 struct peer *peer;
8242 struct listnode *node, *nnode;
8243 struct listnode *mnode, *mnnode;
8244
8245 QOBJ_UNREG(bm);
8246
8247 /* Close the listener sockets first as this prevents peers from
8248 * attempting
8249 * to reconnect on receiving the peer unconfig message. In the presence
8250 * of a large number of peers this will ensure that no peer is left with
8251 * a dangling connection
8252 */
8253
8254 bgp_close();
8255 /* reverse bgp_master_init */
8256 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
8257 bgp_close_vrf_socket(bgp);
8258 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8259 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
8260 if (bgp_debug_neighbor_events(peer))
8261 zlog_debug(
8262 "%pBP configured Graceful-Restart, skipping unconfig notification",
8263 peer);
8264 continue;
8265 }
8266 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
8267 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
8268 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
8269 }
8270 }
8271
8272 if (bm->listen_sockets)
8273 list_delete(&bm->listen_sockets);
8274
8275 THREAD_OFF(bm->t_rmap_update);
8276
8277 bgp_mac_finish();
8278 }
8279
8280 struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
8281 const char *ip_str, bool use_json)
8282 {
8283 int ret;
8284 struct peer *peer;
8285 union sockunion su;
8286
8287 /* Get peer sockunion. */
8288 ret = str2sockunion(ip_str, &su);
8289 if (ret < 0) {
8290 peer = peer_lookup_by_conf_if(bgp, ip_str);
8291 if (!peer) {
8292 peer = peer_lookup_by_hostname(bgp, ip_str);
8293
8294 if (!peer) {
8295 if (use_json) {
8296 json_object *json_no = NULL;
8297 json_no = json_object_new_object();
8298 json_object_string_add(
8299 json_no,
8300 "malformedAddressOrName",
8301 ip_str);
8302 vty_json(vty, json_no);
8303 } else
8304 vty_out(vty,
8305 "%% Malformed address or name: %s\n",
8306 ip_str);
8307 return NULL;
8308 }
8309 }
8310 return peer;
8311 }
8312
8313 /* Peer structure lookup. */
8314 peer = peer_lookup(bgp, &su);
8315 if (!peer) {
8316 if (use_json) {
8317 json_object *json_no = NULL;
8318 json_no = json_object_new_object();
8319 json_object_string_add(json_no, "warning",
8320 "No such neighbor in this view/vrf");
8321 vty_json(vty, json_no);
8322 } else
8323 vty_out(vty, "No such neighbor in this view/vrf\n");
8324 return NULL;
8325 }
8326
8327 return peer;
8328 }
8329
8330 void bgp_gr_apply_running_config(void)
8331 {
8332 struct peer *peer = NULL;
8333 struct bgp *bgp = NULL;
8334 struct listnode *node, *nnode;
8335 bool gr_router_detected = false;
8336
8337 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
8338 zlog_debug("[BGP_GR] %s called !", __func__);
8339
8340 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
8341 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8342 bgp_peer_gr_flags_update(peer);
8343 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART))
8344 gr_router_detected = true;
8345 }
8346
8347 if (gr_router_detected
8348 && bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
8349 bgp_zebra_send_capabilities(bgp, true);
8350 } else if (!gr_router_detected
8351 && bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
8352 bgp_zebra_send_capabilities(bgp, false);
8353 }
8354
8355 gr_router_detected = false;
8356 }
8357 }
8358
8359 printfrr_ext_autoreg_p("BP", printfrr_bp);
8360 static ssize_t printfrr_bp(struct fbuf *buf, struct printfrr_eargs *ea,
8361 const void *ptr)
8362 {
8363 const struct peer *peer = ptr;
8364
8365 if (!peer)
8366 return bputs(buf, "(null)");
8367
8368 return bprintfrr(buf, "%s(%s)", peer->host,
8369 peer->hostname ? peer->hostname : "Unknown");
8370 }