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