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