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