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