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