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