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