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