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