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