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