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