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