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