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