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