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