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