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