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