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