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