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