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