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