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