]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgpd.c
Merge pull request #5464 from qlyoung/fix-bgp-prefix-orf-heap-overflow
[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 bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED;
2994 #if DFLT_BGP_IMPORT_CHECK
2995 bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
2996 #endif
2997 #if DFLT_BGP_SHOW_HOSTNAME
2998 bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
2999 #endif
3000 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
3001 bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
3002 #endif
3003 #if DFLT_BGP_DETERMINISTIC_MED
3004 bgp_flag_set(bgp, BGP_FLAG_DETERMINISTIC_MED);
3005 #endif
3006 bgp_addpath_init_bgp_data(&bgp->tx_addpath);
3007
3008 bgp->as = *as;
3009
3010 #if ENABLE_BGP_VNC
3011 if (inst_type != BGP_INSTANCE_TYPE_VRF) {
3012 bgp->rfapi = bgp_rfapi_new(bgp);
3013 assert(bgp->rfapi);
3014 assert(bgp->rfapi_cfg);
3015 }
3016 #endif /* ENABLE_BGP_VNC */
3017
3018 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3019 bgp->vpn_policy[afi].bgp = bgp;
3020 bgp->vpn_policy[afi].afi = afi;
3021 bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
3022 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent =
3023 MPLS_LABEL_NONE;
3024
3025 bgp->vpn_policy[afi].import_vrf = list_new();
3026 bgp->vpn_policy[afi].import_vrf->del =
3027 bgp_vrf_string_name_delete;
3028 bgp->vpn_policy[afi].export_vrf = list_new();
3029 bgp->vpn_policy[afi].export_vrf->del =
3030 bgp_vrf_string_name_delete;
3031 }
3032 if (name) {
3033 bgp->name = XSTRDUP(MTYPE_BGP, name);
3034 } else {
3035 /* TODO - The startup timer needs to be run for the whole of BGP
3036 */
3037 thread_add_timer(bm->master, bgp_startup_timer_expire, bgp,
3038 bgp->restart_time, &bgp->t_startup);
3039 }
3040
3041 /* printable name we can use in debug messages */
3042 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
3043 bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
3044 } else {
3045 const char *n;
3046 int len;
3047
3048 if (bgp->name)
3049 n = bgp->name;
3050 else
3051 n = "?";
3052
3053 len = 4 + 1 + strlen(n) + 1; /* "view foo\0" */
3054
3055 bgp->name_pretty = XCALLOC(MTYPE_BGP, len);
3056 snprintf(bgp->name_pretty, len, "%s %s",
3057 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3058 ? "VRF"
3059 : "VIEW",
3060 n);
3061 }
3062
3063 atomic_store_explicit(&bgp->wpkt_quanta, BGP_WRITE_PACKET_MAX,
3064 memory_order_relaxed);
3065 atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
3066 memory_order_relaxed);
3067 bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
3068
3069 QOBJ_REG(bgp, bgp);
3070
3071 update_bgp_group_init(bgp);
3072
3073 /* assign a unique rd id for auto derivation of vrf's RD */
3074 bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
3075
3076 bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO,
3077 sizeof(struct bgp_evpn_info));
3078
3079 bgp_evpn_init(bgp);
3080 bgp_pbr_init(bgp);
3081 return bgp;
3082 }
3083
3084 /* Return the "default VRF" instance of BGP. */
3085 struct bgp *bgp_get_default(void)
3086 {
3087 struct bgp *bgp;
3088 struct listnode *node, *nnode;
3089
3090 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3091 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3092 return bgp;
3093 return NULL;
3094 }
3095
3096 /* Lookup BGP entry. */
3097 struct bgp *bgp_lookup(as_t as, const char *name)
3098 {
3099 struct bgp *bgp;
3100 struct listnode *node, *nnode;
3101
3102 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3103 if (bgp->as == as
3104 && ((bgp->name == NULL && name == NULL)
3105 || (bgp->name && name && strcmp(bgp->name, name) == 0)))
3106 return bgp;
3107 return NULL;
3108 }
3109
3110 /* Lookup BGP structure by view name. */
3111 struct bgp *bgp_lookup_by_name(const char *name)
3112 {
3113 struct bgp *bgp;
3114 struct listnode *node, *nnode;
3115
3116 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3117 if ((bgp->name == NULL && name == NULL)
3118 || (bgp->name && name && strcmp(bgp->name, name) == 0))
3119 return bgp;
3120 return NULL;
3121 }
3122
3123 /* Lookup BGP instance based on VRF id. */
3124 /* Note: Only to be used for incoming messages from Zebra. */
3125 struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
3126 {
3127 struct vrf *vrf;
3128
3129 /* Lookup VRF (in tree) and follow link. */
3130 vrf = vrf_lookup_by_id(vrf_id);
3131 if (!vrf)
3132 return NULL;
3133 return (vrf->info) ? (struct bgp *)vrf->info : NULL;
3134 }
3135
3136 /* Sets the BGP instance where EVPN is enabled */
3137 void bgp_set_evpn(struct bgp *bgp)
3138 {
3139 if (bm->bgp_evpn == bgp)
3140 return;
3141
3142 /* First, release the reference count we hold on the instance */
3143 if (bm->bgp_evpn)
3144 bgp_unlock(bm->bgp_evpn);
3145
3146 bm->bgp_evpn = bgp;
3147
3148 /* Increase the reference count on this new VRF */
3149 if (bm->bgp_evpn)
3150 bgp_lock(bm->bgp_evpn);
3151 }
3152
3153 /* Returns the BGP instance where EVPN is enabled, if any */
3154 struct bgp *bgp_get_evpn(void)
3155 {
3156 return bm->bgp_evpn;
3157 }
3158
3159 /* handle socket creation or deletion, if necessary
3160 * this is called for all new BGP instances
3161 */
3162 int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
3163 bool create)
3164 {
3165 int ret = 0;
3166
3167 /* Create BGP server socket, if listen mode not disabled */
3168 if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
3169 return 0;
3170 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3171 /*
3172 * suppress vrf socket
3173 */
3174 if (create == false) {
3175 bgp_close_vrf_socket(bgp);
3176 return 0;
3177 }
3178 if (vrf == NULL)
3179 return BGP_ERR_INVALID_VALUE;
3180 /* do nothing
3181 * if vrf_id did not change
3182 */
3183 if (vrf->vrf_id == old_vrf_id)
3184 return 0;
3185 if (old_vrf_id != VRF_UNKNOWN) {
3186 /* look for old socket. close it. */
3187 bgp_close_vrf_socket(bgp);
3188 }
3189 /* if backend is not yet identified ( VRF_UNKNOWN) then
3190 * creation will be done later
3191 */
3192 if (vrf->vrf_id == VRF_UNKNOWN)
3193 return 0;
3194 ret = bgp_socket(bgp, bm->port, bm->address);
3195 if (ret < 0)
3196 return BGP_ERR_INVALID_VALUE;
3197 return 0;
3198 } else
3199 return bgp_check_main_socket(create, bgp);
3200 }
3201
3202 /* Called from VTY commands. */
3203 int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
3204 enum bgp_instance_type inst_type)
3205 {
3206 struct bgp *bgp;
3207 struct vrf *vrf = NULL;
3208
3209 /* Multiple instance check. */
3210 if (name)
3211 bgp = bgp_lookup_by_name(name);
3212 else
3213 bgp = bgp_get_default();
3214
3215 /* Already exists. */
3216 if (bgp) {
3217 if (bgp->as != *as) {
3218 *as = bgp->as;
3219 return BGP_ERR_INSTANCE_MISMATCH;
3220 }
3221 if (bgp->inst_type != inst_type)
3222 return BGP_ERR_INSTANCE_MISMATCH;
3223 *bgp_val = bgp;
3224 return BGP_SUCCESS;
3225 }
3226
3227 bgp = bgp_create(as, name, inst_type);
3228 if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name)
3229 bgp->vrf_id = vrf_generate_id();
3230 bgp_router_id_set(bgp, &bgp->router_id_zebra, true);
3231 bgp_address_init(bgp);
3232 bgp_tip_hash_init(bgp);
3233 bgp_scan_init(bgp);
3234 *bgp_val = bgp;
3235
3236 bgp->t_rmap_def_originate_eval = NULL;
3237
3238 /* If Default instance or VRF, link to the VRF structure, if present. */
3239 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
3240 || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3241 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3242 if (vrf)
3243 bgp_vrf_link(bgp, vrf);
3244 }
3245 /* BGP server socket already processed if BGP instance
3246 * already part of the list
3247 */
3248 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, true);
3249 listnode_add(bm->bgp, bgp);
3250
3251 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3252 if (BGP_DEBUG(zebra, ZEBRA))
3253 zlog_debug("%s: Registering BGP instance %s to zebra",
3254 __PRETTY_FUNCTION__, name);
3255 bgp_zebra_instance_register(bgp);
3256 }
3257
3258 return BGP_SUCCESS;
3259 }
3260
3261 /*
3262 * Make BGP instance "up". Applies only to VRFs (non-default) and
3263 * implies the VRF has been learnt from Zebra.
3264 */
3265 void bgp_instance_up(struct bgp *bgp)
3266 {
3267 struct peer *peer;
3268 struct listnode *node, *next;
3269
3270 /* Register with zebra. */
3271 bgp_zebra_instance_register(bgp);
3272
3273 /* Kick off any peers that may have been configured. */
3274 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3275 if (!BGP_PEER_START_SUPPRESSED(peer))
3276 BGP_EVENT_ADD(peer, BGP_Start);
3277 }
3278
3279 /* Process any networks that have been configured. */
3280 bgp_static_add(bgp);
3281 }
3282
3283 /*
3284 * Make BGP instance "down". Applies only to VRFs (non-default) and
3285 * implies the VRF has been deleted by Zebra.
3286 */
3287 void bgp_instance_down(struct bgp *bgp)
3288 {
3289 struct peer *peer;
3290 struct listnode *node;
3291 struct listnode *next;
3292
3293 /* Stop timers. */
3294 if (bgp->t_rmap_def_originate_eval) {
3295 BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
3296 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3297 why? */
3298 }
3299
3300 /* Bring down peers, so corresponding routes are purged. */
3301 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3302 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3303 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3304 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3305 else
3306 bgp_session_reset(peer);
3307 }
3308
3309 /* Purge network and redistributed routes. */
3310 bgp_purge_static_redist_routes(bgp);
3311
3312 /* Cleanup registered nexthops (flags) */
3313 bgp_cleanup_nexthops(bgp);
3314 }
3315
3316 /* Delete BGP instance. */
3317 int bgp_delete(struct bgp *bgp)
3318 {
3319 struct peer *peer;
3320 struct peer_group *group;
3321 struct listnode *node, *next;
3322 struct vrf *vrf;
3323 afi_t afi;
3324 int i;
3325
3326 assert(bgp);
3327
3328 hook_call(bgp_inst_delete, bgp);
3329
3330 THREAD_OFF(bgp->t_startup);
3331 THREAD_OFF(bgp->t_maxmed_onstartup);
3332 THREAD_OFF(bgp->t_update_delay);
3333 THREAD_OFF(bgp->t_establish_wait);
3334
3335 /* Set flag indicating bgp instance delete in progress */
3336 bgp_flag_set(bgp, BGP_FLAG_DELETE_IN_PROGRESS);
3337
3338 if (BGP_DEBUG(zebra, ZEBRA)) {
3339 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3340 zlog_debug("Deleting Default VRF");
3341 else
3342 zlog_debug("Deleting %s %s",
3343 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3344 ? "VRF"
3345 : "VIEW",
3346 bgp->name);
3347 }
3348
3349 /* unmap from RT list */
3350 bgp_evpn_vrf_delete(bgp);
3351
3352 /* unmap bgp vrf label */
3353 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
3354 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
3355
3356 /* Stop timers. */
3357 if (bgp->t_rmap_def_originate_eval) {
3358 BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
3359 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3360 why? */
3361 }
3362
3363 /* Inform peers we're going down. */
3364 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3365 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3366 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3367 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3368 }
3369
3370 /* Delete static routes (networks). */
3371 bgp_static_delete(bgp);
3372
3373 /* Unset redistribution. */
3374 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3375 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3376 if (i != ZEBRA_ROUTE_BGP)
3377 bgp_redistribute_unset(bgp, afi, i, 0);
3378
3379 /* Free peers and peer-groups. */
3380 for (ALL_LIST_ELEMENTS(bgp->group, node, next, group))
3381 peer_group_delete(group);
3382
3383 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
3384 peer_delete(peer);
3385
3386 if (bgp->peer_self) {
3387 peer_delete(bgp->peer_self);
3388 bgp->peer_self = NULL;
3389 }
3390
3391 update_bgp_group_free(bgp);
3392
3393 /* TODO - Other memory may need to be freed - e.g., NHT */
3394
3395 #if ENABLE_BGP_VNC
3396 rfapi_delete(bgp);
3397 #endif
3398 bgp_cleanup_routes(bgp);
3399
3400 for (afi = 0; afi < AFI_MAX; ++afi) {
3401 if (!bgp->vpn_policy[afi].import_redirect_rtlist)
3402 continue;
3403 ecommunity_free(
3404 &bgp->vpn_policy[afi]
3405 .import_redirect_rtlist);
3406 bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
3407 }
3408
3409 /* Deregister from Zebra, if needed */
3410 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3411 if (BGP_DEBUG(zebra, ZEBRA))
3412 zlog_debug("%s: deregistering this bgp %s instance from zebra",
3413 __PRETTY_FUNCTION__, bgp->name);
3414 bgp_zebra_instance_deregister(bgp);
3415 }
3416
3417 /* Remove visibility via the master list - there may however still be
3418 * routes to be processed still referencing the struct bgp.
3419 */
3420 listnode_delete(bm->bgp, bgp);
3421
3422 /* Free interfaces in this instance. */
3423 bgp_if_finish(bgp);
3424
3425 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3426 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
3427 if (vrf)
3428 bgp_vrf_unlink(bgp, vrf);
3429
3430 /* Update EVPN VRF pointer */
3431 if (bm->bgp_evpn == bgp) {
3432 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3433 bgp_set_evpn(NULL);
3434 else
3435 bgp_set_evpn(bgp_get_default());
3436 }
3437
3438 thread_master_free_unused(bm->master);
3439 bgp_unlock(bgp); /* initial reference */
3440
3441 return 0;
3442 }
3443
3444 void bgp_free(struct bgp *bgp)
3445 {
3446 afi_t afi;
3447 safi_t safi;
3448 struct bgp_table *table;
3449 struct bgp_node *rn;
3450 struct bgp_rmap *rmap;
3451
3452 QOBJ_UNREG(bgp);
3453
3454 list_delete(&bgp->group);
3455 list_delete(&bgp->peer);
3456
3457 if (bgp->peerhash) {
3458 hash_free(bgp->peerhash);
3459 bgp->peerhash = NULL;
3460 }
3461
3462 FOREACH_AFI_SAFI (afi, safi) {
3463 /* Special handling for 2-level routing tables. */
3464 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
3465 || safi == SAFI_EVPN) {
3466 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
3467 rn = bgp_route_next(rn)) {
3468 table = bgp_node_get_bgp_table_info(rn);
3469 bgp_table_finish(&table);
3470 }
3471 }
3472 if (bgp->route[afi][safi])
3473 bgp_table_finish(&bgp->route[afi][safi]);
3474 if (bgp->aggregate[afi][safi])
3475 bgp_table_finish(&bgp->aggregate[afi][safi]);
3476 if (bgp->rib[afi][safi])
3477 bgp_table_finish(&bgp->rib[afi][safi]);
3478 rmap = &bgp->table_map[afi][safi];
3479 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
3480 }
3481
3482 bgp_scan_finish(bgp);
3483 bgp_address_destroy(bgp);
3484 bgp_tip_hash_destroy(bgp);
3485
3486 /* release the auto RD id */
3487 bf_release_index(bm->rd_idspace, bgp->vrf_rd_id);
3488
3489 bgp_evpn_cleanup(bgp);
3490 bgp_pbr_cleanup(bgp);
3491 XFREE(MTYPE_BGP_EVPN_INFO, bgp->evpn_info);
3492
3493 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3494 vpn_policy_direction_t dir;
3495
3496 if (bgp->vpn_policy[afi].import_vrf)
3497 list_delete(&bgp->vpn_policy[afi].import_vrf);
3498 if (bgp->vpn_policy[afi].export_vrf)
3499 list_delete(&bgp->vpn_policy[afi].export_vrf);
3500
3501 dir = BGP_VPN_POLICY_DIR_FROMVPN;
3502 if (bgp->vpn_policy[afi].rtlist[dir])
3503 ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3504 dir = BGP_VPN_POLICY_DIR_TOVPN;
3505 if (bgp->vpn_policy[afi].rtlist[dir])
3506 ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3507 }
3508
3509 XFREE(MTYPE_BGP, bgp->name);
3510 XFREE(MTYPE_BGP, bgp->name_pretty);
3511
3512 XFREE(MTYPE_BGP, bgp);
3513 }
3514
3515 struct peer *peer_lookup_by_conf_if(struct bgp *bgp, const char *conf_if)
3516 {
3517 struct peer *peer;
3518 struct listnode *node, *nnode;
3519
3520 if (!conf_if)
3521 return NULL;
3522
3523 if (bgp != NULL) {
3524 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3525 if (peer->conf_if && !strcmp(peer->conf_if, conf_if)
3526 && !CHECK_FLAG(peer->sflags,
3527 PEER_STATUS_ACCEPT_PEER))
3528 return peer;
3529 } else if (bm->bgp != NULL) {
3530 struct listnode *bgpnode, *nbgpnode;
3531
3532 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3533 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3534 if (peer->conf_if
3535 && !strcmp(peer->conf_if, conf_if)
3536 && !CHECK_FLAG(peer->sflags,
3537 PEER_STATUS_ACCEPT_PEER))
3538 return peer;
3539 }
3540 return NULL;
3541 }
3542
3543 struct peer *peer_lookup_by_hostname(struct bgp *bgp, const char *hostname)
3544 {
3545 struct peer *peer;
3546 struct listnode *node, *nnode;
3547
3548 if (!hostname)
3549 return NULL;
3550
3551 if (bgp != NULL) {
3552 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3553 if (peer->hostname && !strcmp(peer->hostname, hostname)
3554 && !CHECK_FLAG(peer->sflags,
3555 PEER_STATUS_ACCEPT_PEER))
3556 return peer;
3557 } else if (bm->bgp != NULL) {
3558 struct listnode *bgpnode, *nbgpnode;
3559
3560 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3561 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3562 if (peer->hostname
3563 && !strcmp(peer->hostname, hostname)
3564 && !CHECK_FLAG(peer->sflags,
3565 PEER_STATUS_ACCEPT_PEER))
3566 return peer;
3567 }
3568 return NULL;
3569 }
3570
3571 struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
3572 {
3573 struct peer *peer = NULL;
3574 struct peer tmp_peer;
3575
3576 memset(&tmp_peer, 0, sizeof(struct peer));
3577
3578 /*
3579 * We do not want to find the doppelganger peer so search for the peer
3580 * in
3581 * the hash that has PEER_FLAG_CONFIG_NODE
3582 */
3583 SET_FLAG(tmp_peer.flags, PEER_FLAG_CONFIG_NODE);
3584
3585 tmp_peer.su = *su;
3586
3587 if (bgp != NULL) {
3588 peer = hash_lookup(bgp->peerhash, &tmp_peer);
3589 } else if (bm->bgp != NULL) {
3590 struct listnode *bgpnode, *nbgpnode;
3591
3592 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp)) {
3593 peer = hash_lookup(bgp->peerhash, &tmp_peer);
3594 if (peer)
3595 break;
3596 }
3597 }
3598
3599 return peer;
3600 }
3601
3602 struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
3603 union sockunion *su,
3604 struct peer_group *group)
3605 {
3606 struct peer *peer;
3607 afi_t afi;
3608 safi_t safi;
3609
3610 /* Create peer first; we've already checked group config is valid. */
3611 peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
3612 group->conf->as_type, 0, 0, group);
3613 if (!peer)
3614 return NULL;
3615
3616 /* Link to group */
3617 peer = peer_lock(peer);
3618 listnode_add(group->peer, peer);
3619
3620 peer_group2peer_config_copy(group, peer);
3621
3622 /*
3623 * Bind peer for all AFs configured for the group. We don't call
3624 * peer_group_bind as that is sub-optimal and does some stuff we don't
3625 * want.
3626 */
3627 FOREACH_AFI_SAFI (afi, safi) {
3628 if (!group->conf->afc[afi][safi])
3629 continue;
3630 peer->afc[afi][safi] = 1;
3631
3632 if (!peer_af_find(peer, afi, safi))
3633 peer_af_create(peer, afi, safi);
3634
3635 peer_group2peer_config_copy_af(group, peer, afi, safi);
3636 }
3637
3638 /* Mark as dynamic, but also as a "config node" for other things to
3639 * work. */
3640 SET_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR);
3641 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
3642
3643 return peer;
3644 }
3645
3646 struct prefix *
3647 peer_group_lookup_dynamic_neighbor_range(struct peer_group *group,
3648 struct prefix *prefix)
3649 {
3650 struct listnode *node, *nnode;
3651 struct prefix *range;
3652 afi_t afi;
3653
3654 afi = family2afi(prefix->family);
3655
3656 if (group->listen_range[afi])
3657 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
3658 range))
3659 if (prefix_match(range, prefix))
3660 return range;
3661
3662 return NULL;
3663 }
3664
3665 struct peer_group *
3666 peer_group_lookup_dynamic_neighbor(struct bgp *bgp, struct prefix *prefix,
3667 struct prefix **listen_range)
3668 {
3669 struct prefix *range = NULL;
3670 struct peer_group *group = NULL;
3671 struct listnode *node, *nnode;
3672
3673 *listen_range = NULL;
3674 if (bgp != NULL) {
3675 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
3676 if ((range = peer_group_lookup_dynamic_neighbor_range(
3677 group, prefix)))
3678 break;
3679 } else if (bm->bgp != NULL) {
3680 struct listnode *bgpnode, *nbgpnode;
3681
3682 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3683 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
3684 if ((range = peer_group_lookup_dynamic_neighbor_range(
3685 group, prefix)))
3686 goto found_range;
3687 }
3688
3689 found_range:
3690 *listen_range = range;
3691 return (group && range) ? group : NULL;
3692 }
3693
3694 struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
3695 {
3696 struct peer_group *group;
3697 struct bgp *gbgp;
3698 struct peer *peer;
3699 struct prefix prefix;
3700 struct prefix *listen_range;
3701 int dncount;
3702 char buf[PREFIX2STR_BUFFER];
3703 char buf1[PREFIX2STR_BUFFER];
3704
3705 sockunion2hostprefix(su, &prefix);
3706
3707 /* See if incoming connection matches a configured listen range. */
3708 group = peer_group_lookup_dynamic_neighbor(bgp, &prefix, &listen_range);
3709
3710 if (!group)
3711 return NULL;
3712
3713
3714 gbgp = group->bgp;
3715
3716 if (!gbgp)
3717 return NULL;
3718
3719 prefix2str(&prefix, buf, sizeof(buf));
3720 prefix2str(listen_range, buf1, sizeof(buf1));
3721
3722 if (bgp_debug_neighbor_events(NULL))
3723 zlog_debug(
3724 "Dynamic Neighbor %s matches group %s listen range %s",
3725 buf, group->name, buf1);
3726
3727 /* Are we within the listen limit? */
3728 dncount = gbgp->dynamic_neighbors_count;
3729
3730 if (dncount >= gbgp->dynamic_neighbors_limit) {
3731 if (bgp_debug_neighbor_events(NULL))
3732 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3733 inet_sutop(su, buf),
3734 gbgp->dynamic_neighbors_limit);
3735 return NULL;
3736 }
3737
3738 /* Ensure group is not disabled. */
3739 if (CHECK_FLAG(group->conf->flags, PEER_FLAG_SHUTDOWN)) {
3740 if (bgp_debug_neighbor_events(NULL))
3741 zlog_debug(
3742 "Dynamic Neighbor %s rejected - group %s disabled",
3743 buf, group->name);
3744 return NULL;
3745 }
3746
3747 /* Check that at least one AF is activated for the group. */
3748 if (!peer_group_af_configured(group)) {
3749 if (bgp_debug_neighbor_events(NULL))
3750 zlog_debug(
3751 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3752 buf, group->name);
3753 return NULL;
3754 }
3755
3756 /* Create dynamic peer and bind to associated group. */
3757 peer = peer_create_bind_dynamic_neighbor(gbgp, su, group);
3758 assert(peer);
3759
3760 gbgp->dynamic_neighbors_count = ++dncount;
3761
3762 if (bgp_debug_neighbor_events(peer))
3763 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3764 peer->host, group->name, dncount);
3765
3766 return peer;
3767 }
3768
3769 static void peer_drop_dynamic_neighbor(struct peer *peer)
3770 {
3771 int dncount = -1;
3772 if (peer->group->bgp) {
3773 dncount = peer->group->bgp->dynamic_neighbors_count;
3774 if (dncount)
3775 peer->group->bgp->dynamic_neighbors_count = --dncount;
3776 }
3777 if (bgp_debug_neighbor_events(peer))
3778 zlog_debug("%s dropped from group %s, count %d", peer->host,
3779 peer->group->name, dncount);
3780 }
3781
3782 /* If peer is configured at least one address family return 1. */
3783 int peer_active(struct peer *peer)
3784 {
3785 if (BGP_PEER_SU_UNSPEC(peer))
3786 return 0;
3787 if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
3788 || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
3789 || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
3790 || peer->afc[AFI_IP][SAFI_FLOWSPEC]
3791 || peer->afc[AFI_IP6][SAFI_UNICAST]
3792 || peer->afc[AFI_IP6][SAFI_MULTICAST]
3793 || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
3794 || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
3795 || peer->afc[AFI_IP6][SAFI_ENCAP]
3796 || peer->afc[AFI_IP6][SAFI_FLOWSPEC]
3797 || peer->afc[AFI_L2VPN][SAFI_EVPN])
3798 return 1;
3799 return 0;
3800 }
3801
3802 /* If peer is negotiated at least one address family return 1. */
3803 int peer_active_nego(struct peer *peer)
3804 {
3805 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
3806 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
3807 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
3808 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
3809 || peer->afc_nego[AFI_IP][SAFI_ENCAP]
3810 || peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
3811 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
3812 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
3813 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
3814 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
3815 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]
3816 || peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
3817 || peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
3818 return 1;
3819 return 0;
3820 }
3821
3822 void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
3823 enum peer_change_type type)
3824 {
3825 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
3826 return;
3827
3828 if (peer->status != Established)
3829 return;
3830
3831 if (type == peer_change_reset) {
3832 /* If we're resetting session, we've to delete both peer struct
3833 */
3834 if ((peer->doppelganger)
3835 && (peer->doppelganger->status != Deleted)
3836 && (!CHECK_FLAG(peer->doppelganger->flags,
3837 PEER_FLAG_CONFIG_NODE)))
3838 peer_delete(peer->doppelganger);
3839
3840 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3841 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3842 } else if (type == peer_change_reset_in) {
3843 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
3844 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
3845 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0);
3846 else {
3847 if ((peer->doppelganger)
3848 && (peer->doppelganger->status != Deleted)
3849 && (!CHECK_FLAG(peer->doppelganger->flags,
3850 PEER_FLAG_CONFIG_NODE)))
3851 peer_delete(peer->doppelganger);
3852
3853 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3854 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3855 }
3856 } else if (type == peer_change_reset_out) {
3857 update_group_adjust_peer(peer_af_find(peer, afi, safi));
3858 bgp_announce_route(peer, afi, safi);
3859 }
3860 }
3861
3862 struct peer_flag_action {
3863 /* Peer's flag. */
3864 uint32_t flag;
3865
3866 /* This flag can be set for peer-group member. */
3867 uint8_t not_for_member;
3868
3869 /* Action when the flag is changed. */
3870 enum peer_change_type type;
3871 };
3872
3873 static const struct peer_flag_action peer_flag_action_list[] = {
3874 {PEER_FLAG_PASSIVE, 0, peer_change_reset},
3875 {PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
3876 {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
3877 {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
3878 {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
3879 {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset},
3880 {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset},
3881 {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset},
3882 {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in},
3883 {PEER_FLAG_IFPEER_V6ONLY, 0, peer_change_reset},
3884 {PEER_FLAG_ROUTEADV, 0, peer_change_none},
3885 {PEER_FLAG_TIMER, 0, peer_change_none},
3886 {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
3887 {PEER_FLAG_PASSWORD, 0, peer_change_none},
3888 {PEER_FLAG_LOCAL_AS, 0, peer_change_none},
3889 {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none},
3890 {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_none},
3891 {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none},
3892 {0, 0, 0}};
3893
3894 static const struct peer_flag_action peer_af_flag_action_list[] = {
3895 {PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out},
3896 {PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out},
3897 {PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out},
3898 {PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out},
3899 {PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset},
3900 {PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset},
3901 {PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in},
3902 {PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out},
3903 {PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out},
3904 {PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out},
3905 {PEER_FLAG_DEFAULT_ORIGINATE, 0, peer_change_none},
3906 {PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out},
3907 {PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in},
3908 {PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in},
3909 {PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset},
3910 {PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset},
3911 {PEER_FLAG_MAX_PREFIX, 0, peer_change_none},
3912 {PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none},
3913 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out},
3914 {PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out},
3915 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out},
3916 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out},
3917 {PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out},
3918 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out},
3919 {PEER_FLAG_WEIGHT, 0, peer_change_reset_in},
3920 {0, 0, 0}};
3921
3922 /* Proper action set. */
3923 static int peer_flag_action_set(const struct peer_flag_action *action_list,
3924 int size, struct peer_flag_action *action,
3925 uint32_t flag)
3926 {
3927 int i;
3928 int found = 0;
3929 int reset_in = 0;
3930 int reset_out = 0;
3931 const struct peer_flag_action *match = NULL;
3932
3933 /* Check peer's frag action. */
3934 for (i = 0; i < size; i++) {
3935 match = &action_list[i];
3936
3937 if (match->flag == 0)
3938 break;
3939
3940 if (match->flag & flag) {
3941 found = 1;
3942
3943 if (match->type == peer_change_reset_in)
3944 reset_in = 1;
3945 if (match->type == peer_change_reset_out)
3946 reset_out = 1;
3947 if (match->type == peer_change_reset) {
3948 reset_in = 1;
3949 reset_out = 1;
3950 }
3951 if (match->not_for_member)
3952 action->not_for_member = 1;
3953 }
3954 }
3955
3956 /* Set peer clear type. */
3957 if (reset_in && reset_out)
3958 action->type = peer_change_reset;
3959 else if (reset_in)
3960 action->type = peer_change_reset_in;
3961 else if (reset_out)
3962 action->type = peer_change_reset_out;
3963 else
3964 action->type = peer_change_none;
3965
3966 return found;
3967 }
3968
3969 static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
3970 {
3971 if (flag == PEER_FLAG_SHUTDOWN) {
3972 if (CHECK_FLAG(peer->flags, flag)) {
3973 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
3974 peer_nsf_stop(peer);
3975
3976 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3977 if (peer->t_pmax_restart) {
3978 BGP_TIMER_OFF(peer->t_pmax_restart);
3979 if (bgp_debug_neighbor_events(peer))
3980 zlog_debug(
3981 "%s Maximum-prefix restart timer canceled",
3982 peer->host);
3983 }
3984
3985 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
3986 peer_nsf_stop(peer);
3987
3988 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
3989 char *msg = peer->tx_shutdown_message;
3990 size_t msglen;
3991
3992 if (!msg && peer_group_active(peer))
3993 msg = peer->group->conf
3994 ->tx_shutdown_message;
3995 msglen = msg ? strlen(msg) : 0;
3996 if (msglen > 128)
3997 msglen = 128;
3998
3999 if (msglen) {
4000 uint8_t msgbuf[129];
4001
4002 msgbuf[0] = msglen;
4003 memcpy(msgbuf + 1, msg, msglen);
4004
4005 bgp_notify_send_with_data(
4006 peer, BGP_NOTIFY_CEASE,
4007 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
4008 msgbuf, msglen + 1);
4009 } else
4010 bgp_notify_send(
4011 peer, BGP_NOTIFY_CEASE,
4012 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
4013 } else
4014 bgp_session_reset(peer);
4015 } else {
4016 peer->v_start = BGP_INIT_START_TIMER;
4017 BGP_EVENT_ADD(peer, BGP_Stop);
4018 }
4019 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4020 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
4021 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4022 else if (flag == PEER_FLAG_PASSIVE)
4023 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
4024 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
4025 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
4026
4027 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4028 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4029 } else
4030 bgp_session_reset(peer);
4031 }
4032
4033 /* Change specified peer flag. */
4034 static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
4035 {
4036 int found;
4037 int size;
4038 bool invert, member_invert;
4039 struct peer *member;
4040 struct listnode *node, *nnode;
4041 struct peer_flag_action action;
4042
4043 memset(&action, 0, sizeof(struct peer_flag_action));
4044 size = sizeof peer_flag_action_list / sizeof(struct peer_flag_action);
4045
4046 invert = CHECK_FLAG(peer->flags_invert, flag);
4047 found = peer_flag_action_set(peer_flag_action_list, size, &action,
4048 flag);
4049
4050 /* Abort if no flag action exists. */
4051 if (!found)
4052 return BGP_ERR_INVALID_FLAG;
4053
4054 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4055 if (set && CHECK_FLAG(peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
4056 && CHECK_FLAG(peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
4057 return BGP_ERR_PEER_FLAG_CONFLICT;
4058
4059 /* Handle flag updates where desired state matches current state. */
4060 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4061 if (set && CHECK_FLAG(peer->flags, flag)) {
4062 COND_FLAG(peer->flags_override, flag, !invert);
4063 return 0;
4064 }
4065
4066 if (!set && !CHECK_FLAG(peer->flags, flag)) {
4067 COND_FLAG(peer->flags_override, flag, invert);
4068 return 0;
4069 }
4070 }
4071
4072 /* Inherit from peer-group or set/unset flags accordingly. */
4073 if (peer_group_active(peer) && set == invert)
4074 peer_flag_inherit(peer, flag);
4075 else
4076 COND_FLAG(peer->flags, flag, set);
4077
4078 /* Check if handling a regular peer. */
4079 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4080 /* Update flag override state accordingly. */
4081 COND_FLAG(peer->flags_override, flag, set != invert);
4082
4083 /* Execute flag action on peer. */
4084 if (action.type == peer_change_reset)
4085 peer_flag_modify_action(peer, flag);
4086
4087 /* Skip peer-group mechanics for regular peers. */
4088 return 0;
4089 }
4090
4091 if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
4092 bgp_nht_register_enhe_capability_interfaces(peer);
4093
4094 /*
4095 * Update peer-group members, unless they are explicitely overriding
4096 * peer-group configuration.
4097 */
4098 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4099 /* Skip peers with overridden configuration. */
4100 if (CHECK_FLAG(member->flags_override, flag))
4101 continue;
4102
4103 /* Check if only member without group is inverted. */
4104 member_invert =
4105 CHECK_FLAG(member->flags_invert, flag) && !invert;
4106
4107 /* Skip peers with equivalent configuration. */
4108 if (set != member_invert && CHECK_FLAG(member->flags, flag))
4109 continue;
4110
4111 if (set == member_invert && !CHECK_FLAG(member->flags, flag))
4112 continue;
4113
4114 /* Update flag on peer-group member. */
4115 COND_FLAG(member->flags, flag, set != member_invert);
4116
4117 if (set && flag == PEER_FLAG_CAPABILITY_ENHE)
4118 bgp_nht_register_enhe_capability_interfaces(member);
4119
4120 /* Execute flag action on peer-group member. */
4121 if (action.type == peer_change_reset)
4122 peer_flag_modify_action(member, flag);
4123 }
4124
4125 return 0;
4126 }
4127
4128 int peer_flag_set(struct peer *peer, uint32_t flag)
4129 {
4130 return peer_flag_modify(peer, flag, 1);
4131 }
4132
4133 int peer_flag_unset(struct peer *peer, uint32_t flag)
4134 {
4135 return peer_flag_modify(peer, flag, 0);
4136 }
4137
4138 static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
4139 uint32_t flag, bool set)
4140 {
4141 int found;
4142 int size;
4143 bool invert, member_invert;
4144 struct peer *member;
4145 struct listnode *node, *nnode;
4146 struct peer_flag_action action;
4147
4148 memset(&action, 0, sizeof(struct peer_flag_action));
4149 size = sizeof peer_af_flag_action_list
4150 / sizeof(struct peer_flag_action);
4151
4152 invert = CHECK_FLAG(peer->af_flags_invert[afi][safi], flag);
4153 found = peer_flag_action_set(peer_af_flag_action_list, size, &action,
4154 flag);
4155
4156 /* Abort if flag action exists. */
4157 if (!found)
4158 return BGP_ERR_INVALID_FLAG;
4159
4160 /* Special check for reflector client. */
4161 if (flag & PEER_FLAG_REFLECTOR_CLIENT
4162 && peer_sort(peer) != BGP_PEER_IBGP)
4163 return BGP_ERR_NOT_INTERNAL_PEER;
4164
4165 /* Special check for remove-private-AS. */
4166 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
4167 && peer_sort(peer) == BGP_PEER_IBGP)
4168 return BGP_ERR_REMOVE_PRIVATE_AS;
4169
4170 /* as-override is not allowed for IBGP peers */
4171 if (flag & PEER_FLAG_AS_OVERRIDE && peer_sort(peer) == BGP_PEER_IBGP)
4172 return BGP_ERR_AS_OVERRIDE;
4173
4174 /* Handle flag updates where desired state matches current state. */
4175 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4176 if (set && CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4177 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4178 !invert);
4179 return 0;
4180 }
4181
4182 if (!set && !CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4183 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4184 invert);
4185 return 0;
4186 }
4187 }
4188
4189 /*
4190 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4191 * if we are setting/unsetting flags which conflict with this flag
4192 * handle accordingly
4193 */
4194 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
4195 if (set) {
4196
4197 /*
4198 * if we are setting NEXTHOP_SELF, we need to unset the
4199 * NEXTHOP_UNCHANGED flag
4200 */
4201 if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4202 CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4203 UNSET_FLAG(peer->af_flags[afi][safi],
4204 PEER_FLAG_NEXTHOP_UNCHANGED);
4205 } else {
4206
4207 /*
4208 * if we are unsetting NEXTHOP_SELF, we need to set the
4209 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4210 */
4211 if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4212 CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4213 SET_FLAG(peer->af_flags[afi][safi],
4214 PEER_FLAG_NEXTHOP_UNCHANGED);
4215 }
4216 }
4217
4218 /* Inherit from peer-group or set/unset flags accordingly. */
4219 if (peer_group_active(peer) && set == invert)
4220 peer_af_flag_inherit(peer, afi, safi, flag);
4221 else
4222 COND_FLAG(peer->af_flags[afi][safi], flag, set);
4223
4224 /* Execute action when peer is established. */
4225 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4226 && peer->status == Established) {
4227 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4228 bgp_clear_adj_in(peer, afi, safi);
4229 else {
4230 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4231 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
4232 else if (flag == PEER_FLAG_RSERVER_CLIENT)
4233 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
4234 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
4235 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4236 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
4237 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4238
4239 peer_change_action(peer, afi, safi, action.type);
4240 }
4241 }
4242
4243 /* Check if handling a regular peer. */
4244 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4245 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4246 set != invert);
4247 } else {
4248 /*
4249 * Update peer-group members, unless they are explicitely
4250 * overriding peer-group configuration.
4251 */
4252 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode,
4253 member)) {
4254 /* Skip peers with overridden configuration. */
4255 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4256 flag))
4257 continue;
4258
4259 /* Check if only member without group is inverted. */
4260 member_invert =
4261 CHECK_FLAG(member->af_flags_invert[afi][safi],
4262 flag)
4263 && !invert;
4264
4265 /* Skip peers with equivalent configuration. */
4266 if (set != member_invert
4267 && CHECK_FLAG(member->af_flags[afi][safi], flag))
4268 continue;
4269
4270 if (set == member_invert
4271 && !CHECK_FLAG(member->af_flags[afi][safi], flag))
4272 continue;
4273
4274 /* Update flag on peer-group member. */
4275 COND_FLAG(member->af_flags[afi][safi], flag,
4276 set != member_invert);
4277
4278 /* Execute flag action on peer-group member. */
4279 if (member->status == Established) {
4280 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4281 bgp_clear_adj_in(member, afi, safi);
4282 else {
4283 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4284 member->last_reset =
4285 PEER_DOWN_RR_CLIENT_CHANGE;
4286 else if (flag
4287 == PEER_FLAG_RSERVER_CLIENT)
4288 member->last_reset =
4289 PEER_DOWN_RS_CLIENT_CHANGE;
4290 else if (flag
4291 == PEER_FLAG_ORF_PREFIX_SM)
4292 member->last_reset =
4293 PEER_DOWN_CAPABILITY_CHANGE;
4294 else if (flag
4295 == PEER_FLAG_ORF_PREFIX_RM)
4296 member->last_reset =
4297 PEER_DOWN_CAPABILITY_CHANGE;
4298
4299 peer_change_action(member, afi, safi,
4300 action.type);
4301 }
4302 }
4303 }
4304 }
4305
4306 return 0;
4307 }
4308
4309 int peer_af_flag_set(struct peer *peer, afi_t afi, safi_t safi, uint32_t flag)
4310 {
4311 return peer_af_flag_modify(peer, afi, safi, flag, 1);
4312 }
4313
4314 int peer_af_flag_unset(struct peer *peer, afi_t afi, safi_t safi, uint32_t flag)
4315 {
4316 return peer_af_flag_modify(peer, afi, safi, flag, 0);
4317 }
4318
4319
4320 int peer_tx_shutdown_message_set(struct peer *peer, const char *msg)
4321 {
4322 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4323 peer->tx_shutdown_message =
4324 msg ? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG, msg) : NULL;
4325 return 0;
4326 }
4327
4328 int peer_tx_shutdown_message_unset(struct peer *peer)
4329 {
4330 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4331 return 0;
4332 }
4333
4334
4335 /* EBGP multihop configuration. */
4336 int peer_ebgp_multihop_set(struct peer *peer, int ttl)
4337 {
4338 struct peer_group *group;
4339 struct listnode *node, *nnode;
4340 struct peer *peer1;
4341
4342 if (peer->sort == BGP_PEER_IBGP || peer->conf_if)
4343 return 0;
4344
4345 /* see comment in peer_ttl_security_hops_set() */
4346 if (ttl != MAXTTL) {
4347 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4348 group = peer->group;
4349 if (group->conf->gtsm_hops != 0)
4350 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4351
4352 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
4353 peer1)) {
4354 if (peer1->sort == BGP_PEER_IBGP)
4355 continue;
4356
4357 if (peer1->gtsm_hops != 0)
4358 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4359 }
4360 } else {
4361 if (peer->gtsm_hops != 0)
4362 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4363 }
4364 }
4365
4366 peer->ttl = ttl;
4367
4368 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4369 if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP) {
4370 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4371 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4372 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4373 else
4374 bgp_session_reset(peer);
4375 }
4376 } else {
4377 group = peer->group;
4378 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4379 if (peer->sort == BGP_PEER_IBGP)
4380 continue;
4381
4382 peer->ttl = group->conf->ttl;
4383
4384 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4385 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4386 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4387 else
4388 bgp_session_reset(peer);
4389 }
4390 }
4391 return 0;
4392 }
4393
4394 int peer_ebgp_multihop_unset(struct peer *peer)
4395 {
4396 struct peer_group *group;
4397 struct listnode *node, *nnode;
4398
4399 if (peer->sort == BGP_PEER_IBGP)
4400 return 0;
4401
4402 if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
4403 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4404
4405 if (peer_group_active(peer))
4406 peer->ttl = peer->group->conf->ttl;
4407 else
4408 peer->ttl = BGP_DEFAULT_TTL;
4409
4410 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4411 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4412 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4413 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4414 else
4415 bgp_session_reset(peer);
4416 } else {
4417 group = peer->group;
4418 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4419 if (peer->sort == BGP_PEER_IBGP)
4420 continue;
4421
4422 peer->ttl = BGP_DEFAULT_TTL;
4423
4424 if (peer->fd >= 0) {
4425 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4426 bgp_notify_send(
4427 peer, BGP_NOTIFY_CEASE,
4428 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4429 else
4430 bgp_session_reset(peer);
4431 }
4432 }
4433 }
4434 return 0;
4435 }
4436
4437 /* Neighbor description. */
4438 int peer_description_set(struct peer *peer, const char *desc)
4439 {
4440 XFREE(MTYPE_PEER_DESC, peer->desc);
4441
4442 peer->desc = XSTRDUP(MTYPE_PEER_DESC, desc);
4443
4444 return 0;
4445 }
4446
4447 int peer_description_unset(struct peer *peer)
4448 {
4449 XFREE(MTYPE_PEER_DESC, peer->desc);
4450
4451 peer->desc = NULL;
4452
4453 return 0;
4454 }
4455
4456 /* Neighbor update-source. */
4457 int peer_update_source_if_set(struct peer *peer, const char *ifname)
4458 {
4459 struct peer *member;
4460 struct listnode *node, *nnode;
4461
4462 /* Set flag and configuration on peer. */
4463 peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
4464 if (peer->update_if) {
4465 if (strcmp(peer->update_if, ifname) == 0)
4466 return 0;
4467 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4468 }
4469 peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
4470 sockunion_free(peer->update_source);
4471 peer->update_source = NULL;
4472
4473 /* Check if handling a regular peer. */
4474 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4475 /* Send notification or reset peer depending on state. */
4476 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4477 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4478 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4479 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4480 } else
4481 bgp_session_reset(peer);
4482
4483 /* Skip peer-group mechanics for regular peers. */
4484 return 0;
4485 }
4486
4487 /*
4488 * Set flag and configuration on all peer-group members, unless they are
4489 * explicitely overriding peer-group configuration.
4490 */
4491 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4492 /* Skip peers with overridden configuration. */
4493 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
4494 continue;
4495
4496 /* Skip peers with the same configuration. */
4497 if (member->update_if) {
4498 if (strcmp(member->update_if, ifname) == 0)
4499 continue;
4500 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
4501 }
4502
4503 /* Set flag and configuration on peer-group member. */
4504 SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
4505 member->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
4506 sockunion_free(member->update_source);
4507 member->update_source = NULL;
4508
4509 /* Send notification or reset peer depending on state. */
4510 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
4511 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4512 bgp_notify_send(member, BGP_NOTIFY_CEASE,
4513 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4514 } else
4515 bgp_session_reset(member);
4516 }
4517
4518 return 0;
4519 }
4520
4521 int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
4522 {
4523 struct peer *member;
4524 struct listnode *node, *nnode;
4525
4526 /* Set flag and configuration on peer. */
4527 peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
4528 if (peer->update_source) {
4529 if (sockunion_cmp(peer->update_source, su) == 0)
4530 return 0;
4531 sockunion_free(peer->update_source);
4532 }
4533 peer->update_source = sockunion_dup(su);
4534 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4535
4536 /* Check if handling a regular peer. */
4537 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4538 /* Send notification or reset peer depending on state. */
4539 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4540 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4541 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4542 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4543 } else
4544 bgp_session_reset(peer);
4545
4546 /* Skip peer-group mechanics for regular peers. */
4547 return 0;
4548 }
4549
4550 /*
4551 * Set flag and configuration on all peer-group members, unless they are
4552 * explicitely overriding peer-group configuration.
4553 */
4554 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4555 /* Skip peers with overridden configuration. */
4556 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
4557 continue;
4558
4559 /* Skip peers with the same configuration. */
4560 if (member->update_source) {
4561 if (sockunion_cmp(member->update_source, su) == 0)
4562 continue;
4563 sockunion_free(member->update_source);
4564 }
4565
4566 /* Set flag and configuration on peer-group member. */
4567 SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
4568 member->update_source = sockunion_dup(su);
4569 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
4570
4571 /* Send notification or reset peer depending on state. */
4572 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
4573 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4574 bgp_notify_send(member, BGP_NOTIFY_CEASE,
4575 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4576 } else
4577 bgp_session_reset(member);
4578 }
4579
4580 return 0;
4581 }
4582
4583 int peer_update_source_unset(struct peer *peer)
4584 {
4585 struct peer *member;
4586 struct listnode *node, *nnode;
4587
4588 if (!CHECK_FLAG(peer->flags, PEER_FLAG_UPDATE_SOURCE))
4589 return 0;
4590
4591 /* Inherit configuration from peer-group if peer is member. */
4592 if (peer_group_active(peer)) {
4593 peer_flag_inherit(peer, PEER_FLAG_UPDATE_SOURCE);
4594 PEER_SU_ATTR_INHERIT(peer, peer->group, update_source);
4595 PEER_STR_ATTR_INHERIT(peer, peer->group, update_if,
4596 MTYPE_PEER_UPDATE_SOURCE);
4597 } else {
4598 /* Otherwise remove flag and configuration from peer. */
4599 peer_flag_unset(peer, PEER_FLAG_UPDATE_SOURCE);
4600 sockunion_free(peer->update_source);
4601 peer->update_source = NULL;
4602 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4603 }
4604
4605 /* Check if handling a regular peer. */
4606 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4607 /* Send notification or reset peer depending on state. */
4608 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4609 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4610 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4611 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4612 } else
4613 bgp_session_reset(peer);
4614
4615 /* Skip peer-group mechanics for regular peers. */
4616 return 0;
4617 }
4618
4619 /*
4620 * Set flag and configuration on all peer-group members, unless they are
4621 * explicitely overriding peer-group configuration.
4622 */
4623 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4624 /* Skip peers with overridden configuration. */
4625 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
4626 continue;
4627
4628 /* Skip peers with the same configuration. */
4629 if (!CHECK_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE)
4630 && !member->update_source && !member->update_if)
4631 continue;
4632
4633 /* Remove flag and configuration on peer-group member. */
4634 UNSET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
4635 sockunion_free(member->update_source);
4636 member->update_source = NULL;
4637 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
4638
4639 /* Send notification or reset peer depending on state. */
4640 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
4641 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4642 bgp_notify_send(member, BGP_NOTIFY_CEASE,
4643 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4644 } else
4645 bgp_session_reset(member);
4646 }
4647
4648 return 0;
4649 }
4650
4651 int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
4652 const char *rmap, struct route_map *route_map)
4653 {
4654 struct peer *member;
4655 struct listnode *node, *nnode;
4656
4657 /* Set flag and configuration on peer. */
4658 peer_af_flag_set(peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE);
4659 if (rmap) {
4660 if (!peer->default_rmap[afi][safi].name
4661 || strcmp(rmap, peer->default_rmap[afi][safi].name) != 0) {
4662 if (peer->default_rmap[afi][safi].name)
4663 XFREE(MTYPE_ROUTE_MAP_NAME,
4664 peer->default_rmap[afi][safi].name);
4665
4666 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4667 peer->default_rmap[afi][safi].name =
4668 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4669 peer->default_rmap[afi][safi].map = route_map;
4670 route_map_counter_increment(route_map);
4671 }
4672 } else if (!rmap) {
4673 if (peer->default_rmap[afi][safi].name)
4674 XFREE(MTYPE_ROUTE_MAP_NAME,
4675 peer->default_rmap[afi][safi].name);
4676
4677 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4678 peer->default_rmap[afi][safi].name = NULL;
4679 peer->default_rmap[afi][safi].map = NULL;
4680 }
4681
4682 /* Check if handling a regular peer. */
4683 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4684 /* Update peer route announcements. */
4685 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4686 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4687 bgp_default_originate(peer, afi, safi, 0);
4688 bgp_announce_route(peer, afi, safi);
4689 }
4690
4691 /* Skip peer-group mechanics for regular peers. */
4692 return 0;
4693 }
4694
4695 /*
4696 * Set flag and configuration on all peer-group members, unless they are
4697 * explicitely overriding peer-group configuration.
4698 */
4699 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4700 /* Skip peers with overridden configuration. */
4701 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4702 PEER_FLAG_DEFAULT_ORIGINATE))
4703 continue;
4704
4705 /* Set flag and configuration on peer-group member. */
4706 SET_FLAG(member->af_flags[afi][safi],
4707 PEER_FLAG_DEFAULT_ORIGINATE);
4708 if (rmap) {
4709 if (member->default_rmap[afi][safi].name)
4710 XFREE(MTYPE_ROUTE_MAP_NAME,
4711 member->default_rmap[afi][safi].name);
4712 route_map_counter_decrement(
4713 member->default_rmap[afi][safi].map);
4714 member->default_rmap[afi][safi].name =
4715 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4716 member->default_rmap[afi][safi].map = route_map;
4717 route_map_counter_increment(route_map);
4718 }
4719
4720 /* Update peer route announcements. */
4721 if (member->status == Established
4722 && member->afc_nego[afi][safi]) {
4723 update_group_adjust_peer(
4724 peer_af_find(member, afi, safi));
4725 bgp_default_originate(member, afi, safi, 0);
4726 bgp_announce_route(member, afi, safi);
4727 }
4728 }
4729
4730 return 0;
4731 }
4732
4733 int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi)
4734 {
4735 struct peer *member;
4736 struct listnode *node, *nnode;
4737
4738 /* Inherit configuration from peer-group if peer is member. */
4739 if (peer_group_active(peer)) {
4740 peer_af_flag_inherit(peer, afi, safi,
4741 PEER_FLAG_DEFAULT_ORIGINATE);
4742 PEER_STR_ATTR_INHERIT(peer, peer->group,
4743 default_rmap[afi][safi].name,
4744 MTYPE_ROUTE_MAP_NAME);
4745 PEER_ATTR_INHERIT(peer, peer->group,
4746 default_rmap[afi][safi].map);
4747 } else {
4748 /* Otherwise remove flag and configuration from peer. */
4749 peer_af_flag_unset(peer, afi, safi,
4750 PEER_FLAG_DEFAULT_ORIGINATE);
4751 if (peer->default_rmap[afi][safi].name)
4752 XFREE(MTYPE_ROUTE_MAP_NAME,
4753 peer->default_rmap[afi][safi].name);
4754 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4755 peer->default_rmap[afi][safi].name = NULL;
4756 peer->default_rmap[afi][safi].map = NULL;
4757 }
4758
4759 /* Check if handling a regular peer. */
4760 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4761 /* Update peer route announcements. */
4762 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4763 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4764 bgp_default_originate(peer, afi, safi, 1);
4765 bgp_announce_route(peer, afi, safi);
4766 }
4767
4768 /* Skip peer-group mechanics for regular peers. */
4769 return 0;
4770 }
4771
4772 /*
4773 * Remove flag and configuration from all peer-group members, unless
4774 * they are explicitely overriding peer-group configuration.
4775 */
4776 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4777 /* Skip peers with overridden configuration. */
4778 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4779 PEER_FLAG_DEFAULT_ORIGINATE))
4780 continue;
4781
4782 /* Remove flag and configuration on peer-group member. */
4783 UNSET_FLAG(peer->af_flags[afi][safi],
4784 PEER_FLAG_DEFAULT_ORIGINATE);
4785 if (peer->default_rmap[afi][safi].name)
4786 XFREE(MTYPE_ROUTE_MAP_NAME,
4787 peer->default_rmap[afi][safi].name);
4788 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4789 peer->default_rmap[afi][safi].name = NULL;
4790 peer->default_rmap[afi][safi].map = NULL;
4791
4792 /* Update peer route announcements. */
4793 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4794 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4795 bgp_default_originate(peer, afi, safi, 1);
4796 bgp_announce_route(peer, afi, safi);
4797 }
4798 }
4799
4800 return 0;
4801 }
4802
4803 int peer_port_set(struct peer *peer, uint16_t port)
4804 {
4805 peer->port = port;
4806 return 0;
4807 }
4808
4809 int peer_port_unset(struct peer *peer)
4810 {
4811 peer->port = BGP_PORT_DEFAULT;
4812 return 0;
4813 }
4814
4815 /*
4816 * Helper function that is called after the name of the policy
4817 * being used by a peer has changed (AF specific). Automatically
4818 * initiates inbound or outbound processing as needed.
4819 */
4820 static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
4821 int outbound)
4822 {
4823 if (outbound) {
4824 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4825 if (peer->status == Established)
4826 bgp_announce_route(peer, afi, safi);
4827 } else {
4828 if (peer->status != Established)
4829 return;
4830
4831 if (CHECK_FLAG(peer->af_flags[afi][safi],
4832 PEER_FLAG_SOFT_RECONFIG))
4833 bgp_soft_reconfig_in(peer, afi, safi);
4834 else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4835 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4836 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0);
4837 }
4838 }
4839
4840
4841 /* neighbor weight. */
4842 int peer_weight_set(struct peer *peer, afi_t afi, safi_t safi, uint16_t weight)
4843 {
4844 struct peer *member;
4845 struct listnode *node, *nnode;
4846
4847 /* Set flag and configuration on peer. */
4848 peer_af_flag_set(peer, afi, safi, PEER_FLAG_WEIGHT);
4849 if (peer->weight[afi][safi] != weight) {
4850 peer->weight[afi][safi] = weight;
4851 peer_on_policy_change(peer, afi, safi, 0);
4852 }
4853
4854 /* Skip peer-group mechanics for regular peers. */
4855 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4856 return 0;
4857
4858 /*
4859 * Set flag and configuration on all peer-group members, unless they are
4860 * explicitely overriding peer-group configuration.
4861 */
4862 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4863 /* Skip peers with overridden configuration. */
4864 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4865 PEER_FLAG_WEIGHT))
4866 continue;
4867
4868 /* Set flag and configuration on peer-group member. */
4869 SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
4870 if (member->weight[afi][safi] != weight) {
4871 member->weight[afi][safi] = weight;
4872 peer_on_policy_change(member, afi, safi, 0);
4873 }
4874 }
4875
4876 return 0;
4877 }
4878
4879 int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi)
4880 {
4881 struct peer *member;
4882 struct listnode *node, *nnode;
4883
4884 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
4885 return 0;
4886
4887 /* Inherit configuration from peer-group if peer is member. */
4888 if (peer_group_active(peer)) {
4889 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_WEIGHT);
4890 PEER_ATTR_INHERIT(peer, peer->group, weight[afi][safi]);
4891
4892 peer_on_policy_change(peer, afi, safi, 0);
4893 return 0;
4894 }
4895
4896 /* Remove flag and configuration from peer. */
4897 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_WEIGHT);
4898 peer->weight[afi][safi] = 0;
4899 peer_on_policy_change(peer, afi, safi, 0);
4900
4901 /* Skip peer-group mechanics for regular peers. */
4902 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4903 return 0;
4904
4905 /*
4906 * Remove flag and configuration from all peer-group members, unless
4907 * they are explicitely overriding peer-group configuration.
4908 */
4909 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4910 /* Skip peers with overridden configuration. */
4911 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4912 PEER_FLAG_WEIGHT))
4913 continue;
4914
4915 /* Skip peers where flag is already disabled. */
4916 if (!CHECK_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT))
4917 continue;
4918
4919 /* Remove flag and configuration on peer-group member. */
4920 UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
4921 member->weight[afi][safi] = 0;
4922 peer_on_policy_change(member, afi, safi, 0);
4923 }
4924
4925 return 0;
4926 }
4927
4928 int peer_timers_set(struct peer *peer, uint32_t keepalive, uint32_t holdtime)
4929 {
4930 struct peer *member;
4931 struct listnode *node, *nnode;
4932
4933 if (keepalive > 65535)
4934 return BGP_ERR_INVALID_VALUE;
4935
4936 if (holdtime > 65535)
4937 return BGP_ERR_INVALID_VALUE;
4938
4939 if (holdtime < 3 && holdtime != 0)
4940 return BGP_ERR_INVALID_VALUE;
4941
4942 /* Set flag and configuration on peer. */
4943 peer_flag_set(peer, PEER_FLAG_TIMER);
4944 peer->holdtime = holdtime;
4945 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
4946
4947 /* Skip peer-group mechanics for regular peers. */
4948 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4949 return 0;
4950
4951 /*
4952 * Set flag and configuration on all peer-group members, unless they are
4953 * explicitely overriding peer-group configuration.
4954 */
4955 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4956 /* Skip peers with overridden configuration. */
4957 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
4958 continue;
4959
4960 /* Set flag and configuration on peer-group member. */
4961 SET_FLAG(member->flags, PEER_FLAG_TIMER);
4962 PEER_ATTR_INHERIT(peer, peer->group, holdtime);
4963 PEER_ATTR_INHERIT(peer, peer->group, keepalive);
4964 }
4965
4966 return 0;
4967 }
4968
4969 int peer_timers_unset(struct peer *peer)
4970 {
4971 struct peer *member;
4972 struct listnode *node, *nnode;
4973
4974 /* Inherit configuration from peer-group if peer is member. */
4975 if (peer_group_active(peer)) {
4976 peer_flag_inherit(peer, PEER_FLAG_TIMER);
4977 PEER_ATTR_INHERIT(peer, peer->group, holdtime);
4978 PEER_ATTR_INHERIT(peer, peer->group, keepalive);
4979 } else {
4980 /* Otherwise remove flag and configuration from peer. */
4981 peer_flag_unset(peer, PEER_FLAG_TIMER);
4982 peer->holdtime = 0;
4983 peer->keepalive = 0;
4984 }
4985
4986 /* Skip peer-group mechanics for regular peers. */
4987 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4988 return 0;
4989
4990 /*
4991 * Remove flag and configuration from all peer-group members, unless
4992 * they are explicitely overriding peer-group configuration.
4993 */
4994 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4995 /* Skip peers with overridden configuration. */
4996 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
4997 continue;
4998
4999 /* Remove flag and configuration on peer-group member. */
5000 UNSET_FLAG(member->flags, PEER_FLAG_TIMER);
5001 member->holdtime = 0;
5002 member->keepalive = 0;
5003 }
5004
5005 return 0;
5006 }
5007
5008 int peer_timers_connect_set(struct peer *peer, uint32_t connect)
5009 {
5010 struct peer *member;
5011 struct listnode *node, *nnode;
5012
5013 if (connect > 65535)
5014 return BGP_ERR_INVALID_VALUE;
5015
5016 /* Set flag and configuration on peer. */
5017 peer_flag_set(peer, PEER_FLAG_TIMER_CONNECT);
5018 peer->connect = connect;
5019 peer->v_connect = connect;
5020
5021 /* Skip peer-group mechanics for regular peers. */
5022 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5023 return 0;
5024
5025 /*
5026 * Set flag and configuration on all peer-group members, unless they are
5027 * explicitely overriding peer-group configuration.
5028 */
5029 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5030 /* Skip peers with overridden configuration. */
5031 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5032 continue;
5033
5034 /* Set flag and configuration on peer-group member. */
5035 SET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5036 member->connect = connect;
5037 member->v_connect = connect;
5038 }
5039
5040 return 0;
5041 }
5042
5043 int peer_timers_connect_unset(struct peer *peer)
5044 {
5045 struct peer *member;
5046 struct listnode *node, *nnode;
5047
5048 /* Inherit configuration from peer-group if peer is member. */
5049 if (peer_group_active(peer)) {
5050 peer_flag_inherit(peer, PEER_FLAG_TIMER_CONNECT);
5051 PEER_ATTR_INHERIT(peer, peer->group, connect);
5052 } else {
5053 /* Otherwise remove flag and configuration from peer. */
5054 peer_flag_unset(peer, PEER_FLAG_TIMER_CONNECT);
5055 peer->connect = 0;
5056 }
5057
5058 /* Set timer with fallback to default value. */
5059 if (peer->connect)
5060 peer->v_connect = peer->connect;
5061 else
5062 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
5063
5064 /* Skip peer-group mechanics for regular peers. */
5065 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5066 return 0;
5067
5068 /*
5069 * Remove flag and configuration from all peer-group members, unless
5070 * they are explicitely overriding peer-group configuration.
5071 */
5072 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5073 /* Skip peers with overridden configuration. */
5074 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5075 continue;
5076
5077 /* Remove flag and configuration on peer-group member. */
5078 UNSET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5079 member->connect = 0;
5080 member->v_connect = BGP_DEFAULT_CONNECT_RETRY;
5081 }
5082
5083 return 0;
5084 }
5085
5086 int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv)
5087 {
5088 struct peer *member;
5089 struct listnode *node, *nnode;
5090
5091 if (routeadv > 600)
5092 return BGP_ERR_INVALID_VALUE;
5093
5094 /* Set flag and configuration on peer. */
5095 peer_flag_set(peer, PEER_FLAG_ROUTEADV);
5096 peer->routeadv = routeadv;
5097 peer->v_routeadv = routeadv;
5098
5099 /* Check if handling a regular peer. */
5100 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5101 /* Update peer route announcements. */
5102 update_group_adjust_peer_afs(peer);
5103 if (peer->status == Established)
5104 bgp_announce_route_all(peer);
5105
5106 /* Skip peer-group mechanics for regular peers. */
5107 return 0;
5108 }
5109
5110 /*
5111 * Set flag and configuration on all peer-group members, unless they are
5112 * explicitely overriding peer-group configuration.
5113 */
5114 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5115 /* Skip peers with overridden configuration. */
5116 if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
5117 continue;
5118
5119 /* Set flag and configuration on peer-group member. */
5120 SET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
5121 member->routeadv = routeadv;
5122 member->v_routeadv = routeadv;
5123
5124 /* Update peer route announcements. */
5125 update_group_adjust_peer_afs(member);
5126 if (member->status == Established)
5127 bgp_announce_route_all(member);
5128 }
5129
5130 return 0;
5131 }
5132
5133 int peer_advertise_interval_unset(struct peer *peer)
5134 {
5135 struct peer *member;
5136 struct listnode *node, *nnode;
5137
5138 /* Inherit configuration from peer-group if peer is member. */
5139 if (peer_group_active(peer)) {
5140 peer_flag_inherit(peer, PEER_FLAG_ROUTEADV);
5141 PEER_ATTR_INHERIT(peer, peer->group, routeadv);
5142 } else {
5143 /* Otherwise remove flag and configuration from peer. */
5144 peer_flag_unset(peer, PEER_FLAG_ROUTEADV);
5145 peer->routeadv = 0;
5146 }
5147
5148 /* Set timer with fallback to default value. */
5149 if (peer->routeadv)
5150 peer->v_routeadv = peer->routeadv;
5151 else
5152 peer->v_routeadv = (peer->sort == BGP_PEER_IBGP)
5153 ? BGP_DEFAULT_IBGP_ROUTEADV
5154 : BGP_DEFAULT_EBGP_ROUTEADV;
5155
5156 /* Check if handling a regular peer. */
5157 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5158 /* Update peer route announcements. */
5159 update_group_adjust_peer_afs(peer);
5160 if (peer->status == Established)
5161 bgp_announce_route_all(peer);
5162
5163 /* Skip peer-group mechanics for regular peers. */
5164 return 0;
5165 }
5166
5167 /*
5168 * Remove flag and configuration from all peer-group members, unless
5169 * they are explicitely overriding peer-group configuration.
5170 */
5171 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5172 /* Skip peers with overridden configuration. */
5173 if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
5174 continue;
5175
5176 /* Remove flag and configuration on peer-group member. */
5177 UNSET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
5178 member->routeadv = 0;
5179 member->v_routeadv = (member->sort == BGP_PEER_IBGP)
5180 ? BGP_DEFAULT_IBGP_ROUTEADV
5181 : BGP_DEFAULT_EBGP_ROUTEADV;
5182
5183 /* Update peer route announcements. */
5184 update_group_adjust_peer_afs(member);
5185 if (member->status == Established)
5186 bgp_announce_route_all(member);
5187 }
5188
5189 return 0;
5190 }
5191
5192 /* neighbor interface */
5193 void peer_interface_set(struct peer *peer, const char *str)
5194 {
5195 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
5196 peer->ifname = XSTRDUP(MTYPE_BGP_PEER_IFNAME, str);
5197 }
5198
5199 void peer_interface_unset(struct peer *peer)
5200 {
5201 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
5202 peer->ifname = NULL;
5203 }
5204
5205 /* Allow-as in. */
5206 int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
5207 int allow_num, int origin)
5208 {
5209 struct peer *member;
5210 struct listnode *node, *nnode;
5211
5212 if (!origin && (allow_num < 1 || allow_num > 10))
5213 return BGP_ERR_INVALID_VALUE;
5214
5215 /* Set flag and configuration on peer. */
5216 peer_af_flag_set(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
5217 if (origin) {
5218 if (peer->allowas_in[afi][safi] != 0
5219 || !CHECK_FLAG(peer->af_flags[afi][safi],
5220 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5221 peer_af_flag_set(peer, afi, safi,
5222 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5223 peer->allowas_in[afi][safi] = 0;
5224 peer_on_policy_change(peer, afi, safi, 0);
5225 }
5226 } else {
5227 if (peer->allowas_in[afi][safi] != allow_num
5228 || CHECK_FLAG(peer->af_flags[afi][safi],
5229 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5230
5231 peer_af_flag_unset(peer, afi, safi,
5232 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5233 peer->allowas_in[afi][safi] = allow_num;
5234 peer_on_policy_change(peer, afi, safi, 0);
5235 }
5236 }
5237
5238 /* Skip peer-group mechanics for regular peers. */
5239 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5240 return 0;
5241
5242 /*
5243 * Set flag and configuration on all peer-group members, unless
5244 * they are explicitely overriding peer-group configuration.
5245 */
5246 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5247 /* Skip peers with overridden configuration. */
5248 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5249 PEER_FLAG_ALLOWAS_IN))
5250 continue;
5251
5252 /* Set flag and configuration on peer-group member. */
5253 SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
5254 if (origin) {
5255 if (member->allowas_in[afi][safi] != 0
5256 || !CHECK_FLAG(member->af_flags[afi][safi],
5257 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5258 SET_FLAG(member->af_flags[afi][safi],
5259 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5260 member->allowas_in[afi][safi] = 0;
5261 peer_on_policy_change(peer, afi, safi, 0);
5262 }
5263 } else {
5264 if (member->allowas_in[afi][safi] != allow_num
5265 || CHECK_FLAG(member->af_flags[afi][safi],
5266 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5267 UNSET_FLAG(member->af_flags[afi][safi],
5268 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5269 member->allowas_in[afi][safi] = allow_num;
5270 peer_on_policy_change(peer, afi, safi, 0);
5271 }
5272 }
5273 }
5274
5275 return 0;
5276 }
5277
5278 int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
5279 {
5280 struct peer *member;
5281 struct listnode *node, *nnode;
5282
5283 /* Skip peer if flag is already disabled. */
5284 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
5285 return 0;
5286
5287 /* Inherit configuration from peer-group if peer is member. */
5288 if (peer_group_active(peer)) {
5289 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
5290 peer_af_flag_inherit(peer, afi, safi,
5291 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5292 PEER_ATTR_INHERIT(peer, peer->group, allowas_in[afi][safi]);
5293 peer_on_policy_change(peer, afi, safi, 0);
5294
5295 return 0;
5296 }
5297
5298 /* Remove flag and configuration from peer. */
5299 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
5300 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN);
5301 peer->allowas_in[afi][safi] = 0;
5302 peer_on_policy_change(peer, afi, safi, 0);
5303
5304 /* Skip peer-group mechanics if handling a regular peer. */
5305 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5306 return 0;
5307
5308 /*
5309 * Remove flags and configuration from all peer-group members, unless
5310 * they are explicitely overriding peer-group configuration.
5311 */
5312 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5313 /* Skip peers with overridden configuration. */
5314 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5315 PEER_FLAG_ALLOWAS_IN))
5316 continue;
5317
5318 /* Skip peers where flag is already disabled. */
5319 if (!CHECK_FLAG(member->af_flags[afi][safi],
5320 PEER_FLAG_ALLOWAS_IN))
5321 continue;
5322
5323 /* Remove flags and configuration on peer-group member. */
5324 UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
5325 UNSET_FLAG(member->af_flags[afi][safi],
5326 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5327 member->allowas_in[afi][safi] = 0;
5328 peer_on_policy_change(member, afi, safi, 0);
5329 }
5330
5331 return 0;
5332 }
5333
5334 int peer_local_as_set(struct peer *peer, as_t as, int no_prepend,
5335 int replace_as)
5336 {
5337 bool old_no_prepend, old_replace_as;
5338 struct bgp *bgp = peer->bgp;
5339 struct peer *member;
5340 struct listnode *node, *nnode;
5341
5342 if (peer_sort(peer) != BGP_PEER_EBGP
5343 && peer_sort(peer) != BGP_PEER_INTERNAL)
5344 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
5345
5346 if (bgp->as == as)
5347 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
5348
5349 if (peer->as == as)
5350 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
5351
5352 /* Save previous flag states. */
5353 old_no_prepend =
5354 !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5355 old_replace_as =
5356 !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5357
5358 /* Set flag and configuration on peer. */
5359 peer_flag_set(peer, PEER_FLAG_LOCAL_AS);
5360 peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND, no_prepend);
5361 peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as);
5362
5363 if (peer->change_local_as == as && old_no_prepend == no_prepend
5364 && old_replace_as == replace_as)
5365 return 0;
5366 peer->change_local_as = as;
5367
5368 /* Check if handling a regular peer. */
5369 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5370 /* Send notification or reset peer depending on state. */
5371 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5372 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5373 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5374 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5375 } else
5376 bgp_session_reset(peer);
5377
5378 /* Skip peer-group mechanics for regular peers. */
5379 return 0;
5380 }
5381
5382 /*
5383 * Set flag and configuration on all peer-group members, unless they are
5384 * explicitely overriding peer-group configuration.
5385 */
5386 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5387 /* Skip peers with overridden configuration. */
5388 if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
5389 continue;
5390
5391 /* Skip peers with the same configuration. */
5392 old_no_prepend = CHECK_FLAG(member->flags,
5393 PEER_FLAG_LOCAL_AS_NO_PREPEND);
5394 old_replace_as = CHECK_FLAG(member->flags,
5395 PEER_FLAG_LOCAL_AS_REPLACE_AS);
5396 if (member->change_local_as == as
5397 && CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS)
5398 && old_no_prepend == no_prepend
5399 && old_replace_as == replace_as)
5400 continue;
5401
5402 /* Set flag and configuration on peer-group member. */
5403 SET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
5404 COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND,
5405 no_prepend);
5406 COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
5407 replace_as);
5408 member->change_local_as = as;
5409
5410 /* Send notification or stop peer depending on state. */
5411 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5412 member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5413 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5414 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5415 } else
5416 BGP_EVENT_ADD(member, BGP_Stop);
5417 }
5418
5419 return 0;
5420 }
5421
5422 int peer_local_as_unset(struct peer *peer)
5423 {
5424 struct peer *member;
5425 struct listnode *node, *nnode;
5426
5427 if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS))
5428 return 0;
5429
5430 /* Inherit configuration from peer-group if peer is member. */
5431 if (peer_group_active(peer)) {
5432 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS);
5433 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5434 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5435 PEER_ATTR_INHERIT(peer, peer->group, change_local_as);
5436 } else {
5437 /* Otherwise remove flag and configuration from peer. */
5438 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS);
5439 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5440 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5441 peer->change_local_as = 0;
5442 }
5443
5444 /* Check if handling a regular peer. */
5445 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5446 /* Send notification or stop peer depending on state. */
5447 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5448 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5449 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5450 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5451 } else
5452 BGP_EVENT_ADD(peer, BGP_Stop);
5453
5454 /* Skip peer-group mechanics for regular peers. */
5455 return 0;
5456 }
5457
5458 /*
5459 * Remove flag and configuration from all peer-group members, unless
5460 * they are explicitely overriding peer-group configuration.
5461 */
5462 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5463 /* Skip peers with overridden configuration. */
5464 if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
5465 continue;
5466
5467 /* Remove flag and configuration on peer-group member. */
5468 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
5469 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5470 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5471 member->change_local_as = 0;
5472
5473 /* Send notification or stop peer depending on state. */
5474 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5475 member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5476 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5477 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5478 } else
5479 bgp_session_reset(member);
5480 }
5481
5482 return 0;
5483 }
5484
5485 /* Set password for authenticating with the peer. */
5486 int peer_password_set(struct peer *peer, const char *password)
5487 {
5488 struct peer *member;
5489 struct listnode *node, *nnode;
5490 int len = password ? strlen(password) : 0;
5491 int ret = BGP_SUCCESS;
5492
5493 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
5494 return BGP_ERR_INVALID_VALUE;
5495
5496 /* Set flag and configuration on peer. */
5497 peer_flag_set(peer, PEER_FLAG_PASSWORD);
5498 if (peer->password && strcmp(peer->password, password) == 0)
5499 return 0;
5500 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5501 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
5502
5503 /* Check if handling a regular peer. */
5504 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5505 /* Send notification or reset peer depending on state. */
5506 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5507 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5508 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5509 else
5510 bgp_session_reset(peer);
5511
5512 /*
5513 * Attempt to install password on socket and skip peer-group
5514 * mechanics.
5515 */
5516 if (BGP_PEER_SU_UNSPEC(peer))
5517 return BGP_SUCCESS;
5518 return (bgp_md5_set(peer) >= 0) ? BGP_SUCCESS
5519 : BGP_ERR_TCPSIG_FAILED;
5520 }
5521
5522 /*
5523 * Set flag and configuration on all peer-group members, unless they are
5524 * explicitely overriding peer-group configuration.
5525 */
5526 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5527 /* Skip peers with overridden configuration. */
5528 if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
5529 continue;
5530
5531 /* Skip peers with the same password. */
5532 if (member->password && strcmp(member->password, password) == 0)
5533 continue;
5534
5535 /* Set flag and configuration on peer-group member. */
5536 SET_FLAG(member->flags, PEER_FLAG_PASSWORD);
5537 if (member->password)
5538 XFREE(MTYPE_PEER_PASSWORD, member->password);
5539 member->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
5540
5541 /* Send notification or reset peer depending on state. */
5542 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
5543 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5544 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5545 else
5546 bgp_session_reset(member);
5547
5548 /* Attempt to install password on socket. */
5549 if (!BGP_PEER_SU_UNSPEC(member) && bgp_md5_set(member) < 0)
5550 ret = BGP_ERR_TCPSIG_FAILED;
5551 }
5552
5553 /* Set flag and configuration on all peer-group listen ranges */
5554 struct listnode *ln;
5555 struct prefix *lr;
5556
5557 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
5558 bgp_md5_set_prefix(lr, password);
5559 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
5560 bgp_md5_set_prefix(lr, password);
5561
5562 return ret;
5563 }
5564
5565 int peer_password_unset(struct peer *peer)
5566 {
5567 struct peer *member;
5568 struct listnode *node, *nnode;
5569
5570 if (!CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD))
5571 return 0;
5572
5573 /* Inherit configuration from peer-group if peer is member. */
5574 if (peer_group_active(peer)) {
5575 peer_flag_inherit(peer, PEER_FLAG_PASSWORD);
5576 PEER_STR_ATTR_INHERIT(peer, peer->group, password,
5577 MTYPE_PEER_PASSWORD);
5578 } else {
5579 /* Otherwise remove flag and configuration from peer. */
5580 peer_flag_unset(peer, PEER_FLAG_PASSWORD);
5581 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5582 }
5583
5584 /* Check if handling a regular peer. */
5585 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5586 /* Send notification or reset peer depending on state. */
5587 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5588 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5589 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5590 else
5591 bgp_session_reset(peer);
5592
5593 /* Attempt to uninstall password on socket. */
5594 if (!BGP_PEER_SU_UNSPEC(peer))
5595 bgp_md5_unset(peer);
5596
5597 /* Skip peer-group mechanics for regular peers. */
5598 return 0;
5599 }
5600
5601 /*
5602 * Remove flag and configuration from all peer-group members, unless
5603 * they are explicitely overriding peer-group configuration.
5604 */
5605 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5606 /* Skip peers with overridden configuration. */
5607 if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
5608 continue;
5609
5610 /* Remove flag and configuration on peer-group member. */
5611 UNSET_FLAG(member->flags, PEER_FLAG_PASSWORD);
5612 XFREE(MTYPE_PEER_PASSWORD, member->password);
5613
5614 /* Send notification or reset peer depending on state. */
5615 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
5616 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5617 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5618 else
5619 bgp_session_reset(member);
5620
5621 /* Attempt to uninstall password on socket. */
5622 if (!BGP_PEER_SU_UNSPEC(member))
5623 bgp_md5_unset(member);
5624 }
5625
5626 /* Set flag and configuration on all peer-group listen ranges */
5627 struct listnode *ln;
5628 struct prefix *lr;
5629
5630 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
5631 bgp_md5_unset_prefix(lr);
5632 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
5633 bgp_md5_unset_prefix(lr);
5634
5635 return 0;
5636 }
5637
5638
5639 /* Set distribute list to the peer. */
5640 int peer_distribute_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5641 const char *name)
5642 {
5643 struct peer *member;
5644 struct bgp_filter *filter;
5645 struct listnode *node, *nnode;
5646
5647 if (direct != FILTER_IN && direct != FILTER_OUT)
5648 return BGP_ERR_INVALID_VALUE;
5649
5650 /* Set configuration on peer. */
5651 filter = &peer->filter[afi][safi];
5652 if (filter->plist[direct].name)
5653 return BGP_ERR_PEER_FILTER_CONFLICT;
5654 if (filter->dlist[direct].name)
5655 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[direct].name);
5656 filter->dlist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5657 filter->dlist[direct].alist = access_list_lookup(afi, name);
5658
5659 /* Check if handling a regular peer. */
5660 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5661 /* Set override-flag and process peer route updates. */
5662 SET_FLAG(peer->filter_override[afi][safi][direct],
5663 PEER_FT_DISTRIBUTE_LIST);
5664 peer_on_policy_change(peer, afi, safi,
5665 (direct == FILTER_OUT) ? 1 : 0);
5666
5667 /* Skip peer-group mechanics for regular peers. */
5668 return 0;
5669 }
5670
5671 /*
5672 * Set configuration on all peer-group members, un less they are
5673 * explicitely overriding peer-group configuration.
5674 */
5675 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5676 /* Skip peers with overridden configuration. */
5677 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5678 PEER_FT_DISTRIBUTE_LIST))
5679 continue;
5680
5681 /* Set configuration on peer-group member. */
5682 filter = &member->filter[afi][safi];
5683 if (filter->dlist[direct].name)
5684 XFREE(MTYPE_BGP_FILTER_NAME,
5685 filter->dlist[direct].name);
5686 filter->dlist[direct].name =
5687 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5688 filter->dlist[direct].alist = access_list_lookup(afi, name);
5689
5690 /* Process peer route updates. */
5691 peer_on_policy_change(member, afi, safi,
5692 (direct == FILTER_OUT) ? 1 : 0);
5693 }
5694
5695 return 0;
5696 }
5697
5698 int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
5699 {
5700 struct peer *member;
5701 struct bgp_filter *filter;
5702 struct listnode *node, *nnode;
5703
5704 if (direct != FILTER_IN && direct != FILTER_OUT)
5705 return BGP_ERR_INVALID_VALUE;
5706
5707 /* Unset override-flag unconditionally. */
5708 UNSET_FLAG(peer->filter_override[afi][safi][direct],
5709 PEER_FT_DISTRIBUTE_LIST);
5710
5711 /* Inherit configuration from peer-group if peer is member. */
5712 if (peer_group_active(peer)) {
5713 PEER_STR_ATTR_INHERIT(peer, peer->group,
5714 filter[afi][safi].dlist[direct].name,
5715 MTYPE_BGP_FILTER_NAME);
5716 PEER_ATTR_INHERIT(peer, peer->group,
5717 filter[afi][safi].dlist[direct].alist);
5718 } else {
5719 /* Otherwise remove configuration from peer. */
5720 filter = &peer->filter[afi][safi];
5721 if (filter->dlist[direct].name)
5722 XFREE(MTYPE_BGP_FILTER_NAME,
5723 filter->dlist[direct].name);
5724 filter->dlist[direct].name = NULL;
5725 filter->dlist[direct].alist = NULL;
5726 }
5727
5728 /* Check if handling a regular peer. */
5729 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5730 /* Process peer route updates. */
5731 peer_on_policy_change(peer, afi, safi,
5732 (direct == FILTER_OUT) ? 1 : 0);
5733
5734 /* Skip peer-group mechanics for regular peers. */
5735 return 0;
5736 }
5737
5738 /*
5739 * Remove configuration on all peer-group members, unless they are
5740 * explicitely overriding peer-group configuration.
5741 */
5742 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5743 /* Skip peers with overridden configuration. */
5744 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5745 PEER_FT_DISTRIBUTE_LIST))
5746 continue;
5747
5748 /* Remove configuration on peer-group member. */
5749 filter = &member->filter[afi][safi];
5750 if (filter->dlist[direct].name)
5751 XFREE(MTYPE_BGP_FILTER_NAME,
5752 filter->dlist[direct].name);
5753 filter->dlist[direct].name = NULL;
5754 filter->dlist[direct].alist = NULL;
5755
5756 /* Process peer route updates. */
5757 peer_on_policy_change(member, afi, safi,
5758 (direct == FILTER_OUT) ? 1 : 0);
5759 }
5760
5761 return 0;
5762 }
5763
5764 /* Update distribute list. */
5765 static void peer_distribute_update(struct access_list *access)
5766 {
5767 afi_t afi;
5768 safi_t safi;
5769 int direct;
5770 struct listnode *mnode, *mnnode;
5771 struct listnode *node, *nnode;
5772 struct bgp *bgp;
5773 struct peer *peer;
5774 struct peer_group *group;
5775 struct bgp_filter *filter;
5776
5777 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5778 if (access->name)
5779 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
5780 access->name, 0, 0);
5781 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5782 FOREACH_AFI_SAFI (afi, safi) {
5783 filter = &peer->filter[afi][safi];
5784
5785 for (direct = FILTER_IN; direct < FILTER_MAX;
5786 direct++) {
5787 if (filter->dlist[direct].name)
5788 filter->dlist[direct]
5789 .alist = access_list_lookup(
5790 afi,
5791 filter->dlist[direct]
5792 .name);
5793 else
5794 filter->dlist[direct].alist =
5795 NULL;
5796 }
5797 }
5798 }
5799 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
5800 FOREACH_AFI_SAFI (afi, safi) {
5801 filter = &group->conf->filter[afi][safi];
5802
5803 for (direct = FILTER_IN; direct < FILTER_MAX;
5804 direct++) {
5805 if (filter->dlist[direct].name)
5806 filter->dlist[direct]
5807 .alist = access_list_lookup(
5808 afi,
5809 filter->dlist[direct]
5810 .name);
5811 else
5812 filter->dlist[direct].alist =
5813 NULL;
5814 }
5815 }
5816 }
5817 #if ENABLE_BGP_VNC
5818 vnc_prefix_list_update(bgp);
5819 #endif
5820 }
5821 }
5822
5823 /* Set prefix list to the peer. */
5824 int peer_prefix_list_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5825 const char *name)
5826 {
5827 struct peer *member;
5828 struct bgp_filter *filter;
5829 struct listnode *node, *nnode;
5830
5831 if (direct != FILTER_IN && direct != FILTER_OUT)
5832 return BGP_ERR_INVALID_VALUE;
5833
5834 /* Set configuration on peer. */
5835 filter = &peer->filter[afi][safi];
5836 if (filter->dlist[direct].name)
5837 return BGP_ERR_PEER_FILTER_CONFLICT;
5838 if (filter->plist[direct].name)
5839 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[direct].name);
5840 filter->plist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5841 filter->plist[direct].plist = prefix_list_lookup(afi, name);
5842
5843 /* Check if handling a regular peer. */
5844 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5845 /* Set override-flag and process peer route updates. */
5846 SET_FLAG(peer->filter_override[afi][safi][direct],
5847 PEER_FT_PREFIX_LIST);
5848 peer_on_policy_change(peer, afi, safi,
5849 (direct == FILTER_OUT) ? 1 : 0);
5850
5851 /* Skip peer-group mechanics for regular peers. */
5852 return 0;
5853 }
5854
5855 /*
5856 * Set configuration on all peer-group members, unless they are
5857 * explicitely overriding peer-group configuration.
5858 */
5859 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5860 /* Skip peers with overridden configuration. */
5861 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5862 PEER_FT_PREFIX_LIST))
5863 continue;
5864
5865 /* Set configuration on peer-group member. */
5866 filter = &member->filter[afi][safi];
5867 if (filter->plist[direct].name)
5868 XFREE(MTYPE_BGP_FILTER_NAME,
5869 filter->plist[direct].name);
5870 filter->plist[direct].name =
5871 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5872 filter->plist[direct].plist = prefix_list_lookup(afi, name);
5873
5874 /* Process peer route updates. */
5875 peer_on_policy_change(member, afi, safi,
5876 (direct == FILTER_OUT) ? 1 : 0);
5877 }
5878
5879 return 0;
5880 }
5881
5882 int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi,
5883 int direct)
5884 {
5885 struct peer *member;
5886 struct bgp_filter *filter;
5887 struct listnode *node, *nnode;
5888
5889 if (direct != FILTER_IN && direct != FILTER_OUT)
5890 return BGP_ERR_INVALID_VALUE;
5891
5892 /* Unset override-flag unconditionally. */
5893 UNSET_FLAG(peer->filter_override[afi][safi][direct],
5894 PEER_FT_PREFIX_LIST);
5895
5896 /* Inherit configuration from peer-group if peer is member. */
5897 if (peer_group_active(peer)) {
5898 PEER_STR_ATTR_INHERIT(peer, peer->group,
5899 filter[afi][safi].plist[direct].name,
5900 MTYPE_BGP_FILTER_NAME);
5901 PEER_ATTR_INHERIT(peer, peer->group,
5902 filter[afi][safi].plist[direct].plist);
5903 } else {
5904 /* Otherwise remove configuration from peer. */
5905 filter = &peer->filter[afi][safi];
5906 if (filter->plist[direct].name)
5907 XFREE(MTYPE_BGP_FILTER_NAME,
5908 filter->plist[direct].name);
5909 filter->plist[direct].name = NULL;
5910 filter->plist[direct].plist = NULL;
5911 }
5912
5913 /* Check if handling a regular peer. */
5914 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5915 /* Process peer route updates. */
5916 peer_on_policy_change(peer, afi, safi,
5917 (direct == FILTER_OUT) ? 1 : 0);
5918
5919 /* Skip peer-group mechanics for regular peers. */
5920 return 0;
5921 }
5922
5923 /*
5924 * Remove configuration on all peer-group members, unless they are
5925 * explicitely overriding peer-group configuration.
5926 */
5927 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5928 /* Skip peers with overridden configuration. */
5929 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5930 PEER_FT_PREFIX_LIST))
5931 continue;
5932
5933 /* Remove configuration on peer-group member. */
5934 filter = &member->filter[afi][safi];
5935 if (filter->plist[direct].name)
5936 XFREE(MTYPE_BGP_FILTER_NAME,
5937 filter->plist[direct].name);
5938 filter->plist[direct].name = NULL;
5939 filter->plist[direct].plist = NULL;
5940
5941 /* Process peer route updates. */
5942 peer_on_policy_change(member, afi, safi,
5943 (direct == FILTER_OUT) ? 1 : 0);
5944 }
5945
5946 return 0;
5947 }
5948
5949 /* Update prefix-list list. */
5950 static void peer_prefix_list_update(struct prefix_list *plist)
5951 {
5952 struct listnode *mnode, *mnnode;
5953 struct listnode *node, *nnode;
5954 struct bgp *bgp;
5955 struct peer *peer;
5956 struct peer_group *group;
5957 struct bgp_filter *filter;
5958 afi_t afi;
5959 safi_t safi;
5960 int direct;
5961
5962 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5963
5964 /*
5965 * Update the prefix-list on update groups.
5966 */
5967 update_group_policy_update(
5968 bgp, BGP_POLICY_PREFIX_LIST,
5969 plist ? prefix_list_name(plist) : NULL, 0, 0);
5970
5971 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5972 FOREACH_AFI_SAFI (afi, safi) {
5973 filter = &peer->filter[afi][safi];
5974
5975 for (direct = FILTER_IN; direct < FILTER_MAX;
5976 direct++) {
5977 if (filter->plist[direct].name)
5978 filter->plist[direct]
5979 .plist = prefix_list_lookup(
5980 afi,
5981 filter->plist[direct]
5982 .name);
5983 else
5984 filter->plist[direct].plist =
5985 NULL;
5986 }
5987 }
5988 }
5989 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
5990 FOREACH_AFI_SAFI (afi, safi) {
5991 filter = &group->conf->filter[afi][safi];
5992
5993 for (direct = FILTER_IN; direct < FILTER_MAX;
5994 direct++) {
5995 if (filter->plist[direct].name)
5996 filter->plist[direct]
5997 .plist = prefix_list_lookup(
5998 afi,
5999 filter->plist[direct]
6000 .name);
6001 else
6002 filter->plist[direct].plist =
6003 NULL;
6004 }
6005 }
6006 }
6007 }
6008 }
6009
6010 int peer_aslist_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6011 const char *name)
6012 {
6013 struct peer *member;
6014 struct bgp_filter *filter;
6015 struct listnode *node, *nnode;
6016
6017 if (direct != FILTER_IN && direct != FILTER_OUT)
6018 return BGP_ERR_INVALID_VALUE;
6019
6020 /* Set configuration on peer. */
6021 filter = &peer->filter[afi][safi];
6022 if (filter->aslist[direct].name)
6023 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[direct].name);
6024 filter->aslist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6025 filter->aslist[direct].aslist = as_list_lookup(name);
6026
6027 /* Check if handling a regular peer. */
6028 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6029 /* Set override-flag and process peer route updates. */
6030 SET_FLAG(peer->filter_override[afi][safi][direct],
6031 PEER_FT_FILTER_LIST);
6032 peer_on_policy_change(peer, afi, safi,
6033 (direct == FILTER_OUT) ? 1 : 0);
6034
6035 /* Skip peer-group mechanics for regular peers. */
6036 return 0;
6037 }
6038
6039 /*
6040 * Set configuration on all peer-group members, unless they are
6041 * explicitely overriding peer-group configuration.
6042 */
6043 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6044 /* Skip peers with overridden configuration. */
6045 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6046 PEER_FT_FILTER_LIST))
6047 continue;
6048
6049 /* Set configuration on peer-group member. */
6050 filter = &member->filter[afi][safi];
6051 if (filter->aslist[direct].name)
6052 XFREE(MTYPE_BGP_FILTER_NAME,
6053 filter->aslist[direct].name);
6054 filter->aslist[direct].name =
6055 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6056 filter->aslist[direct].aslist = as_list_lookup(name);
6057
6058 /* Process peer route updates. */
6059 peer_on_policy_change(member, afi, safi,
6060 (direct == FILTER_OUT) ? 1 : 0);
6061 }
6062
6063 return 0;
6064 }
6065
6066 int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
6067 {
6068 struct peer *member;
6069 struct bgp_filter *filter;
6070 struct listnode *node, *nnode;
6071
6072 if (direct != FILTER_IN && direct != FILTER_OUT)
6073 return BGP_ERR_INVALID_VALUE;
6074
6075 /* Unset override-flag unconditionally. */
6076 UNSET_FLAG(peer->filter_override[afi][safi][direct],
6077 PEER_FT_FILTER_LIST);
6078
6079 /* Inherit configuration from peer-group if peer is member. */
6080 if (peer_group_active(peer)) {
6081 PEER_STR_ATTR_INHERIT(peer, peer->group,
6082 filter[afi][safi].aslist[direct].name,
6083 MTYPE_BGP_FILTER_NAME);
6084 PEER_ATTR_INHERIT(peer, peer->group,
6085 filter[afi][safi].aslist[direct].aslist);
6086 } else {
6087 /* Otherwise remove configuration from peer. */
6088 filter = &peer->filter[afi][safi];
6089 if (filter->aslist[direct].name)
6090 XFREE(MTYPE_BGP_FILTER_NAME,
6091 filter->aslist[direct].name);
6092 filter->aslist[direct].name = NULL;
6093 filter->aslist[direct].aslist = NULL;
6094 }
6095
6096 /* Check if handling a regular peer. */
6097 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6098 /* Process peer route updates. */
6099 peer_on_policy_change(peer, afi, safi,
6100 (direct == FILTER_OUT) ? 1 : 0);
6101
6102 /* Skip peer-group mechanics for regular peers. */
6103 return 0;
6104 }
6105
6106 /*
6107 * Remove configuration on all peer-group members, unless they are
6108 * explicitely overriding peer-group configuration.
6109 */
6110 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6111 /* Skip peers with overridden configuration. */
6112 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6113 PEER_FT_FILTER_LIST))
6114 continue;
6115
6116 /* Remove configuration on peer-group member. */
6117 filter = &member->filter[afi][safi];
6118 if (filter->aslist[direct].name)
6119 XFREE(MTYPE_BGP_FILTER_NAME,
6120 filter->aslist[direct].name);
6121 filter->aslist[direct].name = NULL;
6122 filter->aslist[direct].aslist = NULL;
6123
6124 /* Process peer route updates. */
6125 peer_on_policy_change(member, afi, safi,
6126 (direct == FILTER_OUT) ? 1 : 0);
6127 }
6128
6129 return 0;
6130 }
6131
6132 static void peer_aslist_update(const char *aslist_name)
6133 {
6134 afi_t afi;
6135 safi_t safi;
6136 int direct;
6137 struct listnode *mnode, *mnnode;
6138 struct listnode *node, *nnode;
6139 struct bgp *bgp;
6140 struct peer *peer;
6141 struct peer_group *group;
6142 struct bgp_filter *filter;
6143
6144 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
6145 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
6146 aslist_name, 0, 0);
6147
6148 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
6149 FOREACH_AFI_SAFI (afi, safi) {
6150 filter = &peer->filter[afi][safi];
6151
6152 for (direct = FILTER_IN; direct < FILTER_MAX;
6153 direct++) {
6154 if (filter->aslist[direct].name)
6155 filter->aslist[direct]
6156 .aslist = as_list_lookup(
6157 filter->aslist[direct]
6158 .name);
6159 else
6160 filter->aslist[direct].aslist =
6161 NULL;
6162 }
6163 }
6164 }
6165 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6166 FOREACH_AFI_SAFI (afi, safi) {
6167 filter = &group->conf->filter[afi][safi];
6168
6169 for (direct = FILTER_IN; direct < FILTER_MAX;
6170 direct++) {
6171 if (filter->aslist[direct].name)
6172 filter->aslist[direct]
6173 .aslist = as_list_lookup(
6174 filter->aslist[direct]
6175 .name);
6176 else
6177 filter->aslist[direct].aslist =
6178 NULL;
6179 }
6180 }
6181 }
6182 }
6183 }
6184
6185 static void peer_aslist_add(char *aslist_name)
6186 {
6187 peer_aslist_update(aslist_name);
6188 route_map_notify_dependencies((char *)aslist_name,
6189 RMAP_EVENT_ASLIST_ADDED);
6190 }
6191
6192 static void peer_aslist_del(const char *aslist_name)
6193 {
6194 peer_aslist_update(aslist_name);
6195 route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_DELETED);
6196 }
6197
6198
6199 int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6200 const char *name, struct route_map *route_map)
6201 {
6202 struct peer *member;
6203 struct bgp_filter *filter;
6204 struct listnode *node, *nnode;
6205
6206 if (direct != RMAP_IN && direct != RMAP_OUT)
6207 return BGP_ERR_INVALID_VALUE;
6208
6209 /* Set configuration on peer. */
6210 filter = &peer->filter[afi][safi];
6211 if (filter->map[direct].name) {
6212 /* If the neighbor is configured with the same route-map
6213 * again then, ignore the duplicate configuration.
6214 */
6215 if (strcmp(filter->map[direct].name, name) == 0)
6216 return 0;
6217
6218 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6219 }
6220 route_map_counter_decrement(filter->map[direct].map);
6221 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6222 filter->map[direct].map = route_map;
6223 route_map_counter_increment(route_map);
6224
6225 /* Check if handling a regular peer. */
6226 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6227 /* Set override-flag and process peer route updates. */
6228 SET_FLAG(peer->filter_override[afi][safi][direct],
6229 PEER_FT_ROUTE_MAP);
6230 peer_on_policy_change(peer, afi, safi,
6231 (direct == RMAP_OUT) ? 1 : 0);
6232
6233 /* Skip peer-group mechanics for regular peers. */
6234 return 0;
6235 }
6236
6237 /*
6238 * Set configuration on all peer-group members, unless they are
6239 * explicitely overriding peer-group configuration.
6240 */
6241 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6242 /* Skip peers with overridden configuration. */
6243 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6244 PEER_FT_ROUTE_MAP))
6245 continue;
6246
6247 /* Set configuration on peer-group member. */
6248 filter = &member->filter[afi][safi];
6249 if (filter->map[direct].name)
6250 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6251 route_map_counter_decrement(filter->map[direct].map);
6252 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6253 filter->map[direct].map = route_map;
6254 route_map_counter_increment(route_map);
6255
6256 /* Process peer route updates. */
6257 peer_on_policy_change(member, afi, safi,
6258 (direct == RMAP_OUT) ? 1 : 0);
6259 }
6260 return 0;
6261 }
6262
6263 /* Unset route-map from the peer. */
6264 int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
6265 {
6266 struct peer *member;
6267 struct bgp_filter *filter;
6268 struct listnode *node, *nnode;
6269
6270 if (direct != RMAP_IN && direct != RMAP_OUT)
6271 return BGP_ERR_INVALID_VALUE;
6272
6273 /* Unset override-flag unconditionally. */
6274 UNSET_FLAG(peer->filter_override[afi][safi][direct], PEER_FT_ROUTE_MAP);
6275
6276 /* Inherit configuration from peer-group if peer is member. */
6277 if (peer_group_active(peer)) {
6278 PEER_STR_ATTR_INHERIT(peer, peer->group,
6279 filter[afi][safi].map[direct].name,
6280 MTYPE_BGP_FILTER_NAME);
6281 PEER_ATTR_INHERIT(peer, peer->group,
6282 filter[afi][safi].map[direct].map);
6283 } else {
6284 /* Otherwise remove configuration from peer. */
6285 filter = &peer->filter[afi][safi];
6286 if (filter->map[direct].name)
6287 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6288 route_map_counter_decrement(filter->map[direct].map);
6289 filter->map[direct].name = NULL;
6290 filter->map[direct].map = NULL;
6291 }
6292
6293 /* Check if handling a regular peer. */
6294 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6295 /* Process peer route updates. */
6296 peer_on_policy_change(peer, afi, safi,
6297 (direct == RMAP_OUT) ? 1 : 0);
6298
6299 /* Skip peer-group mechanics for regular peers. */
6300 return 0;
6301 }
6302
6303 /*
6304 * Remove configuration on all peer-group members, unless they are
6305 * explicitely overriding peer-group configuration.
6306 */
6307 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6308 /* Skip peers with overridden configuration. */
6309 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6310 PEER_FT_ROUTE_MAP))
6311 continue;
6312
6313 /* Remove configuration on peer-group member. */
6314 filter = &member->filter[afi][safi];
6315 if (filter->map[direct].name)
6316 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6317 route_map_counter_decrement(filter->map[direct].map);
6318 filter->map[direct].name = NULL;
6319 filter->map[direct].map = NULL;
6320
6321 /* Process peer route updates. */
6322 peer_on_policy_change(member, afi, safi,
6323 (direct == RMAP_OUT) ? 1 : 0);
6324 }
6325
6326 return 0;
6327 }
6328
6329 /* Set unsuppress-map to the peer. */
6330 int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
6331 const char *name, struct route_map *route_map)
6332 {
6333 struct peer *member;
6334 struct bgp_filter *filter;
6335 struct listnode *node, *nnode;
6336
6337 /* Set configuration on peer. */
6338 filter = &peer->filter[afi][safi];
6339 if (filter->usmap.name)
6340 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6341 route_map_counter_decrement(filter->usmap.map);
6342 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6343 filter->usmap.map = route_map;
6344 route_map_counter_increment(route_map);
6345
6346 /* Check if handling a regular peer. */
6347 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6348 /* Set override-flag and process peer route updates. */
6349 SET_FLAG(peer->filter_override[afi][safi][0],
6350 PEER_FT_UNSUPPRESS_MAP);
6351 peer_on_policy_change(peer, afi, safi, 1);
6352
6353 /* Skip peer-group mechanics for regular peers. */
6354 return 0;
6355 }
6356
6357 /*
6358 * Set configuration on all peer-group members, unless they are
6359 * explicitely overriding peer-group configuration.
6360 */
6361 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6362 /* Skip peers with overridden configuration. */
6363 if (CHECK_FLAG(member->filter_override[afi][safi][0],
6364 PEER_FT_UNSUPPRESS_MAP))
6365 continue;
6366
6367 /* Set configuration on peer-group member. */
6368 filter = &member->filter[afi][safi];
6369 if (filter->usmap.name)
6370 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6371 route_map_counter_decrement(filter->usmap.map);
6372 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6373 filter->usmap.map = route_map;
6374 route_map_counter_increment(route_map);
6375
6376 /* Process peer route updates. */
6377 peer_on_policy_change(member, afi, safi, 1);
6378 }
6379
6380 return 0;
6381 }
6382
6383 /* Unset route-map from the peer. */
6384 int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
6385 {
6386 struct peer *member;
6387 struct bgp_filter *filter;
6388 struct listnode *node, *nnode;
6389
6390 /* Unset override-flag unconditionally. */
6391 UNSET_FLAG(peer->filter_override[afi][safi][0], PEER_FT_UNSUPPRESS_MAP);
6392
6393 /* Inherit configuration from peer-group if peer is member. */
6394 if (peer_group_active(peer)) {
6395 PEER_STR_ATTR_INHERIT(peer, peer->group,
6396 filter[afi][safi].usmap.name,
6397 MTYPE_BGP_FILTER_NAME);
6398 PEER_ATTR_INHERIT(peer, peer->group,
6399 filter[afi][safi].usmap.map);
6400 } else {
6401 /* Otherwise remove configuration from peer. */
6402 filter = &peer->filter[afi][safi];
6403 if (filter->usmap.name)
6404 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6405 route_map_counter_decrement(filter->usmap.map);
6406 filter->usmap.name = NULL;
6407 filter->usmap.map = NULL;
6408 }
6409
6410 /* Check if handling a regular peer. */
6411 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6412 /* Process peer route updates. */
6413 peer_on_policy_change(peer, afi, safi, 1);
6414
6415 /* Skip peer-group mechanics for regular peers. */
6416 return 0;
6417 }
6418
6419 /*
6420 * Remove configuration on all peer-group members, unless they are
6421 * explicitely overriding peer-group configuration.
6422 */
6423 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6424 /* Skip peers with overridden configuration. */
6425 if (CHECK_FLAG(member->filter_override[afi][safi][0],
6426 PEER_FT_UNSUPPRESS_MAP))
6427 continue;
6428
6429 /* Remove configuration on peer-group member. */
6430 filter = &member->filter[afi][safi];
6431 if (filter->usmap.name)
6432 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6433 route_map_counter_decrement(filter->usmap.map);
6434 filter->usmap.name = NULL;
6435 filter->usmap.map = NULL;
6436
6437 /* Process peer route updates. */
6438 peer_on_policy_change(member, afi, safi, 1);
6439 }
6440
6441 return 0;
6442 }
6443
6444 int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
6445 uint32_t max, uint8_t threshold, int warning,
6446 uint16_t restart)
6447 {
6448 struct peer *member;
6449 struct listnode *node, *nnode;
6450
6451 /* Set flags and configuration on peer. */
6452 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
6453 if (warning)
6454 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
6455 else
6456 peer_af_flag_unset(peer, afi, safi,
6457 PEER_FLAG_MAX_PREFIX_WARNING);
6458
6459 peer->pmax[afi][safi] = max;
6460 peer->pmax_threshold[afi][safi] = threshold;
6461 peer->pmax_restart[afi][safi] = restart;
6462
6463 /* Check if handling a regular peer. */
6464 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6465 /* Re-check if peer violates maximum-prefix. */
6466 if ((peer->status == Established) && (peer->afc[afi][safi]))
6467 bgp_maximum_prefix_overflow(peer, afi, safi, 1);
6468
6469 /* Skip peer-group mechanics for regular peers. */
6470 return 0;
6471 }
6472
6473 /*
6474 * Set flags and configuration on all peer-group members, unless they
6475 * are explicitely overriding peer-group configuration.
6476 */
6477 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6478 /* Skip peers with overridden configuration. */
6479 if (CHECK_FLAG(member->af_flags_override[afi][safi],
6480 PEER_FLAG_MAX_PREFIX))
6481 continue;
6482
6483 /* Set flag and configuration on peer-group member. */
6484 member->pmax[afi][safi] = max;
6485 member->pmax_threshold[afi][safi] = threshold;
6486 member->pmax_restart[afi][safi] = restart;
6487 if (warning)
6488 SET_FLAG(member->af_flags[afi][safi],
6489 PEER_FLAG_MAX_PREFIX_WARNING);
6490 else
6491 UNSET_FLAG(member->af_flags[afi][safi],
6492 PEER_FLAG_MAX_PREFIX_WARNING);
6493
6494 /* Re-check if peer violates maximum-prefix. */
6495 if ((member->status == Established) && (member->afc[afi][safi]))
6496 bgp_maximum_prefix_overflow(member, afi, safi, 1);
6497 }
6498
6499 return 0;
6500 }
6501
6502 int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
6503 {
6504 /* Inherit configuration from peer-group if peer is member. */
6505 if (peer_group_active(peer)) {
6506 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
6507 peer_af_flag_inherit(peer, afi, safi,
6508 PEER_FLAG_MAX_PREFIX_WARNING);
6509 PEER_ATTR_INHERIT(peer, peer->group, pmax[afi][safi]);
6510 PEER_ATTR_INHERIT(peer, peer->group, pmax_threshold[afi][safi]);
6511 PEER_ATTR_INHERIT(peer, peer->group, pmax_restart[afi][safi]);
6512
6513 return 0;
6514 }
6515
6516 /* Remove flags and configuration from peer. */
6517 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
6518 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
6519 peer->pmax[afi][safi] = 0;
6520 peer->pmax_threshold[afi][safi] = 0;
6521 peer->pmax_restart[afi][safi] = 0;
6522
6523 /*
6524 * Remove flags and configuration from all peer-group members, unless
6525 * they are explicitely overriding peer-group configuration.
6526 */
6527 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6528 struct peer *member;
6529 struct listnode *node;
6530
6531 for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
6532 /* Skip peers with overridden configuration. */
6533 if (CHECK_FLAG(member->af_flags_override[afi][safi],
6534 PEER_FLAG_MAX_PREFIX))
6535 continue;
6536
6537 /* Remove flag and configuration on peer-group member.
6538 */
6539 UNSET_FLAG(member->af_flags[afi][safi],
6540 PEER_FLAG_MAX_PREFIX);
6541 UNSET_FLAG(member->af_flags[afi][safi],
6542 PEER_FLAG_MAX_PREFIX_WARNING);
6543 member->pmax[afi][safi] = 0;
6544 member->pmax_threshold[afi][safi] = 0;
6545 member->pmax_restart[afi][safi] = 0;
6546 }
6547 }
6548
6549 return 0;
6550 }
6551
6552 int is_ebgp_multihop_configured(struct peer *peer)
6553 {
6554 struct peer_group *group;
6555 struct listnode *node, *nnode;
6556 struct peer *peer1;
6557
6558 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6559 group = peer->group;
6560 if ((peer_sort(peer) != BGP_PEER_IBGP)
6561 && (group->conf->ttl != BGP_DEFAULT_TTL))
6562 return 1;
6563
6564 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer1)) {
6565 if ((peer_sort(peer1) != BGP_PEER_IBGP)
6566 && (peer1->ttl != BGP_DEFAULT_TTL))
6567 return 1;
6568 }
6569 } else {
6570 if ((peer_sort(peer) != BGP_PEER_IBGP)
6571 && (peer->ttl != BGP_DEFAULT_TTL))
6572 return 1;
6573 }
6574 return 0;
6575 }
6576
6577 /* Set # of hops between us and BGP peer. */
6578 int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops)
6579 {
6580 struct peer_group *group;
6581 struct listnode *node, *nnode;
6582 int ret;
6583
6584 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6585 gtsm_hops, peer->host);
6586
6587 /* We cannot configure ttl-security hops when ebgp-multihop is already
6588 set. For non peer-groups, the check is simple. For peer-groups,
6589 it's
6590 slightly messy, because we need to check both the peer-group
6591 structure
6592 and all peer-group members for any trace of ebgp-multihop
6593 configuration
6594 before actually applying the ttl-security rules. Cisco really made a
6595 mess of this configuration parameter, and OpenBGPD got it right.
6596 */
6597
6598 if ((peer->gtsm_hops == 0) && (peer->sort != BGP_PEER_IBGP)) {
6599 if (is_ebgp_multihop_configured(peer))
6600 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
6601
6602 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6603 peer->gtsm_hops = gtsm_hops;
6604
6605 /* Calling ebgp multihop also resets the session.
6606 * On restart, NHT will get setup correctly as will the
6607 * min & max ttls on the socket. The return value is
6608 * irrelevant.
6609 */
6610 ret = peer_ebgp_multihop_set(peer, MAXTTL);
6611
6612 if (ret != 0)
6613 return ret;
6614 } else {
6615 group = peer->group;
6616 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
6617 peer)) {
6618 peer->gtsm_hops = group->conf->gtsm_hops;
6619
6620 /* Calling ebgp multihop also resets the
6621 * session.
6622 * On restart, NHT will get setup correctly as
6623 * will the
6624 * min & max ttls on the socket. The return
6625 * value is
6626 * irrelevant.
6627 */
6628 peer_ebgp_multihop_set(peer, MAXTTL);
6629 }
6630 }
6631 } else {
6632 /* Post the first gtsm setup or if its ibgp, maxttl setting
6633 * isn't
6634 * necessary, just set the minttl.
6635 */
6636 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6637 peer->gtsm_hops = gtsm_hops;
6638
6639 if (peer->fd >= 0)
6640 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
6641 MAXTTL + 1 - gtsm_hops);
6642 if ((peer->status < Established) && peer->doppelganger
6643 && (peer->doppelganger->fd >= 0))
6644 sockopt_minttl(peer->su.sa.sa_family,
6645 peer->doppelganger->fd,
6646 MAXTTL + 1 - gtsm_hops);
6647 } else {
6648 group = peer->group;
6649 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
6650 peer)) {
6651 peer->gtsm_hops = group->conf->gtsm_hops;
6652
6653 /* Change setting of existing peer
6654 * established then change value (may break
6655 * connectivity)
6656 * not established yet (teardown session and
6657 * restart)
6658 * no session then do nothing (will get
6659 * handled by next connection)
6660 */
6661 if (peer->fd >= 0 && peer->gtsm_hops != 0)
6662 sockopt_minttl(
6663 peer->su.sa.sa_family, peer->fd,
6664 MAXTTL + 1 - peer->gtsm_hops);
6665 if ((peer->status < Established)
6666 && peer->doppelganger
6667 && (peer->doppelganger->fd >= 0))
6668 sockopt_minttl(peer->su.sa.sa_family,
6669 peer->doppelganger->fd,
6670 MAXTTL + 1 - gtsm_hops);
6671 }
6672 }
6673 }
6674
6675 return 0;
6676 }
6677
6678 int peer_ttl_security_hops_unset(struct peer *peer)
6679 {
6680 struct peer_group *group;
6681 struct listnode *node, *nnode;
6682 int ret = 0;
6683
6684 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6685 peer->host);
6686
6687 /* if a peer-group member, then reset to peer-group default rather than
6688 * 0 */
6689 if (peer_group_active(peer))
6690 peer->gtsm_hops = peer->group->conf->gtsm_hops;
6691 else
6692 peer->gtsm_hops = 0;
6693
6694 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6695 /* Invoking ebgp_multihop_set will set the TTL back to the
6696 * original
6697 * value as well as restting the NHT and such. The session is
6698 * reset.
6699 */
6700 if (peer->sort == BGP_PEER_EBGP)
6701 ret = peer_ebgp_multihop_unset(peer);
6702 else {
6703 if (peer->fd >= 0)
6704 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
6705 0);
6706
6707 if ((peer->status < Established) && peer->doppelganger
6708 && (peer->doppelganger->fd >= 0))
6709 sockopt_minttl(peer->su.sa.sa_family,
6710 peer->doppelganger->fd, 0);
6711 }
6712 } else {
6713 group = peer->group;
6714 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
6715 peer->gtsm_hops = 0;
6716 if (peer->sort == BGP_PEER_EBGP)
6717 ret = peer_ebgp_multihop_unset(peer);
6718 else {
6719 if (peer->fd >= 0)
6720 sockopt_minttl(peer->su.sa.sa_family,
6721 peer->fd, 0);
6722
6723 if ((peer->status < Established)
6724 && peer->doppelganger
6725 && (peer->doppelganger->fd >= 0))
6726 sockopt_minttl(peer->su.sa.sa_family,
6727 peer->doppelganger->fd,
6728 0);
6729 }
6730 }
6731 }
6732
6733 return ret;
6734 }
6735
6736 /*
6737 * If peer clear is invoked in a loop for all peers on the BGP instance,
6738 * it may end up freeing the doppelganger, and if this was the next node
6739 * to the current node, we would end up accessing the freed next node.
6740 * Pass along additional parameter which can be updated if next node
6741 * is freed; only required when walking the peer list on BGP instance.
6742 */
6743 int peer_clear(struct peer *peer, struct listnode **nnode)
6744 {
6745 if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) {
6746 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) {
6747 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
6748 if (peer->t_pmax_restart) {
6749 BGP_TIMER_OFF(peer->t_pmax_restart);
6750 if (bgp_debug_neighbor_events(peer))
6751 zlog_debug(
6752 "%s Maximum-prefix restart timer canceled",
6753 peer->host);
6754 }
6755 BGP_EVENT_ADD(peer, BGP_Start);
6756 return 0;
6757 }
6758
6759 peer->v_start = BGP_INIT_START_TIMER;
6760 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6761 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6762 BGP_NOTIFY_CEASE_ADMIN_RESET);
6763 else
6764 bgp_session_reset_safe(peer, nnode);
6765 }
6766 return 0;
6767 }
6768
6769 int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi,
6770 enum bgp_clear_type stype)
6771 {
6772 struct peer_af *paf;
6773
6774 if (peer->status != Established)
6775 return 0;
6776
6777 if (!peer->afc[afi][safi])
6778 return BGP_ERR_AF_UNCONFIGURED;
6779
6780 peer->rtt = sockopt_tcp_rtt(peer->fd);
6781
6782 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) {
6783 /* Clear the "neighbor x.x.x.x default-originate" flag */
6784 paf = peer_af_find(peer, afi, safi);
6785 if (paf && paf->subgroup
6786 && CHECK_FLAG(paf->subgroup->sflags,
6787 SUBGRP_STATUS_DEFAULT_ORIGINATE))
6788 UNSET_FLAG(paf->subgroup->sflags,
6789 SUBGRP_STATUS_DEFAULT_ORIGINATE);
6790
6791 bgp_announce_route(peer, afi, safi);
6792 }
6793
6794 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
6795 if (CHECK_FLAG(peer->af_cap[afi][safi],
6796 PEER_CAP_ORF_PREFIX_SM_ADV)
6797 && (CHECK_FLAG(peer->af_cap[afi][safi],
6798 PEER_CAP_ORF_PREFIX_RM_RCV)
6799 || CHECK_FLAG(peer->af_cap[afi][safi],
6800 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))) {
6801 struct bgp_filter *filter = &peer->filter[afi][safi];
6802 uint8_t prefix_type;
6803
6804 if (CHECK_FLAG(peer->af_cap[afi][safi],
6805 PEER_CAP_ORF_PREFIX_RM_RCV))
6806 prefix_type = ORF_TYPE_PREFIX;
6807 else
6808 prefix_type = ORF_TYPE_PREFIX_OLD;
6809
6810 if (filter->plist[FILTER_IN].plist) {
6811 if (CHECK_FLAG(peer->af_sflags[afi][safi],
6812 PEER_STATUS_ORF_PREFIX_SEND))
6813 bgp_route_refresh_send(
6814 peer, afi, safi, prefix_type,
6815 REFRESH_DEFER, 1);
6816 bgp_route_refresh_send(peer, afi, safi,
6817 prefix_type,
6818 REFRESH_IMMEDIATE, 0);
6819 } else {
6820 if (CHECK_FLAG(peer->af_sflags[afi][safi],
6821 PEER_STATUS_ORF_PREFIX_SEND))
6822 bgp_route_refresh_send(
6823 peer, afi, safi, prefix_type,
6824 REFRESH_IMMEDIATE, 1);
6825 else
6826 bgp_route_refresh_send(peer, afi, safi,
6827 0, 0, 0);
6828 }
6829 return 0;
6830 }
6831 }
6832
6833 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
6834 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
6835 /* If neighbor has soft reconfiguration inbound flag.
6836 Use Adj-RIB-In database. */
6837 if (CHECK_FLAG(peer->af_flags[afi][safi],
6838 PEER_FLAG_SOFT_RECONFIG))
6839 bgp_soft_reconfig_in(peer, afi, safi);
6840 else {
6841 /* If neighbor has route refresh capability, send route
6842 refresh
6843 message to the peer. */
6844 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
6845 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
6846 bgp_route_refresh_send(peer, afi, safi, 0, 0,
6847 0);
6848 else
6849 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
6850 }
6851 }
6852 return 0;
6853 }
6854
6855 /* Display peer uptime.*/
6856 char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
6857 json_object *json)
6858 {
6859 time_t uptime1, epoch_tbuf;
6860 struct tm *tm;
6861
6862 /* If there is no connection has been done before print `never'. */
6863 if (uptime2 == 0) {
6864 if (use_json) {
6865 json_object_string_add(json, "peerUptime", "never");
6866 json_object_int_add(json, "peerUptimeMsec", 0);
6867 } else
6868 snprintf(buf, len, "never");
6869 return buf;
6870 }
6871
6872 /* Get current time. */
6873 uptime1 = bgp_clock();
6874 uptime1 -= uptime2;
6875 tm = gmtime(&uptime1);
6876
6877 if (uptime1 < ONE_DAY_SECOND)
6878 snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
6879 tm->tm_sec);
6880 else if (uptime1 < ONE_WEEK_SECOND)
6881 snprintf(buf, len, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
6882 tm->tm_min);
6883 else if (uptime1 < ONE_YEAR_SECOND)
6884 snprintf(buf, len, "%02dw%dd%02dh", tm->tm_yday / 7,
6885 tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour);
6886 else
6887 snprintf(buf, len, "%02dy%02dw%dd", tm->tm_year - 70,
6888 tm->tm_yday / 7,
6889 tm->tm_yday - ((tm->tm_yday / 7) * 7));
6890
6891 if (use_json) {
6892 epoch_tbuf = time(NULL) - uptime1;
6893 json_object_string_add(json, "peerUptime", buf);
6894 json_object_int_add(json, "peerUptimeMsec", uptime1 * 1000);
6895 json_object_int_add(json, "peerUptimeEstablishedEpoch",
6896 epoch_tbuf);
6897 }
6898
6899 return buf;
6900 }
6901
6902 static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
6903 afi_t afi, safi_t safi)
6904 {
6905 struct bgp_filter *filter;
6906 char *addr;
6907
6908 addr = peer->host;
6909 filter = &peer->filter[afi][safi];
6910
6911 /* distribute-list. */
6912 if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST,
6913 FILTER_IN))
6914 vty_out(vty, " neighbor %s distribute-list %s in\n", addr,
6915 filter->dlist[FILTER_IN].name);
6916
6917 if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST,
6918 FILTER_OUT))
6919 vty_out(vty, " neighbor %s distribute-list %s out\n", addr,
6920 filter->dlist[FILTER_OUT].name);
6921
6922 /* prefix-list. */
6923 if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST,
6924 FILTER_IN))
6925 vty_out(vty, " neighbor %s prefix-list %s in\n", addr,
6926 filter->plist[FILTER_IN].name);
6927
6928 if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST,
6929 FILTER_OUT))
6930 vty_out(vty, " neighbor %s prefix-list %s out\n", addr,
6931 filter->plist[FILTER_OUT].name);
6932
6933 /* route-map. */
6934 if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP, RMAP_IN))
6935 vty_out(vty, " neighbor %s route-map %s in\n", addr,
6936 filter->map[RMAP_IN].name);
6937
6938 if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP,
6939 RMAP_OUT))
6940 vty_out(vty, " neighbor %s route-map %s out\n", addr,
6941 filter->map[RMAP_OUT].name);
6942
6943 /* unsuppress-map */
6944 if (peergroup_filter_check(peer, afi, safi, PEER_FT_UNSUPPRESS_MAP, 0))
6945 vty_out(vty, " neighbor %s unsuppress-map %s\n", addr,
6946 filter->usmap.name);
6947
6948 /* filter-list. */
6949 if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST,
6950 FILTER_IN))
6951 vty_out(vty, " neighbor %s filter-list %s in\n", addr,
6952 filter->aslist[FILTER_IN].name);
6953
6954 if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST,
6955 FILTER_OUT))
6956 vty_out(vty, " neighbor %s filter-list %s out\n", addr,
6957 filter->aslist[FILTER_OUT].name);
6958 }
6959
6960 /* BGP peer configuration display function. */
6961 static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
6962 struct peer *peer)
6963 {
6964 struct peer *g_peer = NULL;
6965 char buf[SU_ADDRSTRLEN];
6966 char *addr;
6967 int if_pg_printed = false;
6968 int if_ras_printed = false;
6969
6970 /* Skip dynamic neighbors. */
6971 if (peer_dynamic_neighbor(peer))
6972 return;
6973
6974 if (peer->conf_if)
6975 addr = peer->conf_if;
6976 else
6977 addr = peer->host;
6978
6979 /************************************
6980 ****** Global to the neighbor ******
6981 ************************************/
6982 if (peer->conf_if) {
6983 if (CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
6984 vty_out(vty, " neighbor %s interface v6only", addr);
6985 else
6986 vty_out(vty, " neighbor %s interface", addr);
6987
6988 if (peer_group_active(peer)) {
6989 vty_out(vty, " peer-group %s", peer->group->name);
6990 if_pg_printed = true;
6991 } else if (peer->as_type == AS_SPECIFIED) {
6992 vty_out(vty, " remote-as %u", peer->as);
6993 if_ras_printed = true;
6994 } else if (peer->as_type == AS_INTERNAL) {
6995 vty_out(vty, " remote-as internal");
6996 if_ras_printed = true;
6997 } else if (peer->as_type == AS_EXTERNAL) {
6998 vty_out(vty, " remote-as external");
6999 if_ras_printed = true;
7000 }
7001
7002 vty_out(vty, "\n");
7003 }
7004
7005 /* remote-as and peer-group */
7006 /* peer is a member of a peer-group */
7007 if (peer_group_active(peer)) {
7008 g_peer = peer->group->conf;
7009
7010 if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) {
7011 if (peer->as_type == AS_SPECIFIED) {
7012 vty_out(vty, " neighbor %s remote-as %u\n",
7013 addr, peer->as);
7014 } else if (peer->as_type == AS_INTERNAL) {
7015 vty_out(vty,
7016 " neighbor %s remote-as internal\n",
7017 addr);
7018 } else if (peer->as_type == AS_EXTERNAL) {
7019 vty_out(vty,
7020 " neighbor %s remote-as external\n",
7021 addr);
7022 }
7023 }
7024
7025 /* For swpX peers we displayed the peer-group
7026 * via 'neighbor swpX interface peer-group PGNAME' */
7027 if (!if_pg_printed)
7028 vty_out(vty, " neighbor %s peer-group %s\n", addr,
7029 peer->group->name);
7030 }
7031
7032 /* peer is NOT a member of a peer-group */
7033 else {
7034 /* peer is a peer-group, declare the peer-group */
7035 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
7036 vty_out(vty, " neighbor %s peer-group\n", addr);
7037 }
7038
7039 if (!if_ras_printed) {
7040 if (peer->as_type == AS_SPECIFIED) {
7041 vty_out(vty, " neighbor %s remote-as %u\n",
7042 addr, peer->as);
7043 } else if (peer->as_type == AS_INTERNAL) {
7044 vty_out(vty,
7045 " neighbor %s remote-as internal\n",
7046 addr);
7047 } else if (peer->as_type == AS_EXTERNAL) {
7048 vty_out(vty,
7049 " neighbor %s remote-as external\n",
7050 addr);
7051 }
7052 }
7053 }
7054
7055 /* local-as */
7056 if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS)) {
7057 vty_out(vty, " neighbor %s local-as %u", addr,
7058 peer->change_local_as);
7059 if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND))
7060 vty_out(vty, " no-prepend");
7061 if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS))
7062 vty_out(vty, " replace-as");
7063 vty_out(vty, "\n");
7064 }
7065
7066 /* description */
7067 if (peer->desc) {
7068 vty_out(vty, " neighbor %s description %s\n", addr, peer->desc);
7069 }
7070
7071 /* shutdown */
7072 if (peergroup_flag_check(peer, PEER_FLAG_SHUTDOWN)) {
7073 if (peer->tx_shutdown_message)
7074 vty_out(vty, " neighbor %s shutdown message %s\n", addr,
7075 peer->tx_shutdown_message);
7076 else
7077 vty_out(vty, " neighbor %s shutdown\n", addr);
7078 }
7079
7080 /* bfd */
7081 if (peer->bfd_info) {
7082 if (!peer_group_active(peer) || !g_peer->bfd_info) {
7083 bgp_bfd_peer_config_write(vty, peer, addr);
7084 }
7085 }
7086
7087 /* password */
7088 if (peergroup_flag_check(peer, PEER_FLAG_PASSWORD))
7089 vty_out(vty, " neighbor %s password %s\n", addr,
7090 peer->password);
7091
7092 /* neighbor solo */
7093 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)) {
7094 if (!peer_group_active(peer)) {
7095 vty_out(vty, " neighbor %s solo\n", addr);
7096 }
7097 }
7098
7099 /* BGP port */
7100 if (peer->port != BGP_PORT_DEFAULT) {
7101 vty_out(vty, " neighbor %s port %d\n", addr, peer->port);
7102 }
7103
7104 /* Local interface name */
7105 if (peer->ifname) {
7106 vty_out(vty, " neighbor %s interface %s\n", addr, peer->ifname);
7107 }
7108
7109 /* passive */
7110 if (peergroup_flag_check(peer, PEER_FLAG_PASSIVE))
7111 vty_out(vty, " neighbor %s passive\n", addr);
7112
7113 /* ebgp-multihop */
7114 if (peer->sort != BGP_PEER_IBGP && peer->ttl != BGP_DEFAULT_TTL
7115 && !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL)) {
7116 if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) {
7117 vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr,
7118 peer->ttl);
7119 }
7120 }
7121
7122 /* ttl-security hops */
7123 if (peer->gtsm_hops != 0) {
7124 if (!peer_group_active(peer)
7125 || g_peer->gtsm_hops != peer->gtsm_hops) {
7126 vty_out(vty, " neighbor %s ttl-security hops %d\n",
7127 addr, peer->gtsm_hops);
7128 }
7129 }
7130
7131 /* disable-connected-check */
7132 if (peergroup_flag_check(peer, PEER_FLAG_DISABLE_CONNECTED_CHECK))
7133 vty_out(vty, " neighbor %s disable-connected-check\n", addr);
7134
7135 /* enforce-first-as */
7136 if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS))
7137 vty_out(vty, " neighbor %s enforce-first-as\n", addr);
7138
7139 /* update-source */
7140 if (peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) {
7141 if (peer->update_source)
7142 vty_out(vty, " neighbor %s update-source %s\n", addr,
7143 sockunion2str(peer->update_source, buf,
7144 SU_ADDRSTRLEN));
7145 else if (peer->update_if)
7146 vty_out(vty, " neighbor %s update-source %s\n", addr,
7147 peer->update_if);
7148 }
7149
7150 /* advertisement-interval */
7151 if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV))
7152 vty_out(vty, " neighbor %s advertisement-interval %u\n", addr,
7153 peer->routeadv);
7154
7155 /* timers */
7156 if (peergroup_flag_check(peer, PEER_FLAG_TIMER))
7157 vty_out(vty, " neighbor %s timers %u %u\n", addr,
7158 peer->keepalive, peer->holdtime);
7159
7160 /* timers connect */
7161 if (peergroup_flag_check(peer, PEER_FLAG_TIMER_CONNECT))
7162 vty_out(vty, " neighbor %s timers connect %u\n", addr,
7163 peer->connect);
7164
7165 /* capability dynamic */
7166 if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY))
7167 vty_out(vty, " neighbor %s capability dynamic\n", addr);
7168
7169 /* capability extended-nexthop */
7170 if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) {
7171 if (!peer->conf_if) {
7172 if (CHECK_FLAG(peer->flags_invert,
7173 PEER_FLAG_CAPABILITY_ENHE))
7174 vty_out(vty,
7175 " no neighbor %s capability extended-nexthop\n",
7176 addr);
7177 else
7178 vty_out(vty,
7179 " neighbor %s capability extended-nexthop\n",
7180 addr);
7181 }
7182 }
7183
7184 /* dont-capability-negotiation */
7185 if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY))
7186 vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr);
7187
7188 /* override-capability */
7189 if (peergroup_flag_check(peer, PEER_FLAG_OVERRIDE_CAPABILITY))
7190 vty_out(vty, " neighbor %s override-capability\n", addr);
7191
7192 /* strict-capability-match */
7193 if (peergroup_flag_check(peer, PEER_FLAG_STRICT_CAP_MATCH))
7194 vty_out(vty, " neighbor %s strict-capability-match\n", addr);
7195
7196 /* Sender side AS path loop detection. */
7197 if (peer->as_path_loop_detection)
7198 vty_out(vty, " neighbor %s sender-as-path-loop-detection\n",
7199 addr);
7200 }
7201
7202 /* BGP peer configuration display function. */
7203 static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
7204 struct peer *peer, afi_t afi, safi_t safi)
7205 {
7206 struct peer *g_peer = NULL;
7207 char *addr;
7208 bool flag_scomm, flag_secomm, flag_slcomm;
7209
7210 /* Skip dynamic neighbors. */
7211 if (peer_dynamic_neighbor(peer))
7212 return;
7213
7214 if (peer->conf_if)
7215 addr = peer->conf_if;
7216 else
7217 addr = peer->host;
7218
7219 /************************************
7220 ****** Per AF to the neighbor ******
7221 ************************************/
7222 if (peer_group_active(peer)) {
7223 g_peer = peer->group->conf;
7224
7225 /* If the peer-group is active but peer is not, print a 'no
7226 * activate' */
7227 if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) {
7228 vty_out(vty, " no neighbor %s activate\n", addr);
7229 }
7230
7231 /* If the peer-group is not active but peer is, print an
7232 'activate' */
7233 else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) {
7234 vty_out(vty, " neighbor %s activate\n", addr);
7235 }
7236 } else {
7237 if (peer->afc[afi][safi]) {
7238 if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
7239 if (bgp_flag_check(bgp,
7240 BGP_FLAG_NO_DEFAULT_IPV4)) {
7241 vty_out(vty, " neighbor %s activate\n",
7242 addr);
7243 }
7244 } else
7245 vty_out(vty, " neighbor %s activate\n", addr);
7246 } else {
7247 if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
7248 if (!bgp_flag_check(bgp,
7249 BGP_FLAG_NO_DEFAULT_IPV4)) {
7250 vty_out(vty,
7251 " no neighbor %s activate\n",
7252 addr);
7253 }
7254 }
7255 }
7256 }
7257
7258 /* addpath TX knobs */
7259 if (peergroup_af_addpath_check(peer, afi, safi)) {
7260 switch (peer->addpath_type[afi][safi]) {
7261 case BGP_ADDPATH_ALL:
7262 vty_out(vty, " neighbor %s addpath-tx-all-paths\n",
7263 addr);
7264 break;
7265 case BGP_ADDPATH_BEST_PER_AS:
7266 vty_out(vty,
7267 " neighbor %s addpath-tx-bestpath-per-AS\n",
7268 addr);
7269 break;
7270 case BGP_ADDPATH_MAX:
7271 case BGP_ADDPATH_NONE:
7272 break;
7273 }
7274 }
7275
7276 /* ORF capability. */
7277 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM)
7278 || peergroup_af_flag_check(peer, afi, safi,
7279 PEER_FLAG_ORF_PREFIX_RM)) {
7280 vty_out(vty, " neighbor %s capability orf prefix-list", addr);
7281
7282 if (peergroup_af_flag_check(peer, afi, safi,
7283 PEER_FLAG_ORF_PREFIX_SM)
7284 && peergroup_af_flag_check(peer, afi, safi,
7285 PEER_FLAG_ORF_PREFIX_RM))
7286 vty_out(vty, " both");
7287 else if (peergroup_af_flag_check(peer, afi, safi,
7288 PEER_FLAG_ORF_PREFIX_SM))
7289 vty_out(vty, " send");
7290 else
7291 vty_out(vty, " receive");
7292 vty_out(vty, "\n");
7293 }
7294
7295 /* BGP flag dampening. */
7296 if (CHECK_FLAG(bgp->af_flags[afi][safi],
7297 BGP_CONFIG_DAMPENING))
7298 bgp_config_write_damp(vty, afi, safi);
7299
7300 /* Route reflector client. */
7301 if (peergroup_af_flag_check(peer, afi, safi,
7302 PEER_FLAG_REFLECTOR_CLIENT)) {
7303 vty_out(vty, " neighbor %s route-reflector-client\n", addr);
7304 }
7305
7306 /* next-hop-self force */
7307 if (peergroup_af_flag_check(peer, afi, safi,
7308 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
7309 vty_out(vty, " neighbor %s next-hop-self force\n", addr);
7310 }
7311
7312 /* next-hop-self */
7313 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) {
7314 vty_out(vty, " neighbor %s next-hop-self\n", addr);
7315 }
7316
7317 /* remove-private-AS */
7318 if (peergroup_af_flag_check(peer, afi, safi,
7319 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) {
7320 vty_out(vty, " neighbor %s remove-private-AS all replace-AS\n",
7321 addr);
7322 }
7323
7324 else if (peergroup_af_flag_check(peer, afi, safi,
7325 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) {
7326 vty_out(vty, " neighbor %s remove-private-AS replace-AS\n",
7327 addr);
7328 }
7329
7330 else if (peergroup_af_flag_check(peer, afi, safi,
7331 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
7332 vty_out(vty, " neighbor %s remove-private-AS all\n", addr);
7333 }
7334
7335 else if (peergroup_af_flag_check(peer, afi, safi,
7336 PEER_FLAG_REMOVE_PRIVATE_AS)) {
7337 vty_out(vty, " neighbor %s remove-private-AS\n", addr);
7338 }
7339
7340 /* as-override */
7341 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
7342 vty_out(vty, " neighbor %s as-override\n", addr);
7343 }
7344
7345 /* send-community print. */
7346 flag_scomm = peergroup_af_flag_check(peer, afi, safi,
7347 PEER_FLAG_SEND_COMMUNITY);
7348 flag_secomm = peergroup_af_flag_check(peer, afi, safi,
7349 PEER_FLAG_SEND_EXT_COMMUNITY);
7350 flag_slcomm = peergroup_af_flag_check(peer, afi, safi,
7351 PEER_FLAG_SEND_LARGE_COMMUNITY);
7352
7353 if (flag_scomm && flag_secomm && flag_slcomm) {
7354 vty_out(vty, " no neighbor %s send-community all\n", addr);
7355 } else {
7356 if (flag_scomm)
7357 vty_out(vty, " no neighbor %s send-community\n", addr);
7358 if (flag_secomm)
7359 vty_out(vty,
7360 " no neighbor %s send-community extended\n",
7361 addr);
7362
7363 if (flag_slcomm)
7364 vty_out(vty, " no neighbor %s send-community large\n",
7365 addr);
7366 }
7367
7368 /* Default information */
7369 if (peergroup_af_flag_check(peer, afi, safi,
7370 PEER_FLAG_DEFAULT_ORIGINATE)) {
7371 vty_out(vty, " neighbor %s default-originate", addr);
7372
7373 if (peer->default_rmap[afi][safi].name)
7374 vty_out(vty, " route-map %s",
7375 peer->default_rmap[afi][safi].name);
7376
7377 vty_out(vty, "\n");
7378 }
7379
7380 /* Soft reconfiguration inbound. */
7381 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) {
7382 vty_out(vty, " neighbor %s soft-reconfiguration inbound\n",
7383 addr);
7384 }
7385
7386 /* maximum-prefix. */
7387 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX)) {
7388 vty_out(vty, " neighbor %s maximum-prefix %" PRIu32, addr,
7389 peer->pmax[afi][safi]);
7390
7391 if (peer->pmax_threshold[afi][safi]
7392 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
7393 vty_out(vty, " %u", peer->pmax_threshold[afi][safi]);
7394 if (peer_af_flag_check(peer, afi, safi,
7395 PEER_FLAG_MAX_PREFIX_WARNING))
7396 vty_out(vty, " warning-only");
7397 if (peer->pmax_restart[afi][safi])
7398 vty_out(vty, " restart %u",
7399 peer->pmax_restart[afi][safi]);
7400
7401 vty_out(vty, "\n");
7402 }
7403
7404 /* Route server client. */
7405 if (peergroup_af_flag_check(peer, afi, safi,
7406 PEER_FLAG_RSERVER_CLIENT)) {
7407 vty_out(vty, " neighbor %s route-server-client\n", addr);
7408 }
7409
7410 /* Nexthop-local unchanged. */
7411 if (peergroup_af_flag_check(peer, afi, safi,
7412 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) {
7413 vty_out(vty, " neighbor %s nexthop-local unchanged\n", addr);
7414 }
7415
7416 /* allowas-in <1-10> */
7417 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) {
7418 if (peer_af_flag_check(peer, afi, safi,
7419 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
7420 vty_out(vty, " neighbor %s allowas-in origin\n", addr);
7421 } else if (peer->allowas_in[afi][safi] == 3) {
7422 vty_out(vty, " neighbor %s allowas-in\n", addr);
7423 } else {
7424 vty_out(vty, " neighbor %s allowas-in %d\n", addr,
7425 peer->allowas_in[afi][safi]);
7426 }
7427 }
7428
7429 /* weight */
7430 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_WEIGHT))
7431 vty_out(vty, " neighbor %s weight %lu\n", addr,
7432 peer->weight[afi][safi]);
7433
7434 /* Filter. */
7435 bgp_config_write_filter(vty, peer, afi, safi);
7436
7437 /* atribute-unchanged. */
7438 if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED)
7439 || (safi != SAFI_EVPN
7440 && peer_af_flag_check(peer, afi, safi,
7441 PEER_FLAG_NEXTHOP_UNCHANGED))
7442 || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
7443
7444 if (!peer_group_active(peer)
7445 || peergroup_af_flag_check(peer, afi, safi,
7446 PEER_FLAG_AS_PATH_UNCHANGED)
7447 || peergroup_af_flag_check(peer, afi, safi,
7448 PEER_FLAG_NEXTHOP_UNCHANGED)
7449 || peergroup_af_flag_check(peer, afi, safi,
7450 PEER_FLAG_MED_UNCHANGED)) {
7451
7452 vty_out(vty,
7453 " neighbor %s attribute-unchanged%s%s%s\n",
7454 addr,
7455 peer_af_flag_check(peer, afi, safi,
7456 PEER_FLAG_AS_PATH_UNCHANGED)
7457 ? " as-path"
7458 : "",
7459 peer_af_flag_check(peer, afi, safi,
7460 PEER_FLAG_NEXTHOP_UNCHANGED)
7461 ? " next-hop"
7462 : "",
7463 peer_af_flag_check(peer, afi, safi,
7464 PEER_FLAG_MED_UNCHANGED)
7465 ? " med"
7466 : "");
7467 }
7468 }
7469 }
7470
7471 /* Address family based peer configuration display. */
7472 static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
7473 safi_t safi)
7474 {
7475 struct peer *peer;
7476 struct peer_group *group;
7477 struct listnode *node, *nnode;
7478
7479
7480 vty_frame(vty, " !\n address-family ");
7481 if (afi == AFI_IP) {
7482 if (safi == SAFI_UNICAST)
7483 vty_frame(vty, "ipv4 unicast");
7484 else if (safi == SAFI_LABELED_UNICAST)
7485 vty_frame(vty, "ipv4 labeled-unicast");
7486 else if (safi == SAFI_MULTICAST)
7487 vty_frame(vty, "ipv4 multicast");
7488 else if (safi == SAFI_MPLS_VPN)
7489 vty_frame(vty, "ipv4 vpn");
7490 else if (safi == SAFI_ENCAP)
7491 vty_frame(vty, "ipv4 encap");
7492 else if (safi == SAFI_FLOWSPEC)
7493 vty_frame(vty, "ipv4 flowspec");
7494 } else if (afi == AFI_IP6) {
7495 if (safi == SAFI_UNICAST)
7496 vty_frame(vty, "ipv6 unicast");
7497 else if (safi == SAFI_LABELED_UNICAST)
7498 vty_frame(vty, "ipv6 labeled-unicast");
7499 else if (safi == SAFI_MULTICAST)
7500 vty_frame(vty, "ipv6 multicast");
7501 else if (safi == SAFI_MPLS_VPN)
7502 vty_frame(vty, "ipv6 vpn");
7503 else if (safi == SAFI_ENCAP)
7504 vty_frame(vty, "ipv6 encap");
7505 else if (safi == SAFI_FLOWSPEC)
7506 vty_frame(vty, "ipv6 flowspec");
7507 } else if (afi == AFI_L2VPN) {
7508 if (safi == SAFI_EVPN)
7509 vty_frame(vty, "l2vpn evpn");
7510 }
7511 vty_frame(vty, "\n");
7512
7513 bgp_config_write_distance(vty, bgp, afi, safi);
7514
7515 bgp_config_write_network(vty, bgp, afi, safi);
7516
7517 bgp_config_write_redistribute(vty, bgp, afi, safi);
7518
7519 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
7520 bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
7521
7522 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7523 /* Skip dynamic neighbors. */
7524 if (peer_dynamic_neighbor(peer))
7525 continue;
7526
7527 /* Do not display doppelganger peers */
7528 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
7529 bgp_config_write_peer_af(vty, bgp, peer, afi, safi);
7530 }
7531
7532 bgp_config_write_maxpaths(vty, bgp, afi, safi);
7533 bgp_config_write_table_map(vty, bgp, afi, safi);
7534
7535 if (safi == SAFI_EVPN)
7536 bgp_config_write_evpn_info(vty, bgp, afi, safi);
7537
7538 if (safi == SAFI_FLOWSPEC)
7539 bgp_fs_config_write_pbr(vty, bgp, afi, safi);
7540
7541 if (safi == SAFI_UNICAST) {
7542 bgp_vpn_policy_config_write_afi(vty, bgp, afi);
7543 if (CHECK_FLAG(bgp->af_flags[afi][safi],
7544 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) {
7545
7546 vty_out(vty, " export vpn\n");
7547 }
7548 if (CHECK_FLAG(bgp->af_flags[afi][safi],
7549 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) {
7550
7551 vty_out(vty, " import vpn\n");
7552 }
7553 if (CHECK_FLAG(bgp->af_flags[afi][safi],
7554 BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
7555 char *name;
7556
7557 for (ALL_LIST_ELEMENTS_RO(
7558 bgp->vpn_policy[afi].import_vrf, node,
7559 name))
7560 vty_out(vty, " import vrf %s\n", name);
7561 }
7562 }
7563
7564 vty_endframe(vty, " exit-address-family\n");
7565 }
7566
7567 int bgp_config_write(struct vty *vty)
7568 {
7569 struct bgp *bgp;
7570 struct peer_group *group;
7571 struct peer *peer;
7572 struct listnode *node, *nnode;
7573 struct listnode *mnode, *mnnode;
7574
7575 if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER)
7576 vty_out(vty, "bgp route-map delay-timer %u\n",
7577 bm->rmap_update_timer);
7578
7579 /* BGP configuration. */
7580 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
7581
7582 /* skip all auto created vrf as they dont have user config */
7583 if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
7584 continue;
7585
7586 /* Router bgp ASN */
7587 vty_out(vty, "router bgp %u", bgp->as);
7588
7589 if (bgp->name)
7590 vty_out(vty, " %s %s",
7591 (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
7592 ? "view" : "vrf", bgp->name);
7593 vty_out(vty, "\n");
7594
7595 /* BGP fast-external-failover. */
7596 if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
7597 vty_out(vty, " no bgp fast-external-failover\n");
7598
7599 /* BGP router ID. */
7600 if (bgp->router_id_static.s_addr != 0)
7601 vty_out(vty, " bgp router-id %s\n",
7602 inet_ntoa(bgp->router_id_static));
7603
7604 /* BGP log-neighbor-changes. */
7605 if (!!bgp_flag_check(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)
7606 != DFLT_BGP_LOG_NEIGHBOR_CHANGES)
7607 vty_out(vty, " %sbgp log-neighbor-changes\n",
7608 bgp_flag_check(bgp,
7609 BGP_FLAG_LOG_NEIGHBOR_CHANGES)
7610 ? ""
7611 : "no ");
7612
7613 /* BGP configuration. */
7614 if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
7615 vty_out(vty, " bgp always-compare-med\n");
7616
7617 /* RFC8212 default eBGP policy. */
7618 if (bgp->ebgp_requires_policy
7619 == DEFAULT_EBGP_POLICY_ENABLED)
7620 vty_out(vty, " bgp ebgp-requires-policy\n");
7621
7622 /* draft-ietf-idr-deprecate-as-set-confed-set */
7623 if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
7624 vty_out(vty, " bgp reject-as-sets\n");
7625
7626 /* BGP default ipv4-unicast. */
7627 if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
7628 vty_out(vty, " no bgp default ipv4-unicast\n");
7629
7630 /* BGP default local-preference. */
7631 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
7632 vty_out(vty, " bgp default local-preference %u\n",
7633 bgp->default_local_pref);
7634
7635 /* BGP default show-hostname */
7636 if (!!bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
7637 != DFLT_BGP_SHOW_HOSTNAME)
7638 vty_out(vty, " %sbgp default show-hostname\n",
7639 bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
7640 ? ""
7641 : "no ");
7642
7643 /* BGP default subgroup-pkt-queue-max. */
7644 if (bgp->default_subgroup_pkt_queue_max
7645 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
7646 vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
7647 bgp->default_subgroup_pkt_queue_max);
7648
7649 /* BGP client-to-client reflection. */
7650 if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
7651 vty_out(vty, " no bgp client-to-client reflection\n");
7652
7653 /* BGP cluster ID. */
7654 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID))
7655 vty_out(vty, " bgp cluster-id %s\n",
7656 inet_ntoa(bgp->cluster_id));
7657
7658 /* Disable ebgp connected nexthop check */
7659 if (bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
7660 vty_out(vty,
7661 " bgp disable-ebgp-connected-route-check\n");
7662
7663 /* Confederation identifier*/
7664 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
7665 vty_out(vty, " bgp confederation identifier %u\n",
7666 bgp->confed_id);
7667
7668 /* Confederation peer */
7669 if (bgp->confed_peers_cnt > 0) {
7670 int i;
7671
7672 vty_out(vty, " bgp confederation peers");
7673
7674 for (i = 0; i < bgp->confed_peers_cnt; i++)
7675 vty_out(vty, " %u", bgp->confed_peers[i]);
7676
7677 vty_out(vty, "\n");
7678 }
7679
7680 /* BGP deterministic-med. */
7681 if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
7682 != DFLT_BGP_DETERMINISTIC_MED)
7683 vty_out(vty, " %sbgp deterministic-med\n",
7684 bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
7685 ? ""
7686 : "no ");
7687
7688 /* BGP update-delay. */
7689 bgp_config_write_update_delay(vty, bgp);
7690
7691 if (bgp->v_maxmed_onstartup
7692 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) {
7693 vty_out(vty, " bgp max-med on-startup %u",
7694 bgp->v_maxmed_onstartup);
7695 if (bgp->maxmed_onstartup_value
7696 != BGP_MAXMED_VALUE_DEFAULT)
7697 vty_out(vty, " %u",
7698 bgp->maxmed_onstartup_value);
7699 vty_out(vty, "\n");
7700 }
7701 if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) {
7702 vty_out(vty, " bgp max-med administrative");
7703 if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT)
7704 vty_out(vty, " %u", bgp->maxmed_admin_value);
7705 vty_out(vty, "\n");
7706 }
7707
7708 /* write quanta */
7709 bgp_config_write_wpkt_quanta(vty, bgp);
7710 /* read quanta */
7711 bgp_config_write_rpkt_quanta(vty, bgp);
7712
7713 /* coalesce time */
7714 bgp_config_write_coalesce_time(vty, bgp);
7715
7716 /* BGP graceful-restart. */
7717 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
7718 vty_out(vty,
7719 " bgp graceful-restart stalepath-time %u\n",
7720 bgp->stalepath_time);
7721 if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME)
7722 vty_out(vty, " bgp graceful-restart restart-time %u\n",
7723 bgp->restart_time);
7724 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_RESTART))
7725 vty_out(vty, " bgp graceful-restart\n");
7726
7727 /* BGP graceful-shutdown */
7728 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
7729 vty_out(vty, " bgp graceful-shutdown\n");
7730
7731 /* BGP graceful-restart Preserve State F bit. */
7732 if (bgp_flag_check(bgp, BGP_FLAG_GR_PRESERVE_FWD))
7733 vty_out(vty,
7734 " bgp graceful-restart preserve-fw-state\n");
7735
7736 /* BGP bestpath method. */
7737 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE))
7738 vty_out(vty, " bgp bestpath as-path ignore\n");
7739 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED))
7740 vty_out(vty, " bgp bestpath as-path confed\n");
7741
7742 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
7743 if (bgp_flag_check(bgp,
7744 BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
7745 vty_out(vty,
7746 " bgp bestpath as-path multipath-relax as-set\n");
7747 } else {
7748 vty_out(vty,
7749 " bgp bestpath as-path multipath-relax\n");
7750 }
7751 }
7752
7753 if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
7754 vty_out(vty,
7755 " bgp route-reflector allow-outbound-policy\n");
7756 }
7757 if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID))
7758 vty_out(vty, " bgp bestpath compare-routerid\n");
7759 if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)
7760 || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) {
7761 vty_out(vty, " bgp bestpath med");
7762 if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED))
7763 vty_out(vty, " confed");
7764 if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
7765 vty_out(vty, " missing-as-worst");
7766 vty_out(vty, "\n");
7767 }
7768
7769 /* BGP network import check. */
7770 if (!!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
7771 != DFLT_BGP_IMPORT_CHECK)
7772 vty_out(vty, " %sbgp network import-check\n",
7773 bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
7774 ? ""
7775 : "no ");
7776
7777 /* BGP timers configuration. */
7778 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
7779 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
7780 vty_out(vty, " timers bgp %u %u\n",
7781 bgp->default_keepalive, bgp->default_holdtime);
7782
7783 /* peer-group */
7784 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
7785 bgp_config_write_peer_global(vty, bgp, group->conf);
7786 }
7787
7788 /* Normal neighbor configuration. */
7789 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7790 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
7791 bgp_config_write_peer_global(vty, bgp, peer);
7792 }
7793
7794 /* listen range and limit for dynamic BGP neighbors */
7795 bgp_config_write_listen(vty, bgp);
7796
7797 /*
7798 * BGP default autoshutdown neighbors
7799 *
7800 * This must be placed after any peer and peer-group
7801 * configuration, to avoid setting all peers to shutdown after
7802 * a daemon restart, which is undesired behavior. (see #2286)
7803 */
7804 if (bgp->autoshutdown)
7805 vty_out(vty, " bgp default shutdown\n");
7806
7807 /* IPv4 unicast configuration. */
7808 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
7809
7810 /* IPv4 multicast configuration. */
7811 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MULTICAST);
7812
7813 /* IPv4 labeled-unicast configuration. */
7814 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_LABELED_UNICAST);
7815
7816 /* IPv4 VPN configuration. */
7817 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MPLS_VPN);
7818
7819 /* ENCAPv4 configuration. */
7820 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP);
7821
7822 /* FLOWSPEC v4 configuration. */
7823 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_FLOWSPEC);
7824
7825 /* IPv6 unicast configuration. */
7826 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST);
7827
7828 /* IPv6 multicast configuration. */
7829 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MULTICAST);
7830
7831 /* IPv6 labeled-unicast configuration. */
7832 bgp_config_write_family(vty, bgp, AFI_IP6,
7833 SAFI_LABELED_UNICAST);
7834
7835 /* IPv6 VPN configuration. */
7836 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
7837
7838 /* ENCAPv6 configuration. */
7839 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP);
7840
7841 /* FLOWSPEC v6 configuration. */
7842 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_FLOWSPEC);
7843
7844 /* EVPN configuration. */
7845 bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN);
7846
7847 hook_call(bgp_inst_config_write, bgp, vty);
7848
7849 #if ENABLE_BGP_VNC
7850 bgp_rfapi_cfg_write(vty, bgp);
7851 #endif
7852
7853 vty_out(vty, "!\n");
7854 }
7855 return 0;
7856 }
7857
7858 void bgp_master_init(struct thread_master *master, const int buffer_size)
7859 {
7860 qobj_init();
7861
7862 memset(&bgp_master, 0, sizeof(struct bgp_master));
7863
7864 bm = &bgp_master;
7865 bm->bgp = list_new();
7866 bm->listen_sockets = list_new();
7867 bm->port = BGP_PORT_DEFAULT;
7868 bm->master = master;
7869 bm->start_time = bgp_clock();
7870 bm->t_rmap_update = NULL;
7871 bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
7872 bm->terminating = false;
7873 bm->socket_buffer = buffer_size;
7874
7875 bgp_process_queue_init();
7876
7877 bgp_mac_init();
7878 /* init the rd id space.
7879 assign 0th index in the bitfield,
7880 so that we start with id 1
7881 */
7882 bf_init(bm->rd_idspace, UINT16_MAX);
7883 bf_assign_zero_index(bm->rd_idspace);
7884
7885 /* mpls label dynamic allocation pool */
7886 bgp_lp_init(bm->master, &bm->labelpool);
7887
7888 QOBJ_REG(bm, bgp_master);
7889 }
7890
7891 /*
7892 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7893 * instance delete (non-default only) or BGP exit.
7894 */
7895 static void bgp_if_finish(struct bgp *bgp)
7896 {
7897 struct vrf *vrf;
7898 struct interface *ifp;
7899
7900 vrf = bgp_vrf_lookup_by_instance_type(bgp);
7901
7902 if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW || !vrf)
7903 return;
7904
7905 FOR_ALL_INTERFACES (vrf, ifp) {
7906 struct listnode *c_node, *c_nnode;
7907 struct connected *c;
7908
7909 for (ALL_LIST_ELEMENTS(ifp->connected, c_node, c_nnode, c))
7910 bgp_connected_delete(bgp, c);
7911 }
7912 }
7913
7914 static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
7915 {
7916 struct vrf *vrf = NULL;
7917 struct listnode *next;
7918 struct bgp *bgp;
7919
7920 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
7921 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
7922
7923 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
7924 if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
7925 continue;
7926
7927 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bgp->name));
7928 }
7929 }
7930
7931 static void bgp_instasn_autocomplete(vector comps, struct cmd_token *token)
7932 {
7933 struct listnode *next, *next2;
7934 struct bgp *bgp, *bgp2;
7935 char buf[11];
7936
7937 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
7938 /* deduplicate */
7939 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next2, bgp2)) {
7940 if (bgp2->as == bgp->as)
7941 break;
7942 if (bgp2 == bgp)
7943 break;
7944 }
7945 if (bgp2 != bgp)
7946 continue;
7947
7948 snprintf(buf, sizeof(buf), "%u", bgp->as);
7949 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, buf));
7950 }
7951 }
7952
7953 static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = {
7954 {.tokenname = "VIEWVRFNAME", .completions = bgp_viewvrf_autocomplete},
7955 {.varname = "instasn", .completions = bgp_instasn_autocomplete},
7956 {.completions = NULL},
7957 };
7958
7959 struct frr_pthread *bgp_pth_io;
7960 struct frr_pthread *bgp_pth_ka;
7961
7962 static void bgp_pthreads_init(void)
7963 {
7964 assert(!bgp_pth_io);
7965 assert(!bgp_pth_ka);
7966
7967 struct frr_pthread_attr io = {
7968 .start = frr_pthread_attr_default.start,
7969 .stop = frr_pthread_attr_default.stop,
7970 };
7971 struct frr_pthread_attr ka = {
7972 .start = bgp_keepalives_start,
7973 .stop = bgp_keepalives_stop,
7974 };
7975 bgp_pth_io = frr_pthread_new(&io, "BGP I/O thread", "bgpd_io");
7976 bgp_pth_ka = frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
7977 }
7978
7979 void bgp_pthreads_run(void)
7980 {
7981 frr_pthread_run(bgp_pth_io, NULL);
7982 frr_pthread_run(bgp_pth_ka, NULL);
7983
7984 /* Wait until threads are ready. */
7985 frr_pthread_wait_running(bgp_pth_io);
7986 frr_pthread_wait_running(bgp_pth_ka);
7987 }
7988
7989 void bgp_pthreads_finish(void)
7990 {
7991 frr_pthread_stop_all();
7992 }
7993
7994 void bgp_init(unsigned short instance)
7995 {
7996
7997 /* allocates some vital data structures used by peer commands in
7998 * vty_init */
7999
8000 /* pre-init pthreads */
8001 bgp_pthreads_init();
8002
8003 /* Init zebra. */
8004 bgp_zebra_init(bm->master, instance);
8005
8006 #if ENABLE_BGP_VNC
8007 vnc_zebra_init(bm->master);
8008 #endif
8009
8010 /* BGP VTY commands installation. */
8011 bgp_vty_init();
8012
8013 /* BGP inits. */
8014 bgp_attr_init();
8015 bgp_debug_init();
8016 bgp_dump_init();
8017 bgp_route_init();
8018 bgp_route_map_init();
8019 bgp_scan_vty_init();
8020 bgp_mplsvpn_init();
8021 #if ENABLE_BGP_VNC
8022 rfapi_init();
8023 #endif
8024 bgp_ethernetvpn_init();
8025 bgp_flowspec_vty_init();
8026
8027 /* Access list initialize. */
8028 access_list_init();
8029 access_list_add_hook(peer_distribute_update);
8030 access_list_delete_hook(peer_distribute_update);
8031
8032 /* Filter list initialize. */
8033 bgp_filter_init();
8034 as_list_add_hook(peer_aslist_add);
8035 as_list_delete_hook(peer_aslist_del);
8036
8037 /* Prefix list initialize.*/
8038 prefix_list_init();
8039 prefix_list_add_hook(peer_prefix_list_update);
8040 prefix_list_delete_hook(peer_prefix_list_update);
8041
8042 /* Community list initialize. */
8043 bgp_clist = community_list_init();
8044
8045 /* BFD init */
8046 bgp_bfd_init();
8047
8048 cmd_variable_handler_register(bgp_viewvrf_var_handlers);
8049 }
8050
8051 void bgp_terminate(void)
8052 {
8053 struct bgp *bgp;
8054 struct peer *peer;
8055 struct listnode *node, *nnode;
8056 struct listnode *mnode, *mnnode;
8057
8058 QOBJ_UNREG(bm);
8059
8060 /* Close the listener sockets first as this prevents peers from
8061 * attempting
8062 * to reconnect on receiving the peer unconfig message. In the presence
8063 * of a large number of peers this will ensure that no peer is left with
8064 * a dangling connection
8065 */
8066 /* reverse bgp_master_init */
8067 bgp_close();
8068
8069 if (bm->listen_sockets)
8070 list_delete(&bm->listen_sockets);
8071
8072 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
8073 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
8074 if (peer->status == Established
8075 || peer->status == OpenSent
8076 || peer->status == OpenConfirm)
8077 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
8078 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
8079
8080 if (bm->process_main_queue)
8081 work_queue_free_and_null(&bm->process_main_queue);
8082
8083 if (bm->t_rmap_update)
8084 BGP_TIMER_OFF(bm->t_rmap_update);
8085
8086 bgp_mac_finish();
8087 }
8088
8089 struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
8090 const char *ip_str, bool use_json)
8091 {
8092 int ret;
8093 struct peer *peer;
8094 union sockunion su;
8095
8096 /* Get peer sockunion. */
8097 ret = str2sockunion(ip_str, &su);
8098 if (ret < 0) {
8099 peer = peer_lookup_by_conf_if(bgp, ip_str);
8100 if (!peer) {
8101 peer = peer_lookup_by_hostname(bgp, ip_str);
8102
8103 if (!peer) {
8104 if (use_json) {
8105 json_object *json_no = NULL;
8106 json_no = json_object_new_object();
8107 json_object_string_add(
8108 json_no,
8109 "malformedAddressOrName",
8110 ip_str);
8111 vty_out(vty, "%s\n",
8112 json_object_to_json_string_ext(
8113 json_no,
8114 JSON_C_TO_STRING_PRETTY));
8115 json_object_free(json_no);
8116 } else
8117 vty_out(vty,
8118 "%% Malformed address or name: %s\n",
8119 ip_str);
8120 return NULL;
8121 }
8122 }
8123 return peer;
8124 }
8125
8126 /* Peer structure lookup. */
8127 peer = peer_lookup(bgp, &su);
8128 if (!peer) {
8129 if (use_json) {
8130 json_object *json_no = NULL;
8131 json_no = json_object_new_object();
8132 json_object_string_add(json_no, "warning",
8133 "No such neighbor in this view/vrf");
8134 vty_out(vty, "%s\n",
8135 json_object_to_json_string_ext(
8136 json_no, JSON_C_TO_STRING_PRETTY));
8137 json_object_free(json_no);
8138 } else
8139 vty_out(vty, "No such neighbor in this view/vrf\n");
8140 return NULL;
8141 }
8142
8143 return peer;
8144 }
8145