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