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