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