]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgpd.c
Merge pull request #6711 from GalaxyGorilla/bfd_isis_profiles
[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 int peer_afc_set(struct peer *peer, afi_t afi, safi_t safi, int enable)
2178 {
2179 if (enable)
2180 return peer_activate(peer, afi, safi);
2181 else
2182 return peer_deactivate(peer, afi, safi);
2183 }
2184
2185 void peer_nsf_stop(struct peer *peer)
2186 {
2187 afi_t afi;
2188 safi_t safi;
2189
2190 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
2191 UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE);
2192
2193 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2194 for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++)
2195 peer->nsf[afi][safi] = 0;
2196
2197 if (peer->t_gr_restart) {
2198 BGP_TIMER_OFF(peer->t_gr_restart);
2199 if (bgp_debug_neighbor_events(peer))
2200 zlog_debug("%s graceful restart timer stopped",
2201 peer->host);
2202 }
2203 if (peer->t_gr_stale) {
2204 BGP_TIMER_OFF(peer->t_gr_stale);
2205 if (bgp_debug_neighbor_events(peer))
2206 zlog_debug(
2207 "%s graceful restart stalepath timer stopped",
2208 peer->host);
2209 }
2210 bgp_clear_route_all(peer);
2211 }
2212
2213 /* Delete peer from confguration.
2214 *
2215 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
2216 * it to "cool off" and refcounts to hit 0, at which state it is freed.
2217 *
2218 * This function /should/ take care to be idempotent, to guard against
2219 * it being called multiple times through stray events that come in
2220 * that happen to result in this function being called again. That
2221 * said, getting here for a "Deleted" peer is a bug in the neighbour
2222 * FSM.
2223 */
2224 int peer_delete(struct peer *peer)
2225 {
2226 int i;
2227 afi_t afi;
2228 safi_t safi;
2229 struct bgp *bgp;
2230 struct bgp_filter *filter;
2231 struct listnode *pn;
2232 int accept_peer;
2233
2234 assert(peer->status != Deleted);
2235
2236 bgp = peer->bgp;
2237 accept_peer = CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
2238
2239 bgp_keepalives_off(peer);
2240 bgp_reads_off(peer);
2241 bgp_writes_off(peer);
2242 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
2243 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
2244 assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_KEEPALIVES_ON));
2245
2246 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
2247 peer_nsf_stop(peer);
2248
2249 SET_FLAG(peer->flags, PEER_FLAG_DELETE);
2250
2251 bgp_bfd_deregister_peer(peer);
2252
2253 /* If this peer belongs to peer group, clear up the
2254 relationship. */
2255 if (peer->group) {
2256 if (peer_dynamic_neighbor(peer))
2257 peer_drop_dynamic_neighbor(peer);
2258
2259 if ((pn = listnode_lookup(peer->group->peer, peer))) {
2260 peer = peer_unlock(
2261 peer); /* group->peer list reference */
2262 list_delete_node(peer->group->peer, pn);
2263 }
2264 peer->group = NULL;
2265 }
2266
2267 /* Withdraw all information from routing table. We can not use
2268 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
2269 * executed after peer structure is deleted.
2270 */
2271 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2272 bgp_stop(peer);
2273 UNSET_FLAG(peer->flags, PEER_FLAG_DELETE);
2274
2275 if (peer->doppelganger) {
2276 peer->doppelganger->doppelganger = NULL;
2277 peer->doppelganger = NULL;
2278 }
2279
2280 UNSET_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
2281 bgp_fsm_change_status(peer, Deleted);
2282
2283 /* Remove from NHT */
2284 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
2285 bgp_unlink_nexthop_by_peer(peer);
2286
2287 /* Password configuration */
2288 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD)) {
2289 XFREE(MTYPE_PEER_PASSWORD, peer->password);
2290
2291 if (!accept_peer && !BGP_PEER_SU_UNSPEC(peer)
2292 && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
2293 bgp_md5_unset(peer);
2294 }
2295
2296 bgp_timer_set(peer); /* stops all timers for Deleted */
2297
2298 /* Delete from all peer list. */
2299 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
2300 && (pn = listnode_lookup(bgp->peer, peer))) {
2301 peer_unlock(peer); /* bgp peer list reference */
2302 list_delete_node(bgp->peer, pn);
2303 hash_release(bgp->peerhash, peer);
2304 }
2305
2306 /* Buffers. */
2307 if (peer->ibuf) {
2308 stream_fifo_free(peer->ibuf);
2309 peer->ibuf = NULL;
2310 }
2311
2312 if (peer->obuf) {
2313 stream_fifo_free(peer->obuf);
2314 peer->obuf = NULL;
2315 }
2316
2317 if (peer->ibuf_work) {
2318 ringbuf_del(peer->ibuf_work);
2319 peer->ibuf_work = NULL;
2320 }
2321
2322 if (peer->obuf_work) {
2323 stream_free(peer->obuf_work);
2324 peer->obuf_work = NULL;
2325 }
2326
2327 if (peer->scratch) {
2328 stream_free(peer->scratch);
2329 peer->scratch = NULL;
2330 }
2331
2332 /* Local and remote addresses. */
2333 if (peer->su_local) {
2334 sockunion_free(peer->su_local);
2335 peer->su_local = NULL;
2336 }
2337
2338 if (peer->su_remote) {
2339 sockunion_free(peer->su_remote);
2340 peer->su_remote = NULL;
2341 }
2342
2343 /* Free filter related memory. */
2344 FOREACH_AFI_SAFI (afi, safi) {
2345 filter = &peer->filter[afi][safi];
2346
2347 for (i = FILTER_IN; i < FILTER_MAX; i++) {
2348 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[i].name);
2349 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[i].name);
2350 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name);
2351 }
2352
2353 for (i = RMAP_IN; i < RMAP_MAX; i++) {
2354 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[i].name);
2355 }
2356
2357 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
2358 XFREE(MTYPE_ROUTE_MAP_NAME, peer->default_rmap[afi][safi].name);
2359 }
2360
2361 FOREACH_AFI_SAFI (afi, safi)
2362 peer_af_delete(peer, afi, safi);
2363
2364 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
2365 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
2366
2367 peer_unlock(peer); /* initial reference */
2368
2369 return 0;
2370 }
2371
2372 static int peer_group_cmp(struct peer_group *g1, struct peer_group *g2)
2373 {
2374 return strcmp(g1->name, g2->name);
2375 }
2376
2377 /* Peer group cofiguration. */
2378 static struct peer_group *peer_group_new(void)
2379 {
2380 return XCALLOC(MTYPE_PEER_GROUP, sizeof(struct peer_group));
2381 }
2382
2383 static void peer_group_free(struct peer_group *group)
2384 {
2385 XFREE(MTYPE_PEER_GROUP, group);
2386 }
2387
2388 struct peer_group *peer_group_lookup(struct bgp *bgp, const char *name)
2389 {
2390 struct peer_group *group;
2391 struct listnode *node, *nnode;
2392
2393 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
2394 if (strcmp(group->name, name) == 0)
2395 return group;
2396 }
2397 return NULL;
2398 }
2399
2400 struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
2401 {
2402 struct peer_group *group;
2403 afi_t afi;
2404
2405 group = peer_group_lookup(bgp, name);
2406 if (group)
2407 return group;
2408
2409 group = peer_group_new();
2410 group->bgp = bgp;
2411 XFREE(MTYPE_PEER_GROUP_HOST, group->name);
2412 group->name = XSTRDUP(MTYPE_PEER_GROUP_HOST, name);
2413 group->peer = list_new();
2414 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2415 group->listen_range[afi] = list_new();
2416 group->conf = peer_new(bgp);
2417 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
2418 group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
2419 XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
2420 group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name);
2421 group->conf->group = group;
2422 group->conf->as = 0;
2423 group->conf->ttl = BGP_DEFAULT_TTL;
2424 group->conf->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
2425 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
2426 SET_FLAG(group->conf->sflags, PEER_STATUS_GROUP);
2427 listnode_add_sort(bgp->group, group);
2428
2429 return group;
2430 }
2431
2432 static void peer_group2peer_config_copy(struct peer_group *group,
2433 struct peer *peer)
2434 {
2435 uint32_t flags_tmp;
2436 struct peer *conf;
2437
2438 conf = group->conf;
2439
2440 /* remote-as */
2441 if (conf->as)
2442 peer->as = conf->as;
2443
2444 /* local-as */
2445 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_LOCAL_AS))
2446 peer->change_local_as = conf->change_local_as;
2447
2448 /* If peer-group has configured TTL then override it */
2449 if (conf->ttl != BGP_DEFAULT_TTL)
2450 peer->ttl = conf->ttl;
2451
2452 /* GTSM hops */
2453 peer->gtsm_hops = conf->gtsm_hops;
2454
2455 /* peer flags apply */
2456 flags_tmp = conf->flags & ~peer->flags_override;
2457 flags_tmp ^= conf->flags_invert ^ peer->flags_invert;
2458 flags_tmp &= ~peer->flags_override;
2459
2460 UNSET_FLAG(peer->flags, ~peer->flags_override);
2461 SET_FLAG(peer->flags, flags_tmp);
2462 SET_FLAG(peer->flags_invert, conf->flags_invert);
2463
2464 /* peer timers apply */
2465 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER)) {
2466 PEER_ATTR_INHERIT(peer, group, holdtime);
2467 PEER_ATTR_INHERIT(peer, group, keepalive);
2468 }
2469
2470 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_CONNECT)) {
2471 PEER_ATTR_INHERIT(peer, group, connect);
2472 if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_CONNECT))
2473 peer->v_connect = conf->connect;
2474 else
2475 peer->v_connect = peer->bgp->default_connect_retry;
2476 }
2477
2478 /* advertisement-interval apply */
2479 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_ROUTEADV)) {
2480 PEER_ATTR_INHERIT(peer, group, routeadv);
2481 if (CHECK_FLAG(conf->flags, PEER_FLAG_ROUTEADV))
2482 peer->v_routeadv = conf->routeadv;
2483 else
2484 peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP)
2485 ? BGP_DEFAULT_IBGP_ROUTEADV
2486 : BGP_DEFAULT_EBGP_ROUTEADV;
2487 }
2488
2489 /* capability extended-nexthop apply */
2490 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE))
2491 if (CHECK_FLAG(conf->flags, PEER_FLAG_CAPABILITY_ENHE))
2492 SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
2493
2494 /* password apply */
2495 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_PASSWORD))
2496 PEER_STR_ATTR_INHERIT(peer, group, password,
2497 MTYPE_PEER_PASSWORD);
2498
2499 if (!BGP_PEER_SU_UNSPEC(peer))
2500 bgp_md5_set(peer);
2501
2502 /* update-source apply */
2503 if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_UPDATE_SOURCE)) {
2504 if (conf->update_source) {
2505 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2506 PEER_SU_ATTR_INHERIT(peer, group, update_source);
2507 } else if (conf->update_if) {
2508 sockunion_free(peer->update_source);
2509 PEER_STR_ATTR_INHERIT(peer, group, update_if,
2510 MTYPE_PEER_UPDATE_SOURCE);
2511 }
2512 }
2513
2514 /* Update GR flags for the peer. */
2515 bgp_peer_gr_flags_update(peer);
2516
2517 bgp_bfd_peer_group2peer_copy(conf, peer);
2518 }
2519
2520 /* Peer group's remote AS configuration. */
2521 int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
2522 int as_type)
2523 {
2524 struct peer_group *group;
2525 struct peer *peer;
2526 struct listnode *node, *nnode;
2527
2528 group = peer_group_lookup(bgp, group_name);
2529 if (!group)
2530 return -1;
2531
2532 if ((as_type == group->conf->as_type) && (group->conf->as == *as))
2533 return 0;
2534
2535
2536 /* When we setup peer-group AS number all peer group member's AS
2537 number must be updated to same number. */
2538 peer_as_change(group->conf, *as, as_type);
2539
2540 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2541 if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
2542 || (peer->as_type != as_type))
2543 peer_as_change(peer, *as, as_type);
2544 }
2545
2546 return 0;
2547 }
2548
2549 void peer_notify_unconfig(struct peer *peer)
2550 {
2551 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2552 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2553 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
2554 }
2555
2556 void peer_group_notify_unconfig(struct peer_group *group)
2557 {
2558 struct peer *peer, *other;
2559 struct listnode *node, *nnode;
2560
2561 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2562 other = peer->doppelganger;
2563 if (other && other->status != Deleted) {
2564 other->group = NULL;
2565 peer_notify_unconfig(other);
2566 } else
2567 peer_notify_unconfig(peer);
2568 }
2569 }
2570
2571 int peer_group_delete(struct peer_group *group)
2572 {
2573 struct bgp *bgp;
2574 struct peer *peer;
2575 struct prefix *prefix;
2576 struct peer *other;
2577 struct listnode *node, *nnode;
2578 afi_t afi;
2579
2580 bgp = group->bgp;
2581
2582 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2583 other = peer->doppelganger;
2584
2585 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
2586 bgp_zebra_terminate_radv(bgp, peer);
2587
2588 peer_delete(peer);
2589 if (other && other->status != Deleted) {
2590 other->group = NULL;
2591 peer_delete(other);
2592 }
2593 }
2594 list_delete(&group->peer);
2595
2596 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2597 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
2598 prefix)) {
2599 prefix_free(&prefix);
2600 }
2601 list_delete(&group->listen_range[afi]);
2602 }
2603
2604 XFREE(MTYPE_PEER_GROUP_HOST, group->name);
2605 group->name = NULL;
2606
2607 bfd_info_free(&(group->conf->bfd_info));
2608
2609 group->conf->group = NULL;
2610 peer_delete(group->conf);
2611
2612 /* Delete from all peer_group list. */
2613 listnode_delete(bgp->group, group);
2614
2615 peer_group_free(group);
2616
2617 return 0;
2618 }
2619
2620 int peer_group_remote_as_delete(struct peer_group *group)
2621 {
2622 struct peer *peer, *other;
2623 struct listnode *node, *nnode;
2624
2625 if ((group->conf->as_type == AS_UNSPECIFIED)
2626 || ((!group->conf->as) && (group->conf->as_type == AS_SPECIFIED)))
2627 return 0;
2628
2629 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2630 other = peer->doppelganger;
2631
2632 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE))
2633 bgp_zebra_terminate_radv(peer->bgp, peer);
2634
2635 peer_delete(peer);
2636
2637 if (other && other->status != Deleted) {
2638 other->group = NULL;
2639 peer_delete(other);
2640 }
2641 }
2642 list_delete_all_node(group->peer);
2643
2644 group->conf->as = 0;
2645 group->conf->as_type = AS_UNSPECIFIED;
2646
2647 return 0;
2648 }
2649
2650 int peer_group_listen_range_add(struct peer_group *group, struct prefix *range)
2651 {
2652 struct prefix *prefix;
2653 struct listnode *node, *nnode;
2654 afi_t afi;
2655
2656 afi = family2afi(range->family);
2657
2658 /* Group needs remote AS configured. */
2659 if (group->conf->as_type == AS_UNSPECIFIED)
2660 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
2661
2662 /* Ensure no duplicates. Currently we don't care about overlaps. */
2663 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) {
2664 if (prefix_same(range, prefix))
2665 return 0;
2666 }
2667
2668 prefix = prefix_new();
2669 prefix_copy(prefix, range);
2670 listnode_add(group->listen_range[afi], prefix);
2671
2672 /* Update passwords for new ranges */
2673 if (group->conf->password)
2674 bgp_md5_set_prefix(prefix, group->conf->password);
2675
2676 return 0;
2677 }
2678
2679 int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
2680 {
2681 struct prefix *prefix, prefix2;
2682 struct listnode *node, *nnode;
2683 struct peer *peer;
2684 afi_t afi;
2685 char buf[PREFIX2STR_BUFFER];
2686
2687 afi = family2afi(range->family);
2688
2689 /* Identify the listen range. */
2690 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode, prefix)) {
2691 if (prefix_same(range, prefix))
2692 break;
2693 }
2694
2695 if (!prefix)
2696 return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND;
2697
2698 prefix2str(prefix, buf, sizeof(buf));
2699
2700 /* Dispose off any dynamic neighbors that exist due to this listen range
2701 */
2702 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
2703 if (!peer_dynamic_neighbor(peer))
2704 continue;
2705
2706 sockunion2hostprefix(&peer->su, &prefix2);
2707 if (prefix_match(prefix, &prefix2)) {
2708 if (bgp_debug_neighbor_events(peer))
2709 zlog_debug(
2710 "Deleting dynamic neighbor %s group %s upon delete of listen range %s",
2711 peer->host, group->name, buf);
2712 peer_delete(peer);
2713 }
2714 }
2715
2716 /* Get rid of the listen range */
2717 listnode_delete(group->listen_range[afi], prefix);
2718
2719 /* Remove passwords for deleted ranges */
2720 if (group->conf->password)
2721 bgp_md5_unset_prefix(prefix);
2722
2723 return 0;
2724 }
2725
2726 /* Bind specified peer to peer group. */
2727 int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
2728 struct peer_group *group, as_t *as)
2729 {
2730 int first_member = 0;
2731 afi_t afi;
2732 safi_t safi;
2733 bgp_peer_sort_t ptype, gtype;
2734
2735 /* Lookup the peer. */
2736 if (!peer)
2737 peer = peer_lookup(bgp, su);
2738
2739 /* The peer exist, bind it to the peer-group */
2740 if (peer) {
2741 /* When the peer already belongs to a peer-group, check the
2742 * consistency. */
2743 if (peer_group_active(peer)) {
2744
2745 /* The peer is already bound to the peer-group,
2746 * nothing to do
2747 */
2748 if (strcmp(peer->group->name, group->name) == 0)
2749 return 0;
2750 else
2751 return BGP_ERR_PEER_GROUP_CANT_CHANGE;
2752 }
2753
2754 /* The peer has not specified a remote-as, inherit it from the
2755 * peer-group */
2756 if (peer->as_type == AS_UNSPECIFIED) {
2757 peer->as_type = group->conf->as_type;
2758 peer->as = group->conf->as;
2759 peer->sort = group->conf->sort;
2760 }
2761
2762 ptype = peer_sort(peer);
2763 if (!group->conf->as && ptype != BGP_PEER_UNSPECIFIED) {
2764 gtype = peer_sort(group->conf);
2765 if ((gtype != BGP_PEER_INTERNAL) && (gtype != ptype)) {
2766 if (as)
2767 *as = peer->as;
2768 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
2769 }
2770
2771 if (gtype == BGP_PEER_INTERNAL)
2772 first_member = 1;
2773 }
2774
2775 peer_group2peer_config_copy(group, peer);
2776
2777 FOREACH_AFI_SAFI (afi, safi) {
2778 if (group->conf->afc[afi][safi]) {
2779 peer->afc[afi][safi] = 1;
2780
2781 if (peer_af_find(peer, afi, safi)
2782 || peer_af_create(peer, afi, safi)) {
2783 peer_group2peer_config_copy_af(
2784 group, peer, afi, safi);
2785 }
2786 } else if (peer->afc[afi][safi])
2787 peer_deactivate(peer, afi, safi);
2788 }
2789
2790 if (peer->group) {
2791 assert(group && peer->group == group);
2792 } else {
2793 listnode_delete(bgp->peer, peer);
2794
2795 peer->group = group;
2796 listnode_add_sort(bgp->peer, peer);
2797
2798 peer = peer_lock(peer); /* group->peer list reference */
2799 listnode_add(group->peer, peer);
2800 }
2801
2802 if (first_member) {
2803 gtype = peer_sort(group->conf);
2804 /* Advertisement-interval reset */
2805 if (!CHECK_FLAG(group->conf->flags,
2806 PEER_FLAG_ROUTEADV)) {
2807 group->conf->v_routeadv =
2808 (gtype == BGP_PEER_IBGP)
2809 ? BGP_DEFAULT_IBGP_ROUTEADV
2810 : BGP_DEFAULT_EBGP_ROUTEADV;
2811 }
2812
2813 /* ebgp-multihop reset */
2814 if (gtype == BGP_PEER_IBGP)
2815 group->conf->ttl = MAXTTL;
2816
2817 /* local-as reset */
2818 if (gtype != BGP_PEER_EBGP) {
2819 group->conf->change_local_as = 0;
2820 peer_flag_unset(group->conf,
2821 PEER_FLAG_LOCAL_AS);
2822 peer_flag_unset(group->conf,
2823 PEER_FLAG_LOCAL_AS_NO_PREPEND);
2824 peer_flag_unset(group->conf,
2825 PEER_FLAG_LOCAL_AS_REPLACE_AS);
2826 }
2827 }
2828
2829 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
2830
2831 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
2832 peer->last_reset = PEER_DOWN_RMAP_BIND;
2833 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
2834 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2835 } else {
2836 bgp_session_reset(peer);
2837 }
2838 }
2839
2840 /* Create a new peer. */
2841 else {
2842 if ((group->conf->as_type == AS_SPECIFIED)
2843 && (!group->conf->as)) {
2844 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
2845 }
2846
2847 peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
2848 group->conf->as_type, 0, 0, group);
2849
2850 peer = peer_lock(peer); /* group->peer list reference */
2851 listnode_add(group->peer, peer);
2852
2853 peer_group2peer_config_copy(group, peer);
2854
2855 /* If the peer-group is active for this afi/safi then activate
2856 * for this peer */
2857 FOREACH_AFI_SAFI (afi, safi) {
2858 if (group->conf->afc[afi][safi]) {
2859 peer->afc[afi][safi] = 1;
2860 peer_af_create(peer, afi, safi);
2861 peer_group2peer_config_copy_af(group, peer, afi,
2862 safi);
2863 } else if (peer->afc[afi][safi])
2864 peer_deactivate(peer, afi, safi);
2865 }
2866
2867 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
2868
2869 /* Set up peer's events and timers. */
2870 if (peer_active(peer))
2871 bgp_timer_set(peer);
2872 }
2873
2874 return 0;
2875 }
2876
2877 static int bgp_startup_timer_expire(struct thread *thread)
2878 {
2879 struct bgp *bgp;
2880
2881 bgp = THREAD_ARG(thread);
2882 bgp->t_startup = NULL;
2883
2884 return 0;
2885 }
2886
2887 /*
2888 * On shutdown we call the cleanup function which
2889 * does a free of the link list nodes, free up
2890 * the data we are pointing at too.
2891 */
2892 static void bgp_vrf_string_name_delete(void *data)
2893 {
2894 char *vname = data;
2895
2896 XFREE(MTYPE_TMP, vname);
2897 }
2898
2899 /* BGP instance creation by `router bgp' commands. */
2900 static struct bgp *bgp_create(as_t *as, const char *name,
2901 enum bgp_instance_type inst_type)
2902 {
2903 struct bgp *bgp;
2904 afi_t afi;
2905 safi_t safi;
2906
2907 if ((bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp))) == NULL)
2908 return NULL;
2909
2910 if (BGP_DEBUG(zebra, ZEBRA)) {
2911 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
2912 zlog_debug("Creating Default VRF, AS %u", *as);
2913 else
2914 zlog_debug("Creating %s %s, AS %u",
2915 (inst_type == BGP_INSTANCE_TYPE_VRF)
2916 ? "VRF"
2917 : "VIEW",
2918 name, *as);
2919 }
2920
2921 /* Default the EVPN VRF to the default one */
2922 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !bgp_master.bgp_evpn) {
2923 bgp_lock(bgp);
2924 bm->bgp_evpn = bgp;
2925 }
2926
2927 bgp_lock(bgp);
2928 bgp->heuristic_coalesce = true;
2929 bgp->inst_type = inst_type;
2930 bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
2931 : VRF_UNKNOWN;
2932 bgp->peer_self = peer_new(bgp);
2933 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
2934 bgp->peer_self->host =
2935 XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
2936 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->hostname);
2937 if (cmd_hostname_get())
2938 bgp->peer_self->hostname =
2939 XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_hostname_get());
2940
2941 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->domainname);
2942 if (cmd_domainname_get())
2943 bgp->peer_self->domainname =
2944 XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get());
2945 bgp->peer = list_new();
2946 bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
2947 bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same,
2948 "BGP Peer Hash");
2949 bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
2950
2951 bgp->group = list_new();
2952 bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
2953
2954 FOREACH_AFI_SAFI (afi, safi) {
2955 bgp->route[afi][safi] = bgp_table_init(bgp, afi, safi);
2956 bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi, safi);
2957 bgp->rib[afi][safi] = bgp_table_init(bgp, afi, safi);
2958
2959 /* Enable maximum-paths */
2960 bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
2961 multipath_num, 0);
2962 bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
2963 multipath_num, 0);
2964 /* Initialize graceful restart info */
2965 bgp->gr_info[afi][safi].eor_required = 0;
2966 bgp->gr_info[afi][safi].eor_received = 0;
2967 bgp->gr_info[afi][safi].t_select_deferral = NULL;
2968 bgp->gr_info[afi][safi].t_route_select = NULL;
2969 bgp->gr_info[afi][safi].route_list = list_new();
2970 }
2971
2972 bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
2973 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
2974 bgp->default_subgroup_pkt_queue_max =
2975 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
2976 bgp_timers_unset(bgp);
2977 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
2978 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
2979 bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME;
2980 bgp->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME;
2981 bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
2982 bgp->dynamic_neighbors_count = 0;
2983 bgp->lb_ref_bw = BGP_LINK_BW_REF_BW;
2984 bgp->lb_handling = BGP_LINK_BW_ECMP;
2985 bgp->reject_as_sets = false;
2986 bgp_addpath_init_bgp_data(&bgp->tx_addpath);
2987
2988 bgp->as = *as;
2989
2990 #ifdef ENABLE_BGP_VNC
2991 if (inst_type != BGP_INSTANCE_TYPE_VRF) {
2992 bgp->rfapi = bgp_rfapi_new(bgp);
2993 assert(bgp->rfapi);
2994 assert(bgp->rfapi_cfg);
2995 }
2996 #endif /* ENABLE_BGP_VNC */
2997
2998 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2999 bgp->vpn_policy[afi].bgp = bgp;
3000 bgp->vpn_policy[afi].afi = afi;
3001 bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
3002 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent =
3003 MPLS_LABEL_NONE;
3004
3005 bgp->vpn_policy[afi].import_vrf = list_new();
3006 bgp->vpn_policy[afi].import_vrf->del =
3007 bgp_vrf_string_name_delete;
3008 bgp->vpn_policy[afi].export_vrf = list_new();
3009 bgp->vpn_policy[afi].export_vrf->del =
3010 bgp_vrf_string_name_delete;
3011 }
3012 if (name)
3013 bgp->name = XSTRDUP(MTYPE_BGP, name);
3014
3015 thread_add_timer(bm->master, bgp_startup_timer_expire, bgp,
3016 bgp->restart_time, &bgp->t_startup);
3017
3018 /* printable name we can use in debug messages */
3019 if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
3020 bgp->name_pretty = XSTRDUP(MTYPE_BGP, "VRF default");
3021 } else {
3022 const char *n;
3023 int len;
3024
3025 if (bgp->name)
3026 n = bgp->name;
3027 else
3028 n = "?";
3029
3030 len = 4 + 1 + strlen(n) + 1; /* "view foo\0" */
3031
3032 bgp->name_pretty = XCALLOC(MTYPE_BGP, len);
3033 snprintf(bgp->name_pretty, len, "%s %s",
3034 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3035 ? "VRF"
3036 : "VIEW",
3037 n);
3038 }
3039
3040 atomic_store_explicit(&bgp->wpkt_quanta, BGP_WRITE_PACKET_MAX,
3041 memory_order_relaxed);
3042 atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
3043 memory_order_relaxed);
3044 bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
3045
3046 QOBJ_REG(bgp, bgp);
3047
3048 update_bgp_group_init(bgp);
3049
3050 /* assign a unique rd id for auto derivation of vrf's RD */
3051 bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id);
3052
3053 bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO,
3054 sizeof(struct bgp_evpn_info));
3055
3056 bgp_evpn_init(bgp);
3057 bgp_pbr_init(bgp);
3058
3059 /*initilize global GR FSM */
3060 bgp_global_gr_init(bgp);
3061 return bgp;
3062 }
3063
3064 /* Return the "default VRF" instance of BGP. */
3065 struct bgp *bgp_get_default(void)
3066 {
3067 struct bgp *bgp;
3068 struct listnode *node, *nnode;
3069
3070 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3071 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3072 return bgp;
3073 return NULL;
3074 }
3075
3076 /* Lookup BGP entry. */
3077 struct bgp *bgp_lookup(as_t as, const char *name)
3078 {
3079 struct bgp *bgp;
3080 struct listnode *node, *nnode;
3081
3082 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3083 if (bgp->as == as
3084 && ((bgp->name == NULL && name == NULL)
3085 || (bgp->name && name && strcmp(bgp->name, name) == 0)))
3086 return bgp;
3087 return NULL;
3088 }
3089
3090 /* Lookup BGP structure by view name. */
3091 struct bgp *bgp_lookup_by_name(const char *name)
3092 {
3093 struct bgp *bgp;
3094 struct listnode *node, *nnode;
3095
3096 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3097 if ((bgp->name == NULL && name == NULL)
3098 || (bgp->name && name && strcmp(bgp->name, name) == 0))
3099 return bgp;
3100 return NULL;
3101 }
3102
3103 /* Lookup BGP instance based on VRF id. */
3104 /* Note: Only to be used for incoming messages from Zebra. */
3105 struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
3106 {
3107 struct vrf *vrf;
3108
3109 /* Lookup VRF (in tree) and follow link. */
3110 vrf = vrf_lookup_by_id(vrf_id);
3111 if (!vrf)
3112 return NULL;
3113 return (vrf->info) ? (struct bgp *)vrf->info : NULL;
3114 }
3115
3116 /* Sets the BGP instance where EVPN is enabled */
3117 void bgp_set_evpn(struct bgp *bgp)
3118 {
3119 if (bm->bgp_evpn == bgp)
3120 return;
3121
3122 /* First, release the reference count we hold on the instance */
3123 if (bm->bgp_evpn)
3124 bgp_unlock(bm->bgp_evpn);
3125
3126 bm->bgp_evpn = bgp;
3127
3128 /* Increase the reference count on this new VRF */
3129 if (bm->bgp_evpn)
3130 bgp_lock(bm->bgp_evpn);
3131 }
3132
3133 /* Returns the BGP instance where EVPN is enabled, if any */
3134 struct bgp *bgp_get_evpn(void)
3135 {
3136 return bm->bgp_evpn;
3137 }
3138
3139 /* handle socket creation or deletion, if necessary
3140 * this is called for all new BGP instances
3141 */
3142 int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
3143 bool create)
3144 {
3145 int ret = 0;
3146
3147 /* Create BGP server socket, if listen mode not disabled */
3148 if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
3149 return 0;
3150 if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3151 /*
3152 * suppress vrf socket
3153 */
3154 if (!create) {
3155 bgp_close_vrf_socket(bgp);
3156 return 0;
3157 }
3158 if (vrf == NULL)
3159 return BGP_ERR_INVALID_VALUE;
3160 /* do nothing
3161 * if vrf_id did not change
3162 */
3163 if (vrf->vrf_id == old_vrf_id)
3164 return 0;
3165 if (old_vrf_id != VRF_UNKNOWN) {
3166 /* look for old socket. close it. */
3167 bgp_close_vrf_socket(bgp);
3168 }
3169 /* if backend is not yet identified ( VRF_UNKNOWN) then
3170 * creation will be done later
3171 */
3172 if (vrf->vrf_id == VRF_UNKNOWN)
3173 return 0;
3174 ret = bgp_socket(bgp, bm->port, bm->address);
3175 if (ret < 0)
3176 return BGP_ERR_INVALID_VALUE;
3177 return 0;
3178 } else
3179 return bgp_check_main_socket(create, bgp);
3180 }
3181
3182 /* Called from VTY commands. */
3183 int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
3184 enum bgp_instance_type inst_type)
3185 {
3186 struct bgp *bgp;
3187 struct vrf *vrf = NULL;
3188
3189 /* Multiple instance check. */
3190 if (name)
3191 bgp = bgp_lookup_by_name(name);
3192 else
3193 bgp = bgp_get_default();
3194
3195 /* Already exists. */
3196 if (bgp) {
3197 if (bgp->as != *as) {
3198 *as = bgp->as;
3199 return BGP_ERR_INSTANCE_MISMATCH;
3200 }
3201 if (bgp->inst_type != inst_type)
3202 return BGP_ERR_INSTANCE_MISMATCH;
3203 *bgp_val = bgp;
3204 return BGP_SUCCESS;
3205 }
3206
3207 bgp = bgp_create(as, name, inst_type);
3208 if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name)
3209 bgp->vrf_id = vrf_generate_id();
3210 bgp_router_id_set(bgp, &bgp->router_id_zebra, true);
3211 bgp_address_init(bgp);
3212 bgp_tip_hash_init(bgp);
3213 bgp_scan_init(bgp);
3214 *bgp_val = bgp;
3215
3216 bgp->t_rmap_def_originate_eval = NULL;
3217
3218 /* If Default instance or VRF, link to the VRF structure, if present. */
3219 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
3220 || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3221 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3222 if (vrf)
3223 bgp_vrf_link(bgp, vrf);
3224 }
3225 /* BGP server socket already processed if BGP instance
3226 * already part of the list
3227 */
3228 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, true);
3229 listnode_add(bm->bgp, bgp);
3230
3231 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3232 if (BGP_DEBUG(zebra, ZEBRA))
3233 zlog_debug("%s: Registering BGP instance %s to zebra",
3234 __func__, name);
3235 bgp_zebra_instance_register(bgp);
3236 }
3237
3238 return BGP_CREATED;
3239 }
3240
3241 /*
3242 * Make BGP instance "up". Applies only to VRFs (non-default) and
3243 * implies the VRF has been learnt from Zebra.
3244 */
3245 void bgp_instance_up(struct bgp *bgp)
3246 {
3247 struct peer *peer;
3248 struct listnode *node, *next;
3249
3250 /* Register with zebra. */
3251 bgp_zebra_instance_register(bgp);
3252
3253 /* Kick off any peers that may have been configured. */
3254 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3255 if (!BGP_PEER_START_SUPPRESSED(peer))
3256 BGP_EVENT_ADD(peer, BGP_Start);
3257 }
3258
3259 /* Process any networks that have been configured. */
3260 bgp_static_add(bgp);
3261 }
3262
3263 /*
3264 * Make BGP instance "down". Applies only to VRFs (non-default) and
3265 * implies the VRF has been deleted by Zebra.
3266 */
3267 void bgp_instance_down(struct bgp *bgp)
3268 {
3269 struct peer *peer;
3270 struct listnode *node;
3271 struct listnode *next;
3272
3273 /* Stop timers. */
3274 if (bgp->t_rmap_def_originate_eval) {
3275 BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
3276 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3277 why? */
3278 }
3279
3280 /* Bring down peers, so corresponding routes are purged. */
3281 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3282 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3283 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3284 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3285 else
3286 bgp_session_reset(peer);
3287 }
3288
3289 /* Purge network and redistributed routes. */
3290 bgp_purge_static_redist_routes(bgp);
3291
3292 /* Cleanup registered nexthops (flags) */
3293 bgp_cleanup_nexthops(bgp);
3294 }
3295
3296 /* Delete BGP instance. */
3297 int bgp_delete(struct bgp *bgp)
3298 {
3299 struct peer *peer;
3300 struct peer_group *group;
3301 struct listnode *node, *next;
3302 struct vrf *vrf;
3303 afi_t afi;
3304 safi_t safi;
3305 int i;
3306 struct graceful_restart_info *gr_info;
3307
3308 assert(bgp);
3309
3310 hook_call(bgp_inst_delete, bgp);
3311
3312 THREAD_OFF(bgp->t_startup);
3313 THREAD_OFF(bgp->t_maxmed_onstartup);
3314 THREAD_OFF(bgp->t_update_delay);
3315 THREAD_OFF(bgp->t_establish_wait);
3316
3317 /* Set flag indicating bgp instance delete in progress */
3318 SET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS);
3319
3320 /* Delete the graceful restart info */
3321 FOREACH_AFI_SAFI (afi, safi) {
3322 gr_info = &bgp->gr_info[afi][safi];
3323 if (!gr_info)
3324 continue;
3325
3326 BGP_TIMER_OFF(gr_info->t_select_deferral);
3327 BGP_TIMER_OFF(gr_info->t_route_select);
3328 if (gr_info->route_list)
3329 list_delete(&gr_info->route_list);
3330 }
3331
3332 if (BGP_DEBUG(zebra, ZEBRA)) {
3333 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3334 zlog_debug("Deleting Default VRF");
3335 else
3336 zlog_debug("Deleting %s %s",
3337 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3338 ? "VRF"
3339 : "VIEW",
3340 bgp->name);
3341 }
3342
3343 /* unmap from RT list */
3344 bgp_evpn_vrf_delete(bgp);
3345
3346 /* unmap bgp vrf label */
3347 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP);
3348 vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6);
3349
3350 /* Stop timers. */
3351 if (bgp->t_rmap_def_originate_eval) {
3352 BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
3353 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3354 why? */
3355 }
3356
3357 /* Inform peers we're going down. */
3358 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3359 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3360 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3361 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3362 }
3363
3364 /* Delete static routes (networks). */
3365 bgp_static_delete(bgp);
3366
3367 /* Unset redistribution. */
3368 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3369 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3370 if (i != ZEBRA_ROUTE_BGP)
3371 bgp_redistribute_unset(bgp, afi, i, 0);
3372
3373 /* Free peers and peer-groups. */
3374 for (ALL_LIST_ELEMENTS(bgp->group, node, next, group))
3375 peer_group_delete(group);
3376
3377 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
3378 peer_delete(peer);
3379
3380 if (bgp->peer_self) {
3381 peer_delete(bgp->peer_self);
3382 bgp->peer_self = NULL;
3383 }
3384
3385 update_bgp_group_free(bgp);
3386
3387 /* TODO - Other memory may need to be freed - e.g., NHT */
3388
3389 #ifdef ENABLE_BGP_VNC
3390 rfapi_delete(bgp);
3391 #endif
3392 bgp_cleanup_routes(bgp);
3393
3394 for (afi = 0; afi < AFI_MAX; ++afi) {
3395 if (!bgp->vpn_policy[afi].import_redirect_rtlist)
3396 continue;
3397 ecommunity_free(
3398 &bgp->vpn_policy[afi]
3399 .import_redirect_rtlist);
3400 bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
3401 }
3402
3403 /* Deregister from Zebra, if needed */
3404 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
3405 if (BGP_DEBUG(zebra, ZEBRA))
3406 zlog_debug(
3407 "%s: deregistering this bgp %s instance from zebra",
3408 __func__, bgp->name);
3409 bgp_zebra_instance_deregister(bgp);
3410 }
3411
3412 /* Remove visibility via the master list - there may however still be
3413 * routes to be processed still referencing the struct bgp.
3414 */
3415 listnode_delete(bm->bgp, bgp);
3416
3417 /* Free interfaces in this instance. */
3418 bgp_if_finish(bgp);
3419
3420 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3421 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
3422 if (vrf)
3423 bgp_vrf_unlink(bgp, vrf);
3424
3425 /* Update EVPN VRF pointer */
3426 if (bm->bgp_evpn == bgp) {
3427 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3428 bgp_set_evpn(NULL);
3429 else
3430 bgp_set_evpn(bgp_get_default());
3431 }
3432
3433 thread_master_free_unused(bm->master);
3434 bgp_unlock(bgp); /* initial reference */
3435
3436 return 0;
3437 }
3438
3439 void bgp_free(struct bgp *bgp)
3440 {
3441 afi_t afi;
3442 safi_t safi;
3443 struct bgp_table *table;
3444 struct bgp_dest *dest;
3445 struct bgp_rmap *rmap;
3446
3447 QOBJ_UNREG(bgp);
3448
3449 list_delete(&bgp->group);
3450 list_delete(&bgp->peer);
3451
3452 if (bgp->peerhash) {
3453 hash_free(bgp->peerhash);
3454 bgp->peerhash = NULL;
3455 }
3456
3457 FOREACH_AFI_SAFI (afi, safi) {
3458 /* Special handling for 2-level routing tables. */
3459 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
3460 || safi == SAFI_EVPN) {
3461 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
3462 dest = bgp_route_next(dest)) {
3463 table = bgp_dest_get_bgp_table_info(dest);
3464 bgp_table_finish(&table);
3465 }
3466 }
3467 if (bgp->route[afi][safi])
3468 bgp_table_finish(&bgp->route[afi][safi]);
3469 if (bgp->aggregate[afi][safi])
3470 bgp_table_finish(&bgp->aggregate[afi][safi]);
3471 if (bgp->rib[afi][safi])
3472 bgp_table_finish(&bgp->rib[afi][safi]);
3473 rmap = &bgp->table_map[afi][safi];
3474 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
3475 }
3476
3477 bgp_scan_finish(bgp);
3478 bgp_address_destroy(bgp);
3479 bgp_tip_hash_destroy(bgp);
3480
3481 /* release the auto RD id */
3482 bf_release_index(bm->rd_idspace, bgp->vrf_rd_id);
3483
3484 bgp_evpn_cleanup(bgp);
3485 bgp_pbr_cleanup(bgp);
3486 XFREE(MTYPE_BGP_EVPN_INFO, bgp->evpn_info);
3487
3488 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
3489 vpn_policy_direction_t dir;
3490
3491 if (bgp->vpn_policy[afi].import_vrf)
3492 list_delete(&bgp->vpn_policy[afi].import_vrf);
3493 if (bgp->vpn_policy[afi].export_vrf)
3494 list_delete(&bgp->vpn_policy[afi].export_vrf);
3495
3496 dir = BGP_VPN_POLICY_DIR_FROMVPN;
3497 if (bgp->vpn_policy[afi].rtlist[dir])
3498 ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3499 dir = BGP_VPN_POLICY_DIR_TOVPN;
3500 if (bgp->vpn_policy[afi].rtlist[dir])
3501 ecommunity_free(&bgp->vpn_policy[afi].rtlist[dir]);
3502 }
3503
3504 XFREE(MTYPE_BGP, bgp->name);
3505 XFREE(MTYPE_BGP, bgp->name_pretty);
3506
3507 XFREE(MTYPE_BGP, bgp);
3508 }
3509
3510 struct peer *peer_lookup_by_conf_if(struct bgp *bgp, const char *conf_if)
3511 {
3512 struct peer *peer;
3513 struct listnode *node, *nnode;
3514
3515 if (!conf_if)
3516 return NULL;
3517
3518 if (bgp != NULL) {
3519 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3520 if (peer->conf_if && !strcmp(peer->conf_if, conf_if)
3521 && !CHECK_FLAG(peer->sflags,
3522 PEER_STATUS_ACCEPT_PEER))
3523 return peer;
3524 } else if (bm->bgp != NULL) {
3525 struct listnode *bgpnode, *nbgpnode;
3526
3527 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3528 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3529 if (peer->conf_if
3530 && !strcmp(peer->conf_if, conf_if)
3531 && !CHECK_FLAG(peer->sflags,
3532 PEER_STATUS_ACCEPT_PEER))
3533 return peer;
3534 }
3535 return NULL;
3536 }
3537
3538 struct peer *peer_lookup_by_hostname(struct bgp *bgp, const char *hostname)
3539 {
3540 struct peer *peer;
3541 struct listnode *node, *nnode;
3542
3543 if (!hostname)
3544 return NULL;
3545
3546 if (bgp != NULL) {
3547 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3548 if (peer->hostname && !strcmp(peer->hostname, hostname)
3549 && !CHECK_FLAG(peer->sflags,
3550 PEER_STATUS_ACCEPT_PEER))
3551 return peer;
3552 } else if (bm->bgp != NULL) {
3553 struct listnode *bgpnode, *nbgpnode;
3554
3555 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3556 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3557 if (peer->hostname
3558 && !strcmp(peer->hostname, hostname)
3559 && !CHECK_FLAG(peer->sflags,
3560 PEER_STATUS_ACCEPT_PEER))
3561 return peer;
3562 }
3563 return NULL;
3564 }
3565
3566 struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
3567 {
3568 struct peer *peer = NULL;
3569 struct peer tmp_peer;
3570
3571 memset(&tmp_peer, 0, sizeof(struct peer));
3572
3573 /*
3574 * We do not want to find the doppelganger peer so search for the peer
3575 * in
3576 * the hash that has PEER_FLAG_CONFIG_NODE
3577 */
3578 SET_FLAG(tmp_peer.flags, PEER_FLAG_CONFIG_NODE);
3579
3580 tmp_peer.su = *su;
3581
3582 if (bgp != NULL) {
3583 peer = hash_lookup(bgp->peerhash, &tmp_peer);
3584 } else if (bm->bgp != NULL) {
3585 struct listnode *bgpnode, *nbgpnode;
3586
3587 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp)) {
3588 peer = hash_lookup(bgp->peerhash, &tmp_peer);
3589 if (peer)
3590 break;
3591 }
3592 }
3593
3594 return peer;
3595 }
3596
3597 struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
3598 union sockunion *su,
3599 struct peer_group *group)
3600 {
3601 struct peer *peer;
3602 afi_t afi;
3603 safi_t safi;
3604
3605 /* Create peer first; we've already checked group config is valid. */
3606 peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
3607 group->conf->as_type, 0, 0, group);
3608 if (!peer)
3609 return NULL;
3610
3611 /* Link to group */
3612 peer = peer_lock(peer);
3613 listnode_add(group->peer, peer);
3614
3615 peer_group2peer_config_copy(group, peer);
3616
3617 /*
3618 * Bind peer for all AFs configured for the group. We don't call
3619 * peer_group_bind as that is sub-optimal and does some stuff we don't
3620 * want.
3621 */
3622 FOREACH_AFI_SAFI (afi, safi) {
3623 if (!group->conf->afc[afi][safi])
3624 continue;
3625 peer->afc[afi][safi] = 1;
3626
3627 if (!peer_af_find(peer, afi, safi))
3628 peer_af_create(peer, afi, safi);
3629
3630 peer_group2peer_config_copy_af(group, peer, afi, safi);
3631 }
3632
3633 /* Mark as dynamic, but also as a "config node" for other things to
3634 * work. */
3635 SET_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR);
3636 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
3637
3638 return peer;
3639 }
3640
3641 struct prefix *
3642 peer_group_lookup_dynamic_neighbor_range(struct peer_group *group,
3643 struct prefix *prefix)
3644 {
3645 struct listnode *node, *nnode;
3646 struct prefix *range;
3647 afi_t afi;
3648
3649 afi = family2afi(prefix->family);
3650
3651 if (group->listen_range[afi])
3652 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
3653 range))
3654 if (prefix_match(range, prefix))
3655 return range;
3656
3657 return NULL;
3658 }
3659
3660 struct peer_group *
3661 peer_group_lookup_dynamic_neighbor(struct bgp *bgp, struct prefix *prefix,
3662 struct prefix **listen_range)
3663 {
3664 struct prefix *range = NULL;
3665 struct peer_group *group = NULL;
3666 struct listnode *node, *nnode;
3667
3668 *listen_range = NULL;
3669 if (bgp != NULL) {
3670 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
3671 if ((range = peer_group_lookup_dynamic_neighbor_range(
3672 group, prefix)))
3673 break;
3674 } else if (bm->bgp != NULL) {
3675 struct listnode *bgpnode, *nbgpnode;
3676
3677 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3678 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
3679 if ((range = peer_group_lookup_dynamic_neighbor_range(
3680 group, prefix)))
3681 goto found_range;
3682 }
3683
3684 found_range:
3685 *listen_range = range;
3686 return (group && range) ? group : NULL;
3687 }
3688
3689 struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
3690 {
3691 struct peer_group *group;
3692 struct bgp *gbgp;
3693 struct peer *peer;
3694 struct prefix prefix;
3695 struct prefix *listen_range;
3696 int dncount;
3697 char buf[PREFIX2STR_BUFFER];
3698 char buf1[PREFIX2STR_BUFFER];
3699
3700 sockunion2hostprefix(su, &prefix);
3701
3702 /* See if incoming connection matches a configured listen range. */
3703 group = peer_group_lookup_dynamic_neighbor(bgp, &prefix, &listen_range);
3704
3705 if (!group)
3706 return NULL;
3707
3708
3709 gbgp = group->bgp;
3710
3711 if (!gbgp)
3712 return NULL;
3713
3714 prefix2str(&prefix, buf, sizeof(buf));
3715 prefix2str(listen_range, buf1, sizeof(buf1));
3716
3717 if (bgp_debug_neighbor_events(NULL))
3718 zlog_debug(
3719 "Dynamic Neighbor %s matches group %s listen range %s",
3720 buf, group->name, buf1);
3721
3722 /* Are we within the listen limit? */
3723 dncount = gbgp->dynamic_neighbors_count;
3724
3725 if (dncount >= gbgp->dynamic_neighbors_limit) {
3726 if (bgp_debug_neighbor_events(NULL))
3727 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3728 inet_sutop(su, buf),
3729 gbgp->dynamic_neighbors_limit);
3730 return NULL;
3731 }
3732
3733 /* Ensure group is not disabled. */
3734 if (CHECK_FLAG(group->conf->flags, PEER_FLAG_SHUTDOWN)) {
3735 if (bgp_debug_neighbor_events(NULL))
3736 zlog_debug(
3737 "Dynamic Neighbor %s rejected - group %s disabled",
3738 buf, group->name);
3739 return NULL;
3740 }
3741
3742 /* Check that at least one AF is activated for the group. */
3743 if (!peer_group_af_configured(group)) {
3744 if (bgp_debug_neighbor_events(NULL))
3745 zlog_debug(
3746 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3747 buf, group->name);
3748 return NULL;
3749 }
3750
3751 /* Create dynamic peer and bind to associated group. */
3752 peer = peer_create_bind_dynamic_neighbor(gbgp, su, group);
3753 assert(peer);
3754
3755 gbgp->dynamic_neighbors_count = ++dncount;
3756
3757 if (bgp_debug_neighbor_events(peer))
3758 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3759 peer->host, group->name, dncount);
3760
3761 return peer;
3762 }
3763
3764 static void peer_drop_dynamic_neighbor(struct peer *peer)
3765 {
3766 int dncount = -1;
3767 if (peer->group->bgp) {
3768 dncount = peer->group->bgp->dynamic_neighbors_count;
3769 if (dncount)
3770 peer->group->bgp->dynamic_neighbors_count = --dncount;
3771 }
3772 if (bgp_debug_neighbor_events(peer))
3773 zlog_debug("%s dropped from group %s, count %d", peer->host,
3774 peer->group->name, dncount);
3775 }
3776
3777 /* If peer is configured at least one address family return 1. */
3778 bool peer_active(struct peer *peer)
3779 {
3780 if (BGP_PEER_SU_UNSPEC(peer))
3781 return false;
3782 if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
3783 || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
3784 || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
3785 || peer->afc[AFI_IP][SAFI_FLOWSPEC]
3786 || peer->afc[AFI_IP6][SAFI_UNICAST]
3787 || peer->afc[AFI_IP6][SAFI_MULTICAST]
3788 || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
3789 || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
3790 || peer->afc[AFI_IP6][SAFI_ENCAP]
3791 || peer->afc[AFI_IP6][SAFI_FLOWSPEC]
3792 || peer->afc[AFI_L2VPN][SAFI_EVPN])
3793 return true;
3794 return false;
3795 }
3796
3797 /* If peer is negotiated at least one address family return 1. */
3798 bool peer_active_nego(struct peer *peer)
3799 {
3800 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
3801 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
3802 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
3803 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
3804 || peer->afc_nego[AFI_IP][SAFI_ENCAP]
3805 || peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
3806 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
3807 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
3808 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
3809 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
3810 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]
3811 || peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
3812 || peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
3813 return true;
3814 return false;
3815 }
3816
3817 void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
3818 enum peer_change_type type)
3819 {
3820 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
3821 return;
3822
3823 if (peer->status != Established)
3824 return;
3825
3826 if (type == peer_change_reset) {
3827 /* If we're resetting session, we've to delete both peer struct
3828 */
3829 if ((peer->doppelganger)
3830 && (peer->doppelganger->status != Deleted)
3831 && (!CHECK_FLAG(peer->doppelganger->flags,
3832 PEER_FLAG_CONFIG_NODE)))
3833 peer_delete(peer->doppelganger);
3834
3835 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3836 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3837 } else if (type == peer_change_reset_in) {
3838 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
3839 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
3840 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0);
3841 else {
3842 if ((peer->doppelganger)
3843 && (peer->doppelganger->status != Deleted)
3844 && (!CHECK_FLAG(peer->doppelganger->flags,
3845 PEER_FLAG_CONFIG_NODE)))
3846 peer_delete(peer->doppelganger);
3847
3848 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3849 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3850 }
3851 } else if (type == peer_change_reset_out) {
3852 update_group_adjust_peer(peer_af_find(peer, afi, safi));
3853 bgp_announce_route(peer, afi, safi);
3854 }
3855 }
3856
3857 struct peer_flag_action {
3858 /* Peer's flag. */
3859 uint32_t flag;
3860
3861 /* This flag can be set for peer-group member. */
3862 uint8_t not_for_member;
3863
3864 /* Action when the flag is changed. */
3865 enum peer_change_type type;
3866 };
3867
3868 static const struct peer_flag_action peer_flag_action_list[] = {
3869 {PEER_FLAG_PASSIVE, 0, peer_change_reset},
3870 {PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
3871 {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
3872 {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
3873 {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
3874 {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset},
3875 {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset},
3876 {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset},
3877 {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in},
3878 {PEER_FLAG_IFPEER_V6ONLY, 0, peer_change_reset},
3879 {PEER_FLAG_ROUTEADV, 0, peer_change_none},
3880 {PEER_FLAG_TIMER, 0, peer_change_none},
3881 {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none},
3882 {PEER_FLAG_PASSWORD, 0, peer_change_none},
3883 {PEER_FLAG_LOCAL_AS, 0, peer_change_none},
3884 {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none},
3885 {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_none},
3886 {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none},
3887 {0, 0, 0}};
3888
3889 static const struct peer_flag_action peer_af_flag_action_list[] = {
3890 {PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out},
3891 {PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out},
3892 {PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out},
3893 {PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out},
3894 {PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset},
3895 {PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset},
3896 {PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in},
3897 {PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out},
3898 {PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out},
3899 {PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out},
3900 {PEER_FLAG_DEFAULT_ORIGINATE, 0, peer_change_none},
3901 {PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out},
3902 {PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in},
3903 {PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in},
3904 {PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset},
3905 {PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset},
3906 {PEER_FLAG_MAX_PREFIX, 0, peer_change_none},
3907 {PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none},
3908 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out},
3909 {PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out},
3910 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out},
3911 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out},
3912 {PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out},
3913 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out},
3914 {PEER_FLAG_WEIGHT, 0, peer_change_reset_in},
3915 {0, 0, 0}};
3916
3917 /* Proper action set. */
3918 static int peer_flag_action_set(const struct peer_flag_action *action_list,
3919 int size, struct peer_flag_action *action,
3920 uint32_t flag)
3921 {
3922 int i;
3923 int found = 0;
3924 int reset_in = 0;
3925 int reset_out = 0;
3926 const struct peer_flag_action *match = NULL;
3927
3928 /* Check peer's frag action. */
3929 for (i = 0; i < size; i++) {
3930 match = &action_list[i];
3931
3932 if (match->flag == 0)
3933 break;
3934
3935 if (match->flag & flag) {
3936 found = 1;
3937
3938 if (match->type == peer_change_reset_in)
3939 reset_in = 1;
3940 if (match->type == peer_change_reset_out)
3941 reset_out = 1;
3942 if (match->type == peer_change_reset) {
3943 reset_in = 1;
3944 reset_out = 1;
3945 }
3946 if (match->not_for_member)
3947 action->not_for_member = 1;
3948 }
3949 }
3950
3951 /* Set peer clear type. */
3952 if (reset_in && reset_out)
3953 action->type = peer_change_reset;
3954 else if (reset_in)
3955 action->type = peer_change_reset_in;
3956 else if (reset_out)
3957 action->type = peer_change_reset_out;
3958 else
3959 action->type = peer_change_none;
3960
3961 return found;
3962 }
3963
3964 static void peer_flag_modify_action(struct peer *peer, uint32_t flag)
3965 {
3966 if (flag == PEER_FLAG_SHUTDOWN) {
3967 if (CHECK_FLAG(peer->flags, flag)) {
3968 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
3969 peer_nsf_stop(peer);
3970
3971 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3972 if (peer->t_pmax_restart) {
3973 BGP_TIMER_OFF(peer->t_pmax_restart);
3974 if (bgp_debug_neighbor_events(peer))
3975 zlog_debug(
3976 "%s Maximum-prefix restart timer canceled",
3977 peer->host);
3978 }
3979
3980 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
3981 peer_nsf_stop(peer);
3982
3983 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
3984 char *msg = peer->tx_shutdown_message;
3985 size_t msglen;
3986
3987 if (!msg && peer_group_active(peer))
3988 msg = peer->group->conf
3989 ->tx_shutdown_message;
3990 msglen = msg ? strlen(msg) : 0;
3991 if (msglen > 128)
3992 msglen = 128;
3993
3994 if (msglen) {
3995 uint8_t msgbuf[129];
3996
3997 msgbuf[0] = msglen;
3998 memcpy(msgbuf + 1, msg, msglen);
3999
4000 bgp_notify_send_with_data(
4001 peer, BGP_NOTIFY_CEASE,
4002 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
4003 msgbuf, msglen + 1);
4004 } else
4005 bgp_notify_send(
4006 peer, BGP_NOTIFY_CEASE,
4007 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
4008 } else
4009 bgp_session_reset(peer);
4010 } else {
4011 peer->v_start = BGP_INIT_START_TIMER;
4012 BGP_EVENT_ADD(peer, BGP_Stop);
4013 }
4014 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4015 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
4016 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4017 else if (flag == PEER_FLAG_PASSIVE)
4018 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
4019 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
4020 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
4021
4022 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4023 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4024 } else
4025 bgp_session_reset(peer);
4026 }
4027
4028 /* Change specified peer flag. */
4029 static int peer_flag_modify(struct peer *peer, uint32_t flag, int set)
4030 {
4031 int found;
4032 int size;
4033 bool invert, member_invert;
4034 struct peer *member;
4035 struct listnode *node, *nnode;
4036 struct peer_flag_action action;
4037
4038 memset(&action, 0, sizeof(struct peer_flag_action));
4039 size = sizeof(peer_flag_action_list) / sizeof(struct peer_flag_action);
4040
4041 invert = CHECK_FLAG(peer->flags_invert, flag);
4042 found = peer_flag_action_set(peer_flag_action_list, size, &action,
4043 flag);
4044
4045 /* Abort if no flag action exists. */
4046 if (!found)
4047 return BGP_ERR_INVALID_FLAG;
4048
4049 /* Check for flag conflict: STRICT_CAP_MATCH && OVERRIDE_CAPABILITY */
4050 if (set && CHECK_FLAG(peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
4051 && CHECK_FLAG(peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
4052 return BGP_ERR_PEER_FLAG_CONFLICT;
4053
4054 /* Handle flag updates where desired state matches current state. */
4055 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4056 if (set && CHECK_FLAG(peer->flags, flag)) {
4057 COND_FLAG(peer->flags_override, flag, !invert);
4058 return 0;
4059 }
4060
4061 if (!set && !CHECK_FLAG(peer->flags, flag)) {
4062 COND_FLAG(peer->flags_override, flag, invert);
4063 return 0;
4064 }
4065 }
4066
4067 /* Inherit from peer-group or set/unset flags accordingly. */
4068 if (peer_group_active(peer) && set == invert)
4069 peer_flag_inherit(peer, flag);
4070 else
4071 COND_FLAG(peer->flags, flag, set);
4072
4073 /* Check if handling a regular peer. */
4074 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4075 /* Update flag override state accordingly. */
4076 COND_FLAG(peer->flags_override, flag, set != invert);
4077
4078 /*
4079 * For the extended next-hop encoding flag we need to turn RAs
4080 * on if flag is being set, but only turn RAs off if the flag
4081 * is being unset on this peer and if this peer is a member of a
4082 * peer-group, the peer-group also doesn't have the flag set.
4083 */
4084 if (flag == PEER_FLAG_CAPABILITY_ENHE) {
4085 if (set) {
4086 bgp_zebra_initiate_radv(peer->bgp, peer);
4087 } else if (peer_group_active(peer)) {
4088 if (!CHECK_FLAG(peer->group->conf->flags, flag))
4089 bgp_zebra_terminate_radv(peer->bgp,
4090 peer);
4091 } else
4092 bgp_zebra_terminate_radv(peer->bgp, peer);
4093 }
4094
4095 /* Execute flag action on peer. */
4096 if (action.type == peer_change_reset)
4097 peer_flag_modify_action(peer, flag);
4098
4099 /* Skip peer-group mechanics for regular peers. */
4100 return 0;
4101 }
4102
4103 /*
4104 * Update peer-group members, unless they are explicitely overriding
4105 * peer-group configuration.
4106 */
4107 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4108 /* Skip peers with overridden configuration. */
4109 if (CHECK_FLAG(member->flags_override, flag))
4110 continue;
4111
4112 /* Check if only member without group is inverted. */
4113 member_invert =
4114 CHECK_FLAG(member->flags_invert, flag) && !invert;
4115
4116 /* Skip peers with equivalent configuration. */
4117 if (set != member_invert && CHECK_FLAG(member->flags, flag))
4118 continue;
4119
4120 if (set == member_invert && !CHECK_FLAG(member->flags, flag))
4121 continue;
4122
4123 /* Update flag on peer-group member. */
4124 COND_FLAG(member->flags, flag, set != member_invert);
4125
4126 if (flag == PEER_FLAG_CAPABILITY_ENHE)
4127 set ? bgp_zebra_initiate_radv(member->bgp, member)
4128 : bgp_zebra_terminate_radv(member->bgp, member);
4129
4130 /* Execute flag action on peer-group member. */
4131 if (action.type == peer_change_reset)
4132 peer_flag_modify_action(member, flag);
4133 }
4134
4135 return 0;
4136 }
4137
4138 int peer_flag_set(struct peer *peer, uint32_t flag)
4139 {
4140 return peer_flag_modify(peer, flag, 1);
4141 }
4142
4143 int peer_flag_unset(struct peer *peer, uint32_t flag)
4144 {
4145 return peer_flag_modify(peer, flag, 0);
4146 }
4147
4148 static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
4149 uint32_t flag, bool set)
4150 {
4151 int found;
4152 int size;
4153 bool invert, member_invert;
4154 struct peer *member;
4155 struct listnode *node, *nnode;
4156 struct peer_flag_action action;
4157 bgp_peer_sort_t ptype;
4158
4159 memset(&action, 0, sizeof(struct peer_flag_action));
4160 size = sizeof(peer_af_flag_action_list)
4161 / sizeof(struct peer_flag_action);
4162
4163 invert = CHECK_FLAG(peer->af_flags_invert[afi][safi], flag);
4164 found = peer_flag_action_set(peer_af_flag_action_list, size, &action,
4165 flag);
4166
4167 /* Abort if flag action exists. */
4168 if (!found)
4169 return BGP_ERR_INVALID_FLAG;
4170
4171 ptype = peer_sort(peer);
4172 /* Special check for reflector client. */
4173 if (flag & PEER_FLAG_REFLECTOR_CLIENT && ptype != BGP_PEER_IBGP)
4174 return BGP_ERR_NOT_INTERNAL_PEER;
4175
4176 /* Special check for remove-private-AS. */
4177 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS && ptype == BGP_PEER_IBGP)
4178 return BGP_ERR_REMOVE_PRIVATE_AS;
4179
4180 /* as-override is not allowed for IBGP peers */
4181 if (flag & PEER_FLAG_AS_OVERRIDE && ptype == BGP_PEER_IBGP)
4182 return BGP_ERR_AS_OVERRIDE;
4183
4184 /* Handle flag updates where desired state matches current state. */
4185 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4186 if (set && CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4187 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4188 !invert);
4189 return 0;
4190 }
4191
4192 if (!set && !CHECK_FLAG(peer->af_flags[afi][safi], flag)) {
4193 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4194 invert);
4195 return 0;
4196 }
4197 }
4198
4199 /*
4200 * For EVPN we implicitly set the NEXTHOP_UNCHANGED flag,
4201 * if we are setting/unsetting flags which conflict with this flag
4202 * handle accordingly
4203 */
4204 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
4205 if (set) {
4206
4207 /*
4208 * if we are setting NEXTHOP_SELF, we need to unset the
4209 * NEXTHOP_UNCHANGED flag
4210 */
4211 if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4212 CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4213 UNSET_FLAG(peer->af_flags[afi][safi],
4214 PEER_FLAG_NEXTHOP_UNCHANGED);
4215 } else {
4216
4217 /*
4218 * if we are unsetting NEXTHOP_SELF, we need to set the
4219 * NEXTHOP_UNCHANGED flag to reset the defaults for EVPN
4220 */
4221 if (CHECK_FLAG(flag, PEER_FLAG_NEXTHOP_SELF) ||
4222 CHECK_FLAG(flag, PEER_FLAG_FORCE_NEXTHOP_SELF))
4223 SET_FLAG(peer->af_flags[afi][safi],
4224 PEER_FLAG_NEXTHOP_UNCHANGED);
4225 }
4226 }
4227
4228 /*
4229 * If the peer is a route server client let's not
4230 * muck with the nexthop on the way out the door
4231 */
4232 if (flag & PEER_FLAG_RSERVER_CLIENT) {
4233 if (set)
4234 SET_FLAG(peer->af_flags[afi][safi],
4235 PEER_FLAG_NEXTHOP_UNCHANGED);
4236 else
4237 UNSET_FLAG(peer->af_flags[afi][safi],
4238 PEER_FLAG_NEXTHOP_UNCHANGED);
4239 }
4240
4241 /* Inherit from peer-group or set/unset flags accordingly. */
4242 if (peer_group_active(peer) && set == invert)
4243 peer_af_flag_inherit(peer, afi, safi, flag);
4244 else
4245 COND_FLAG(peer->af_flags[afi][safi], flag, set);
4246
4247 /* Execute action when peer is established. */
4248 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4249 && peer->status == Established) {
4250 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4251 bgp_clear_adj_in(peer, afi, safi);
4252 else {
4253 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4254 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
4255 else if (flag == PEER_FLAG_RSERVER_CLIENT)
4256 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
4257 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
4258 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4259 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
4260 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4261
4262 peer_change_action(peer, afi, safi, action.type);
4263 }
4264 }
4265
4266 /* Check if handling a regular peer. */
4267 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4268 COND_FLAG(peer->af_flags_override[afi][safi], flag,
4269 set != invert);
4270 } else {
4271 /*
4272 * Update peer-group members, unless they are explicitely
4273 * overriding peer-group configuration.
4274 */
4275 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode,
4276 member)) {
4277 /* Skip peers with overridden configuration. */
4278 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4279 flag))
4280 continue;
4281
4282 /* Check if only member without group is inverted. */
4283 member_invert =
4284 CHECK_FLAG(member->af_flags_invert[afi][safi],
4285 flag)
4286 && !invert;
4287
4288 /* Skip peers with equivalent configuration. */
4289 if (set != member_invert
4290 && CHECK_FLAG(member->af_flags[afi][safi], flag))
4291 continue;
4292
4293 if (set == member_invert
4294 && !CHECK_FLAG(member->af_flags[afi][safi], flag))
4295 continue;
4296
4297 /* Update flag on peer-group member. */
4298 COND_FLAG(member->af_flags[afi][safi], flag,
4299 set != member_invert);
4300
4301 /* Execute flag action on peer-group member. */
4302 if (member->status == Established) {
4303 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4304 bgp_clear_adj_in(member, afi, safi);
4305 else {
4306 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4307 member->last_reset =
4308 PEER_DOWN_RR_CLIENT_CHANGE;
4309 else if (flag
4310 == PEER_FLAG_RSERVER_CLIENT)
4311 member->last_reset =
4312 PEER_DOWN_RS_CLIENT_CHANGE;
4313 else if (flag
4314 == PEER_FLAG_ORF_PREFIX_SM)
4315 member->last_reset =
4316 PEER_DOWN_CAPABILITY_CHANGE;
4317 else if (flag
4318 == PEER_FLAG_ORF_PREFIX_RM)
4319 member->last_reset =
4320 PEER_DOWN_CAPABILITY_CHANGE;
4321
4322 peer_change_action(member, afi, safi,
4323 action.type);
4324 }
4325 }
4326 }
4327 }
4328
4329 return 0;
4330 }
4331
4332 int peer_af_flag_set(struct peer *peer, afi_t afi, safi_t safi, uint32_t flag)
4333 {
4334 return peer_af_flag_modify(peer, afi, safi, flag, 1);
4335 }
4336
4337 int peer_af_flag_unset(struct peer *peer, afi_t afi, safi_t safi, uint32_t flag)
4338 {
4339 return peer_af_flag_modify(peer, afi, safi, flag, 0);
4340 }
4341
4342
4343 void peer_tx_shutdown_message_set(struct peer *peer, const char *msg)
4344 {
4345 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4346 peer->tx_shutdown_message =
4347 msg ? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG, msg) : NULL;
4348 }
4349
4350 void peer_tx_shutdown_message_unset(struct peer *peer)
4351 {
4352 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4353 }
4354
4355
4356 /* EBGP multihop configuration. */
4357 int peer_ebgp_multihop_set(struct peer *peer, int ttl)
4358 {
4359 struct peer_group *group;
4360 struct listnode *node, *nnode;
4361 struct peer *peer1;
4362
4363 if (peer->sort == BGP_PEER_IBGP || peer->conf_if)
4364 return 0;
4365
4366 /* see comment in peer_ttl_security_hops_set() */
4367 if (ttl != MAXTTL) {
4368 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4369 group = peer->group;
4370 if (group->conf->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
4371 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4372
4373 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
4374 peer1)) {
4375 if (peer1->sort == BGP_PEER_IBGP)
4376 continue;
4377
4378 if (peer1->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
4379 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4380 }
4381 } else {
4382 if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED)
4383 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4384 }
4385 }
4386
4387 peer->ttl = ttl;
4388
4389 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4390 if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP) {
4391 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4392 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4393 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4394 else
4395 bgp_session_reset(peer);
4396 }
4397 } else {
4398 group = peer->group;
4399 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4400 if (peer->sort == BGP_PEER_IBGP)
4401 continue;
4402
4403 peer->ttl = group->conf->ttl;
4404
4405 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4406 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4407 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4408 else
4409 bgp_session_reset(peer);
4410 }
4411 }
4412 return 0;
4413 }
4414
4415 int peer_ebgp_multihop_unset(struct peer *peer)
4416 {
4417 struct peer_group *group;
4418 struct listnode *node, *nnode;
4419
4420 if (peer->sort == BGP_PEER_IBGP)
4421 return 0;
4422
4423 if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED && peer->ttl != MAXTTL)
4424 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4425
4426 if (peer_group_active(peer))
4427 peer->ttl = peer->group->conf->ttl;
4428 else
4429 peer->ttl = BGP_DEFAULT_TTL;
4430
4431 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4432 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4433 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4434 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4435 else
4436 bgp_session_reset(peer);
4437 } else {
4438 group = peer->group;
4439 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4440 if (peer->sort == BGP_PEER_IBGP)
4441 continue;
4442
4443 peer->ttl = BGP_DEFAULT_TTL;
4444
4445 if (peer->fd >= 0) {
4446 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4447 bgp_notify_send(
4448 peer, BGP_NOTIFY_CEASE,
4449 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4450 else
4451 bgp_session_reset(peer);
4452 }
4453 }
4454 }
4455 return 0;
4456 }
4457
4458 /* Neighbor description. */
4459 void peer_description_set(struct peer *peer, const char *desc)
4460 {
4461 XFREE(MTYPE_PEER_DESC, peer->desc);
4462
4463 peer->desc = XSTRDUP(MTYPE_PEER_DESC, desc);
4464 }
4465
4466 void peer_description_unset(struct peer *peer)
4467 {
4468 XFREE(MTYPE_PEER_DESC, peer->desc);
4469 }
4470
4471 /* Neighbor update-source. */
4472 int peer_update_source_if_set(struct peer *peer, const char *ifname)
4473 {
4474 struct peer *member;
4475 struct listnode *node, *nnode;
4476
4477 /* Set flag and configuration on peer. */
4478 peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
4479 if (peer->update_if) {
4480 if (strcmp(peer->update_if, ifname) == 0)
4481 return 0;
4482 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4483 }
4484 peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
4485 sockunion_free(peer->update_source);
4486 peer->update_source = NULL;
4487
4488 /* Check if handling a regular peer. */
4489 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4490 /* Send notification or reset peer depending on state. */
4491 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4492 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4493 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4494 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4495 } else
4496 bgp_session_reset(peer);
4497
4498 /* Skip peer-group mechanics for regular peers. */
4499 return 0;
4500 }
4501
4502 /*
4503 * Set flag and configuration on all peer-group members, unless they are
4504 * explicitely overriding peer-group configuration.
4505 */
4506 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4507 /* Skip peers with overridden configuration. */
4508 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
4509 continue;
4510
4511 /* Skip peers with the same configuration. */
4512 if (member->update_if) {
4513 if (strcmp(member->update_if, ifname) == 0)
4514 continue;
4515 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
4516 }
4517
4518 /* Set flag and configuration on peer-group member. */
4519 SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
4520 member->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
4521 sockunion_free(member->update_source);
4522 member->update_source = NULL;
4523
4524 /* Send notification or reset peer depending on state. */
4525 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
4526 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4527 bgp_notify_send(member, BGP_NOTIFY_CEASE,
4528 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4529 } else
4530 bgp_session_reset(member);
4531 }
4532
4533 return 0;
4534 }
4535
4536 int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
4537 {
4538 struct peer *member;
4539 struct listnode *node, *nnode;
4540
4541 /* Set flag and configuration on peer. */
4542 peer_flag_set(peer, PEER_FLAG_UPDATE_SOURCE);
4543 if (peer->update_source) {
4544 if (sockunion_cmp(peer->update_source, su) == 0)
4545 return 0;
4546 sockunion_free(peer->update_source);
4547 }
4548 peer->update_source = sockunion_dup(su);
4549 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4550
4551 /* Check if handling a regular peer. */
4552 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4553 /* Send notification or reset peer depending on state. */
4554 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4555 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4556 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4557 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4558 } else
4559 bgp_session_reset(peer);
4560
4561 /* Skip peer-group mechanics for regular peers. */
4562 return 0;
4563 }
4564
4565 /*
4566 * Set flag and configuration on all peer-group members, unless they are
4567 * explicitely overriding peer-group configuration.
4568 */
4569 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4570 /* Skip peers with overridden configuration. */
4571 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
4572 continue;
4573
4574 /* Skip peers with the same configuration. */
4575 if (member->update_source) {
4576 if (sockunion_cmp(member->update_source, su) == 0)
4577 continue;
4578 sockunion_free(member->update_source);
4579 }
4580
4581 /* Set flag and configuration on peer-group member. */
4582 SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
4583 member->update_source = sockunion_dup(su);
4584 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
4585
4586 /* Send notification or reset peer depending on state. */
4587 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
4588 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4589 bgp_notify_send(member, BGP_NOTIFY_CEASE,
4590 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4591 } else
4592 bgp_session_reset(member);
4593 }
4594
4595 return 0;
4596 }
4597
4598 int peer_update_source_unset(struct peer *peer)
4599 {
4600 struct peer *member;
4601 struct listnode *node, *nnode;
4602
4603 if (!CHECK_FLAG(peer->flags, PEER_FLAG_UPDATE_SOURCE))
4604 return 0;
4605
4606 /* Inherit configuration from peer-group if peer is member. */
4607 if (peer_group_active(peer)) {
4608 peer_flag_inherit(peer, PEER_FLAG_UPDATE_SOURCE);
4609 PEER_SU_ATTR_INHERIT(peer, peer->group, update_source);
4610 PEER_STR_ATTR_INHERIT(peer, peer->group, update_if,
4611 MTYPE_PEER_UPDATE_SOURCE);
4612 } else {
4613 /* Otherwise remove flag and configuration from peer. */
4614 peer_flag_unset(peer, PEER_FLAG_UPDATE_SOURCE);
4615 sockunion_free(peer->update_source);
4616 peer->update_source = NULL;
4617 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4618 }
4619
4620 /* Check if handling a regular peer. */
4621 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4622 /* Send notification or reset peer depending on state. */
4623 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4624 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4625 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4626 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4627 } else
4628 bgp_session_reset(peer);
4629
4630 /* Skip peer-group mechanics for regular peers. */
4631 return 0;
4632 }
4633
4634 /*
4635 * Set flag and configuration on all peer-group members, unless they are
4636 * explicitely overriding peer-group configuration.
4637 */
4638 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4639 /* Skip peers with overridden configuration. */
4640 if (CHECK_FLAG(member->flags_override, PEER_FLAG_UPDATE_SOURCE))
4641 continue;
4642
4643 /* Skip peers with the same configuration. */
4644 if (!CHECK_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE)
4645 && !member->update_source && !member->update_if)
4646 continue;
4647
4648 /* Remove flag and configuration on peer-group member. */
4649 UNSET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE);
4650 sockunion_free(member->update_source);
4651 member->update_source = NULL;
4652 XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if);
4653
4654 /* Send notification or reset peer depending on state. */
4655 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
4656 member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4657 bgp_notify_send(member, BGP_NOTIFY_CEASE,
4658 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4659 } else
4660 bgp_session_reset(member);
4661 }
4662
4663 return 0;
4664 }
4665
4666 int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
4667 const char *rmap, struct route_map *route_map)
4668 {
4669 struct peer *member;
4670 struct listnode *node, *nnode;
4671
4672 /* Set flag and configuration on peer. */
4673 peer_af_flag_set(peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE);
4674 if (rmap) {
4675 if (!peer->default_rmap[afi][safi].name
4676 || strcmp(rmap, peer->default_rmap[afi][safi].name) != 0) {
4677 if (peer->default_rmap[afi][safi].name)
4678 XFREE(MTYPE_ROUTE_MAP_NAME,
4679 peer->default_rmap[afi][safi].name);
4680
4681 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4682 peer->default_rmap[afi][safi].name =
4683 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4684 peer->default_rmap[afi][safi].map = route_map;
4685 route_map_counter_increment(route_map);
4686 }
4687 } else if (!rmap) {
4688 if (peer->default_rmap[afi][safi].name)
4689 XFREE(MTYPE_ROUTE_MAP_NAME,
4690 peer->default_rmap[afi][safi].name);
4691
4692 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4693 peer->default_rmap[afi][safi].name = NULL;
4694 peer->default_rmap[afi][safi].map = NULL;
4695 }
4696
4697 /* Check if handling a regular peer. */
4698 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4699 /* Update peer route announcements. */
4700 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4701 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4702 bgp_default_originate(peer, afi, safi, 0);
4703 bgp_announce_route(peer, afi, safi);
4704 }
4705
4706 /* Skip peer-group mechanics for regular peers. */
4707 return 0;
4708 }
4709
4710 /*
4711 * Set flag and configuration on all peer-group members, unless they are
4712 * explicitely overriding peer-group configuration.
4713 */
4714 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4715 /* Skip peers with overridden configuration. */
4716 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4717 PEER_FLAG_DEFAULT_ORIGINATE))
4718 continue;
4719
4720 /* Set flag and configuration on peer-group member. */
4721 SET_FLAG(member->af_flags[afi][safi],
4722 PEER_FLAG_DEFAULT_ORIGINATE);
4723 if (rmap) {
4724 if (member->default_rmap[afi][safi].name)
4725 XFREE(MTYPE_ROUTE_MAP_NAME,
4726 member->default_rmap[afi][safi].name);
4727 route_map_counter_decrement(
4728 member->default_rmap[afi][safi].map);
4729 member->default_rmap[afi][safi].name =
4730 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4731 member->default_rmap[afi][safi].map = route_map;
4732 route_map_counter_increment(route_map);
4733 }
4734
4735 /* Update peer route announcements. */
4736 if (member->status == Established
4737 && member->afc_nego[afi][safi]) {
4738 update_group_adjust_peer(
4739 peer_af_find(member, afi, safi));
4740 bgp_default_originate(member, afi, safi, 0);
4741 bgp_announce_route(member, afi, safi);
4742 }
4743 }
4744
4745 return 0;
4746 }
4747
4748 int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi)
4749 {
4750 struct peer *member;
4751 struct listnode *node, *nnode;
4752
4753 /* Inherit configuration from peer-group if peer is member. */
4754 if (peer_group_active(peer)) {
4755 peer_af_flag_inherit(peer, afi, safi,
4756 PEER_FLAG_DEFAULT_ORIGINATE);
4757 PEER_STR_ATTR_INHERIT(peer, peer->group,
4758 default_rmap[afi][safi].name,
4759 MTYPE_ROUTE_MAP_NAME);
4760 PEER_ATTR_INHERIT(peer, peer->group,
4761 default_rmap[afi][safi].map);
4762 } else {
4763 /* Otherwise remove flag and configuration from peer. */
4764 peer_af_flag_unset(peer, afi, safi,
4765 PEER_FLAG_DEFAULT_ORIGINATE);
4766 if (peer->default_rmap[afi][safi].name)
4767 XFREE(MTYPE_ROUTE_MAP_NAME,
4768 peer->default_rmap[afi][safi].name);
4769 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4770 peer->default_rmap[afi][safi].name = NULL;
4771 peer->default_rmap[afi][safi].map = NULL;
4772 }
4773
4774 /* Check if handling a regular peer. */
4775 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4776 /* Update peer route announcements. */
4777 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4778 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4779 bgp_default_originate(peer, afi, safi, 1);
4780 bgp_announce_route(peer, afi, safi);
4781 }
4782
4783 /* Skip peer-group mechanics for regular peers. */
4784 return 0;
4785 }
4786
4787 /*
4788 * Remove flag and configuration from all peer-group members, unless
4789 * they are explicitely overriding peer-group configuration.
4790 */
4791 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4792 /* Skip peers with overridden configuration. */
4793 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4794 PEER_FLAG_DEFAULT_ORIGINATE))
4795 continue;
4796
4797 /* Remove flag and configuration on peer-group member. */
4798 UNSET_FLAG(peer->af_flags[afi][safi],
4799 PEER_FLAG_DEFAULT_ORIGINATE);
4800 if (peer->default_rmap[afi][safi].name)
4801 XFREE(MTYPE_ROUTE_MAP_NAME,
4802 peer->default_rmap[afi][safi].name);
4803 route_map_counter_decrement(peer->default_rmap[afi][safi].map);
4804 peer->default_rmap[afi][safi].name = NULL;
4805 peer->default_rmap[afi][safi].map = NULL;
4806
4807 /* Update peer route announcements. */
4808 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4809 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4810 bgp_default_originate(peer, afi, safi, 1);
4811 bgp_announce_route(peer, afi, safi);
4812 }
4813 }
4814
4815 return 0;
4816 }
4817
4818 void peer_port_set(struct peer *peer, uint16_t port)
4819 {
4820 peer->port = port;
4821 }
4822
4823 void peer_port_unset(struct peer *peer)
4824 {
4825 peer->port = BGP_PORT_DEFAULT;
4826 }
4827
4828 /*
4829 * Helper function that is called after the name of the policy
4830 * being used by a peer has changed (AF specific). Automatically
4831 * initiates inbound or outbound processing as needed.
4832 */
4833 static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
4834 int outbound)
4835 {
4836 if (outbound) {
4837 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4838 if (peer->status == Established)
4839 bgp_announce_route(peer, afi, safi);
4840 } else {
4841 if (peer->status != Established)
4842 return;
4843
4844 if (CHECK_FLAG(peer->af_flags[afi][safi],
4845 PEER_FLAG_SOFT_RECONFIG))
4846 bgp_soft_reconfig_in(peer, afi, safi);
4847 else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4848 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4849 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0);
4850 }
4851 }
4852
4853
4854 /* neighbor weight. */
4855 int peer_weight_set(struct peer *peer, afi_t afi, safi_t safi, uint16_t weight)
4856 {
4857 struct peer *member;
4858 struct listnode *node, *nnode;
4859
4860 /* Set flag and configuration on peer. */
4861 peer_af_flag_set(peer, afi, safi, PEER_FLAG_WEIGHT);
4862 if (peer->weight[afi][safi] != weight) {
4863 peer->weight[afi][safi] = weight;
4864 peer_on_policy_change(peer, afi, safi, 0);
4865 }
4866
4867 /* Skip peer-group mechanics for regular peers. */
4868 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4869 return 0;
4870
4871 /*
4872 * Set flag and configuration on all peer-group members, unless they are
4873 * explicitely overriding peer-group configuration.
4874 */
4875 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4876 /* Skip peers with overridden configuration. */
4877 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4878 PEER_FLAG_WEIGHT))
4879 continue;
4880
4881 /* Set flag and configuration on peer-group member. */
4882 SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
4883 if (member->weight[afi][safi] != weight) {
4884 member->weight[afi][safi] = weight;
4885 peer_on_policy_change(member, afi, safi, 0);
4886 }
4887 }
4888
4889 return 0;
4890 }
4891
4892 int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi)
4893 {
4894 struct peer *member;
4895 struct listnode *node, *nnode;
4896
4897 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT))
4898 return 0;
4899
4900 /* Inherit configuration from peer-group if peer is member. */
4901 if (peer_group_active(peer)) {
4902 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_WEIGHT);
4903 PEER_ATTR_INHERIT(peer, peer->group, weight[afi][safi]);
4904
4905 peer_on_policy_change(peer, afi, safi, 0);
4906 return 0;
4907 }
4908
4909 /* Remove flag and configuration from peer. */
4910 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_WEIGHT);
4911 peer->weight[afi][safi] = 0;
4912 peer_on_policy_change(peer, afi, safi, 0);
4913
4914 /* Skip peer-group mechanics for regular peers. */
4915 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4916 return 0;
4917
4918 /*
4919 * Remove flag and configuration from all peer-group members, unless
4920 * they are explicitely overriding peer-group configuration.
4921 */
4922 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4923 /* Skip peers with overridden configuration. */
4924 if (CHECK_FLAG(member->af_flags_override[afi][safi],
4925 PEER_FLAG_WEIGHT))
4926 continue;
4927
4928 /* Skip peers where flag is already disabled. */
4929 if (!CHECK_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT))
4930 continue;
4931
4932 /* Remove flag and configuration on peer-group member. */
4933 UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_WEIGHT);
4934 member->weight[afi][safi] = 0;
4935 peer_on_policy_change(member, afi, safi, 0);
4936 }
4937
4938 return 0;
4939 }
4940
4941 int peer_timers_set(struct peer *peer, uint32_t keepalive, uint32_t holdtime)
4942 {
4943 struct peer *member;
4944 struct listnode *node, *nnode;
4945
4946 if (keepalive > 65535)
4947 return BGP_ERR_INVALID_VALUE;
4948
4949 if (holdtime > 65535)
4950 return BGP_ERR_INVALID_VALUE;
4951
4952 if (holdtime < 3 && holdtime != 0)
4953 return BGP_ERR_INVALID_VALUE;
4954
4955 /* Set flag and configuration on peer. */
4956 peer_flag_set(peer, PEER_FLAG_TIMER);
4957 peer->holdtime = holdtime;
4958 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
4959
4960 /* Skip peer-group mechanics for regular peers. */
4961 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4962 return 0;
4963
4964 /*
4965 * Set flag and configuration on all peer-group members, unless they are
4966 * explicitely overriding peer-group configuration.
4967 */
4968 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
4969 /* Skip peers with overridden configuration. */
4970 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
4971 continue;
4972
4973 /* Set flag and configuration on peer-group member. */
4974 SET_FLAG(member->flags, PEER_FLAG_TIMER);
4975 PEER_ATTR_INHERIT(peer, peer->group, holdtime);
4976 PEER_ATTR_INHERIT(peer, peer->group, keepalive);
4977 }
4978
4979 return 0;
4980 }
4981
4982 int peer_timers_unset(struct peer *peer)
4983 {
4984 struct peer *member;
4985 struct listnode *node, *nnode;
4986
4987 /* Inherit configuration from peer-group if peer is member. */
4988 if (peer_group_active(peer)) {
4989 peer_flag_inherit(peer, PEER_FLAG_TIMER);
4990 PEER_ATTR_INHERIT(peer, peer->group, holdtime);
4991 PEER_ATTR_INHERIT(peer, peer->group, keepalive);
4992 } else {
4993 /* Otherwise remove flag and configuration from peer. */
4994 peer_flag_unset(peer, PEER_FLAG_TIMER);
4995 peer->holdtime = 0;
4996 peer->keepalive = 0;
4997 }
4998
4999 /* Skip peer-group mechanics for regular peers. */
5000 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5001 return 0;
5002
5003 /*
5004 * Remove flag and configuration from all peer-group members, unless
5005 * they are explicitely overriding peer-group configuration.
5006 */
5007 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5008 /* Skip peers with overridden configuration. */
5009 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER))
5010 continue;
5011
5012 /* Remove flag and configuration on peer-group member. */
5013 UNSET_FLAG(member->flags, PEER_FLAG_TIMER);
5014 member->holdtime = 0;
5015 member->keepalive = 0;
5016 }
5017
5018 return 0;
5019 }
5020
5021 int peer_timers_connect_set(struct peer *peer, uint32_t connect)
5022 {
5023 struct peer *member;
5024 struct listnode *node, *nnode;
5025
5026 if (connect > 65535)
5027 return BGP_ERR_INVALID_VALUE;
5028
5029 /* Set flag and configuration on peer. */
5030 peer_flag_set(peer, PEER_FLAG_TIMER_CONNECT);
5031 peer->connect = connect;
5032 peer->v_connect = connect;
5033
5034 /* Skip peer-group mechanics for regular peers. */
5035 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5036 return 0;
5037
5038 /*
5039 * Set flag and configuration on all peer-group members, unless they are
5040 * explicitely overriding peer-group configuration.
5041 */
5042 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5043 /* Skip peers with overridden configuration. */
5044 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5045 continue;
5046
5047 /* Set flag and configuration on peer-group member. */
5048 SET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5049 member->connect = connect;
5050 member->v_connect = connect;
5051 }
5052
5053 return 0;
5054 }
5055
5056 int peer_timers_connect_unset(struct peer *peer)
5057 {
5058 struct peer *member;
5059 struct listnode *node, *nnode;
5060
5061 /* Inherit configuration from peer-group if peer is member. */
5062 if (peer_group_active(peer)) {
5063 peer_flag_inherit(peer, PEER_FLAG_TIMER_CONNECT);
5064 PEER_ATTR_INHERIT(peer, peer->group, connect);
5065 } else {
5066 /* Otherwise remove flag and configuration from peer. */
5067 peer_flag_unset(peer, PEER_FLAG_TIMER_CONNECT);
5068 peer->connect = 0;
5069 }
5070
5071 /* Set timer with fallback to default value. */
5072 if (peer->connect)
5073 peer->v_connect = peer->connect;
5074 else
5075 peer->v_connect = peer->bgp->default_connect_retry;
5076
5077 /* Skip peer-group mechanics for regular peers. */
5078 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5079 return 0;
5080
5081 /*
5082 * Remove flag and configuration from all peer-group members, unless
5083 * they are explicitely overriding peer-group configuration.
5084 */
5085 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5086 /* Skip peers with overridden configuration. */
5087 if (CHECK_FLAG(member->flags_override, PEER_FLAG_TIMER_CONNECT))
5088 continue;
5089
5090 /* Remove flag and configuration on peer-group member. */
5091 UNSET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT);
5092 member->connect = 0;
5093 member->v_connect = peer->bgp->default_connect_retry;
5094 }
5095
5096 return 0;
5097 }
5098
5099 int peer_advertise_interval_set(struct peer *peer, uint32_t routeadv)
5100 {
5101 struct peer *member;
5102 struct listnode *node, *nnode;
5103
5104 if (routeadv > 600)
5105 return BGP_ERR_INVALID_VALUE;
5106
5107 /* Set flag and configuration on peer. */
5108 peer_flag_set(peer, PEER_FLAG_ROUTEADV);
5109 peer->routeadv = routeadv;
5110 peer->v_routeadv = routeadv;
5111
5112 /* Check if handling a regular peer. */
5113 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5114 /* Update peer route announcements. */
5115 update_group_adjust_peer_afs(peer);
5116 if (peer->status == Established)
5117 bgp_announce_route_all(peer);
5118
5119 /* Skip peer-group mechanics for regular peers. */
5120 return 0;
5121 }
5122
5123 /*
5124 * Set flag and configuration on all peer-group members, unless they are
5125 * explicitely overriding peer-group configuration.
5126 */
5127 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5128 /* Skip peers with overridden configuration. */
5129 if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
5130 continue;
5131
5132 /* Set flag and configuration on peer-group member. */
5133 SET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
5134 member->routeadv = routeadv;
5135 member->v_routeadv = routeadv;
5136
5137 /* Update peer route announcements. */
5138 update_group_adjust_peer_afs(member);
5139 if (member->status == Established)
5140 bgp_announce_route_all(member);
5141 }
5142
5143 return 0;
5144 }
5145
5146 int peer_advertise_interval_unset(struct peer *peer)
5147 {
5148 struct peer *member;
5149 struct listnode *node, *nnode;
5150
5151 /* Inherit configuration from peer-group if peer is member. */
5152 if (peer_group_active(peer)) {
5153 peer_flag_inherit(peer, PEER_FLAG_ROUTEADV);
5154 PEER_ATTR_INHERIT(peer, peer->group, routeadv);
5155 } else {
5156 /* Otherwise remove flag and configuration from peer. */
5157 peer_flag_unset(peer, PEER_FLAG_ROUTEADV);
5158 peer->routeadv = 0;
5159 }
5160
5161 /* Set timer with fallback to default value. */
5162 if (peer->routeadv)
5163 peer->v_routeadv = peer->routeadv;
5164 else
5165 peer->v_routeadv = (peer->sort == BGP_PEER_IBGP)
5166 ? BGP_DEFAULT_IBGP_ROUTEADV
5167 : BGP_DEFAULT_EBGP_ROUTEADV;
5168
5169 /* Check if handling a regular peer. */
5170 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5171 /* Update peer route announcements. */
5172 update_group_adjust_peer_afs(peer);
5173 if (peer->status == Established)
5174 bgp_announce_route_all(peer);
5175
5176 /* Skip peer-group mechanics for regular peers. */
5177 return 0;
5178 }
5179
5180 /*
5181 * Remove flag and configuration from all peer-group members, unless
5182 * they are explicitely overriding peer-group configuration.
5183 */
5184 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5185 /* Skip peers with overridden configuration. */
5186 if (CHECK_FLAG(member->flags_override, PEER_FLAG_ROUTEADV))
5187 continue;
5188
5189 /* Remove flag and configuration on peer-group member. */
5190 UNSET_FLAG(member->flags, PEER_FLAG_ROUTEADV);
5191 member->routeadv = 0;
5192 member->v_routeadv = (member->sort == BGP_PEER_IBGP)
5193 ? BGP_DEFAULT_IBGP_ROUTEADV
5194 : BGP_DEFAULT_EBGP_ROUTEADV;
5195
5196 /* Update peer route announcements. */
5197 update_group_adjust_peer_afs(member);
5198 if (member->status == Established)
5199 bgp_announce_route_all(member);
5200 }
5201
5202 return 0;
5203 }
5204
5205 /* neighbor interface */
5206 void peer_interface_set(struct peer *peer, const char *str)
5207 {
5208 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
5209 peer->ifname = XSTRDUP(MTYPE_BGP_PEER_IFNAME, str);
5210 }
5211
5212 void peer_interface_unset(struct peer *peer)
5213 {
5214 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
5215 }
5216
5217 /* Allow-as in. */
5218 int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
5219 int allow_num, int origin)
5220 {
5221 struct peer *member;
5222 struct listnode *node, *nnode;
5223
5224 if (!origin && (allow_num < 1 || allow_num > 10))
5225 return BGP_ERR_INVALID_VALUE;
5226
5227 /* Set flag and configuration on peer. */
5228 peer_af_flag_set(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
5229 if (origin) {
5230 if (peer->allowas_in[afi][safi] != 0
5231 || !CHECK_FLAG(peer->af_flags[afi][safi],
5232 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5233 peer_af_flag_set(peer, afi, safi,
5234 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5235 peer->allowas_in[afi][safi] = 0;
5236 peer_on_policy_change(peer, afi, safi, 0);
5237 }
5238 } else {
5239 if (peer->allowas_in[afi][safi] != allow_num
5240 || CHECK_FLAG(peer->af_flags[afi][safi],
5241 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5242
5243 peer_af_flag_unset(peer, afi, safi,
5244 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5245 peer->allowas_in[afi][safi] = allow_num;
5246 peer_on_policy_change(peer, afi, safi, 0);
5247 }
5248 }
5249
5250 /* Skip peer-group mechanics for regular peers. */
5251 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5252 return 0;
5253
5254 /*
5255 * Set flag and configuration on all peer-group members, unless
5256 * they are explicitely overriding peer-group configuration.
5257 */
5258 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5259 /* Skip peers with overridden configuration. */
5260 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5261 PEER_FLAG_ALLOWAS_IN))
5262 continue;
5263
5264 /* Set flag and configuration on peer-group member. */
5265 SET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
5266 if (origin) {
5267 if (member->allowas_in[afi][safi] != 0
5268 || !CHECK_FLAG(member->af_flags[afi][safi],
5269 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5270 SET_FLAG(member->af_flags[afi][safi],
5271 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5272 member->allowas_in[afi][safi] = 0;
5273 peer_on_policy_change(peer, afi, safi, 0);
5274 }
5275 } else {
5276 if (member->allowas_in[afi][safi] != allow_num
5277 || CHECK_FLAG(member->af_flags[afi][safi],
5278 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
5279 UNSET_FLAG(member->af_flags[afi][safi],
5280 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5281 member->allowas_in[afi][safi] = allow_num;
5282 peer_on_policy_change(peer, afi, safi, 0);
5283 }
5284 }
5285 }
5286
5287 return 0;
5288 }
5289
5290 int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
5291 {
5292 struct peer *member;
5293 struct listnode *node, *nnode;
5294
5295 /* Skip peer if flag is already disabled. */
5296 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
5297 return 0;
5298
5299 /* Inherit configuration from peer-group if peer is member. */
5300 if (peer_group_active(peer)) {
5301 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
5302 peer_af_flag_inherit(peer, afi, safi,
5303 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5304 PEER_ATTR_INHERIT(peer, peer->group, allowas_in[afi][safi]);
5305 peer_on_policy_change(peer, afi, safi, 0);
5306
5307 return 0;
5308 }
5309
5310 /* Remove flag and configuration from peer. */
5311 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
5312 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN);
5313 peer->allowas_in[afi][safi] = 0;
5314 peer_on_policy_change(peer, afi, safi, 0);
5315
5316 /* Skip peer-group mechanics if handling a regular peer. */
5317 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5318 return 0;
5319
5320 /*
5321 * Remove flags and configuration from all peer-group members, unless
5322 * they are explicitely overriding peer-group configuration.
5323 */
5324 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5325 /* Skip peers with overridden configuration. */
5326 if (CHECK_FLAG(member->af_flags_override[afi][safi],
5327 PEER_FLAG_ALLOWAS_IN))
5328 continue;
5329
5330 /* Skip peers where flag is already disabled. */
5331 if (!CHECK_FLAG(member->af_flags[afi][safi],
5332 PEER_FLAG_ALLOWAS_IN))
5333 continue;
5334
5335 /* Remove flags and configuration on peer-group member. */
5336 UNSET_FLAG(member->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
5337 UNSET_FLAG(member->af_flags[afi][safi],
5338 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5339 member->allowas_in[afi][safi] = 0;
5340 peer_on_policy_change(member, afi, safi, 0);
5341 }
5342
5343 return 0;
5344 }
5345
5346 int peer_local_as_set(struct peer *peer, as_t as, int no_prepend,
5347 int replace_as)
5348 {
5349 bool old_no_prepend, old_replace_as;
5350 struct bgp *bgp = peer->bgp;
5351 struct peer *member;
5352 struct listnode *node, *nnode;
5353 bgp_peer_sort_t ptype = peer_sort(peer);
5354
5355 if (ptype != BGP_PEER_EBGP && ptype != BGP_PEER_INTERNAL)
5356 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
5357
5358 if (bgp->as == as)
5359 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
5360
5361 if (peer->as == as)
5362 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
5363
5364 /* Save previous flag states. */
5365 old_no_prepend =
5366 !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5367 old_replace_as =
5368 !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5369
5370 /* Set flag and configuration on peer. */
5371 peer_flag_set(peer, PEER_FLAG_LOCAL_AS);
5372 peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND, no_prepend);
5373 peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as);
5374
5375 if (peer->change_local_as == as && old_no_prepend == no_prepend
5376 && old_replace_as == replace_as)
5377 return 0;
5378 peer->change_local_as = as;
5379
5380 /* Check if handling a regular peer. */
5381 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5382 /* Send notification or reset peer depending on state. */
5383 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5384 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5385 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5386 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5387 } else
5388 bgp_session_reset(peer);
5389
5390 /* Skip peer-group mechanics for regular peers. */
5391 return 0;
5392 }
5393
5394 /*
5395 * Set flag and configuration on all peer-group members, unless they are
5396 * explicitely overriding peer-group configuration.
5397 */
5398 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5399 /* Skip peers with overridden configuration. */
5400 if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
5401 continue;
5402
5403 /* Skip peers with the same configuration. */
5404 old_no_prepend = CHECK_FLAG(member->flags,
5405 PEER_FLAG_LOCAL_AS_NO_PREPEND);
5406 old_replace_as = CHECK_FLAG(member->flags,
5407 PEER_FLAG_LOCAL_AS_REPLACE_AS);
5408 if (member->change_local_as == as
5409 && CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS)
5410 && old_no_prepend == no_prepend
5411 && old_replace_as == replace_as)
5412 continue;
5413
5414 /* Set flag and configuration on peer-group member. */
5415 SET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
5416 COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND,
5417 no_prepend);
5418 COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
5419 replace_as);
5420 member->change_local_as = as;
5421
5422 /* Send notification or stop peer depending on state. */
5423 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5424 member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5425 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5426 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5427 } else
5428 BGP_EVENT_ADD(member, BGP_Stop);
5429 }
5430
5431 return 0;
5432 }
5433
5434 int peer_local_as_unset(struct peer *peer)
5435 {
5436 struct peer *member;
5437 struct listnode *node, *nnode;
5438
5439 if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS))
5440 return 0;
5441
5442 /* Inherit configuration from peer-group if peer is member. */
5443 if (peer_group_active(peer)) {
5444 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS);
5445 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5446 peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5447 PEER_ATTR_INHERIT(peer, peer->group, change_local_as);
5448 } else {
5449 /* Otherwise remove flag and configuration from peer. */
5450 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS);
5451 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5452 peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5453 peer->change_local_as = 0;
5454 }
5455
5456 /* Check if handling a regular peer. */
5457 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5458 /* Send notification or stop peer depending on state. */
5459 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5460 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5461 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5462 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5463 } else
5464 BGP_EVENT_ADD(peer, BGP_Stop);
5465
5466 /* Skip peer-group mechanics for regular peers. */
5467 return 0;
5468 }
5469
5470 /*
5471 * Remove flag and configuration from all peer-group members, unless
5472 * they are explicitely overriding peer-group configuration.
5473 */
5474 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5475 /* Skip peers with overridden configuration. */
5476 if (CHECK_FLAG(member->flags_override, PEER_FLAG_LOCAL_AS))
5477 continue;
5478
5479 /* Remove flag and configuration on peer-group member. */
5480 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS);
5481 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5482 UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5483 member->change_local_as = 0;
5484
5485 /* Send notification or stop peer depending on state. */
5486 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {
5487 member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5488 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5489 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5490 } else
5491 bgp_session_reset(member);
5492 }
5493
5494 return 0;
5495 }
5496
5497 /* Set password for authenticating with the peer. */
5498 int peer_password_set(struct peer *peer, const char *password)
5499 {
5500 struct peer *member;
5501 struct listnode *node, *nnode;
5502 int len = password ? strlen(password) : 0;
5503 int ret = BGP_SUCCESS;
5504
5505 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
5506 return BGP_ERR_INVALID_VALUE;
5507
5508 /* Set flag and configuration on peer. */
5509 peer_flag_set(peer, PEER_FLAG_PASSWORD);
5510 if (peer->password && strcmp(peer->password, password) == 0)
5511 return 0;
5512 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5513 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
5514
5515 /* Check if handling a regular peer. */
5516 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5517 /* Send notification or reset peer depending on state. */
5518 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5519 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5520 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5521 else
5522 bgp_session_reset(peer);
5523
5524 /*
5525 * Attempt to install password on socket and skip peer-group
5526 * mechanics.
5527 */
5528 if (BGP_PEER_SU_UNSPEC(peer))
5529 return BGP_SUCCESS;
5530 return (bgp_md5_set(peer) >= 0) ? BGP_SUCCESS
5531 : BGP_ERR_TCPSIG_FAILED;
5532 }
5533
5534 /*
5535 * Set flag and configuration on all peer-group members, unless they are
5536 * explicitely overriding peer-group configuration.
5537 */
5538 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5539 /* Skip peers with overridden configuration. */
5540 if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
5541 continue;
5542
5543 /* Skip peers with the same password. */
5544 if (member->password && strcmp(member->password, password) == 0)
5545 continue;
5546
5547 /* Set flag and configuration on peer-group member. */
5548 SET_FLAG(member->flags, PEER_FLAG_PASSWORD);
5549 if (member->password)
5550 XFREE(MTYPE_PEER_PASSWORD, member->password);
5551 member->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
5552
5553 /* Send notification or reset peer depending on state. */
5554 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
5555 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5556 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5557 else
5558 bgp_session_reset(member);
5559
5560 /* Attempt to install password on socket. */
5561 if (!BGP_PEER_SU_UNSPEC(member) && bgp_md5_set(member) < 0)
5562 ret = BGP_ERR_TCPSIG_FAILED;
5563 }
5564
5565 /* Set flag and configuration on all peer-group listen ranges */
5566 struct listnode *ln;
5567 struct prefix *lr;
5568
5569 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
5570 bgp_md5_set_prefix(lr, password);
5571 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
5572 bgp_md5_set_prefix(lr, password);
5573
5574 return ret;
5575 }
5576
5577 int peer_password_unset(struct peer *peer)
5578 {
5579 struct peer *member;
5580 struct listnode *node, *nnode;
5581
5582 if (!CHECK_FLAG(peer->flags, PEER_FLAG_PASSWORD))
5583 return 0;
5584
5585 /* Inherit configuration from peer-group if peer is member. */
5586 if (peer_group_active(peer)) {
5587 peer_flag_inherit(peer, PEER_FLAG_PASSWORD);
5588 PEER_STR_ATTR_INHERIT(peer, peer->group, password,
5589 MTYPE_PEER_PASSWORD);
5590 } else {
5591 /* Otherwise remove flag and configuration from peer. */
5592 peer_flag_unset(peer, PEER_FLAG_PASSWORD);
5593 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5594 }
5595
5596 /* Check if handling a regular peer. */
5597 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5598 /* Send notification or reset peer depending on state. */
5599 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5600 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5601 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5602 else
5603 bgp_session_reset(peer);
5604
5605 /* Attempt to uninstall password on socket. */
5606 if (!BGP_PEER_SU_UNSPEC(peer))
5607 bgp_md5_unset(peer);
5608
5609 /* Skip peer-group mechanics for regular peers. */
5610 return 0;
5611 }
5612
5613 /*
5614 * Remove flag and configuration from all peer-group members, unless
5615 * they are explicitely overriding peer-group configuration.
5616 */
5617 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5618 /* Skip peers with overridden configuration. */
5619 if (CHECK_FLAG(member->flags_override, PEER_FLAG_PASSWORD))
5620 continue;
5621
5622 /* Remove flag and configuration on peer-group member. */
5623 UNSET_FLAG(member->flags, PEER_FLAG_PASSWORD);
5624 XFREE(MTYPE_PEER_PASSWORD, member->password);
5625
5626 /* Send notification or reset peer depending on state. */
5627 if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status))
5628 bgp_notify_send(member, BGP_NOTIFY_CEASE,
5629 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5630 else
5631 bgp_session_reset(member);
5632
5633 /* Attempt to uninstall password on socket. */
5634 if (!BGP_PEER_SU_UNSPEC(member))
5635 bgp_md5_unset(member);
5636 }
5637
5638 /* Set flag and configuration on all peer-group listen ranges */
5639 struct listnode *ln;
5640 struct prefix *lr;
5641
5642 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP], ln, lr))
5643 bgp_md5_unset_prefix(lr);
5644 for (ALL_LIST_ELEMENTS_RO(peer->group->listen_range[AFI_IP6], ln, lr))
5645 bgp_md5_unset_prefix(lr);
5646
5647 return 0;
5648 }
5649
5650
5651 /* Set distribute list to the peer. */
5652 int peer_distribute_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5653 const char *name)
5654 {
5655 struct peer *member;
5656 struct bgp_filter *filter;
5657 struct listnode *node, *nnode;
5658
5659 if (direct != FILTER_IN && direct != FILTER_OUT)
5660 return BGP_ERR_INVALID_VALUE;
5661
5662 /* Set configuration on peer. */
5663 filter = &peer->filter[afi][safi];
5664 if (filter->plist[direct].name)
5665 return BGP_ERR_PEER_FILTER_CONFLICT;
5666 if (filter->dlist[direct].name)
5667 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[direct].name);
5668 filter->dlist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5669 filter->dlist[direct].alist = access_list_lookup(afi, name);
5670
5671 /* Check if handling a regular peer. */
5672 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5673 /* Set override-flag and process peer route updates. */
5674 SET_FLAG(peer->filter_override[afi][safi][direct],
5675 PEER_FT_DISTRIBUTE_LIST);
5676 peer_on_policy_change(peer, afi, safi,
5677 (direct == FILTER_OUT) ? 1 : 0);
5678
5679 /* Skip peer-group mechanics for regular peers. */
5680 return 0;
5681 }
5682
5683 /*
5684 * Set configuration on all peer-group members, un less they are
5685 * explicitely overriding peer-group configuration.
5686 */
5687 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5688 /* Skip peers with overridden configuration. */
5689 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5690 PEER_FT_DISTRIBUTE_LIST))
5691 continue;
5692
5693 /* Set configuration on peer-group member. */
5694 filter = &member->filter[afi][safi];
5695 if (filter->dlist[direct].name)
5696 XFREE(MTYPE_BGP_FILTER_NAME,
5697 filter->dlist[direct].name);
5698 filter->dlist[direct].name =
5699 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5700 filter->dlist[direct].alist = access_list_lookup(afi, name);
5701
5702 /* Process peer route updates. */
5703 peer_on_policy_change(member, afi, safi,
5704 (direct == FILTER_OUT) ? 1 : 0);
5705 }
5706
5707 return 0;
5708 }
5709
5710 int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
5711 {
5712 struct peer *member;
5713 struct bgp_filter *filter;
5714 struct listnode *node, *nnode;
5715
5716 if (direct != FILTER_IN && direct != FILTER_OUT)
5717 return BGP_ERR_INVALID_VALUE;
5718
5719 /* Unset override-flag unconditionally. */
5720 UNSET_FLAG(peer->filter_override[afi][safi][direct],
5721 PEER_FT_DISTRIBUTE_LIST);
5722
5723 /* Inherit configuration from peer-group if peer is member. */
5724 if (peer_group_active(peer)) {
5725 PEER_STR_ATTR_INHERIT(peer, peer->group,
5726 filter[afi][safi].dlist[direct].name,
5727 MTYPE_BGP_FILTER_NAME);
5728 PEER_ATTR_INHERIT(peer, peer->group,
5729 filter[afi][safi].dlist[direct].alist);
5730 } else {
5731 /* Otherwise remove configuration from peer. */
5732 filter = &peer->filter[afi][safi];
5733 if (filter->dlist[direct].name)
5734 XFREE(MTYPE_BGP_FILTER_NAME,
5735 filter->dlist[direct].name);
5736 filter->dlist[direct].name = NULL;
5737 filter->dlist[direct].alist = NULL;
5738 }
5739
5740 /* Check if handling a regular peer. */
5741 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5742 /* Process peer route updates. */
5743 peer_on_policy_change(peer, afi, safi,
5744 (direct == FILTER_OUT) ? 1 : 0);
5745
5746 /* Skip peer-group mechanics for regular peers. */
5747 return 0;
5748 }
5749
5750 /*
5751 * Remove configuration on all peer-group members, unless they are
5752 * explicitely overriding peer-group configuration.
5753 */
5754 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5755 /* Skip peers with overridden configuration. */
5756 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5757 PEER_FT_DISTRIBUTE_LIST))
5758 continue;
5759
5760 /* Remove configuration on peer-group member. */
5761 filter = &member->filter[afi][safi];
5762 if (filter->dlist[direct].name)
5763 XFREE(MTYPE_BGP_FILTER_NAME,
5764 filter->dlist[direct].name);
5765 filter->dlist[direct].name = NULL;
5766 filter->dlist[direct].alist = NULL;
5767
5768 /* Process peer route updates. */
5769 peer_on_policy_change(member, afi, safi,
5770 (direct == FILTER_OUT) ? 1 : 0);
5771 }
5772
5773 return 0;
5774 }
5775
5776 /* Update distribute list. */
5777 static void peer_distribute_update(struct access_list *access)
5778 {
5779 afi_t afi;
5780 safi_t safi;
5781 int direct;
5782 struct listnode *mnode, *mnnode;
5783 struct listnode *node, *nnode;
5784 struct bgp *bgp;
5785 struct peer *peer;
5786 struct peer_group *group;
5787 struct bgp_filter *filter;
5788
5789 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5790 if (access->name)
5791 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
5792 access->name, 0, 0);
5793 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5794 FOREACH_AFI_SAFI (afi, safi) {
5795 filter = &peer->filter[afi][safi];
5796
5797 for (direct = FILTER_IN; direct < FILTER_MAX;
5798 direct++) {
5799 if (filter->dlist[direct].name)
5800 filter->dlist[direct]
5801 .alist = access_list_lookup(
5802 afi,
5803 filter->dlist[direct]
5804 .name);
5805 else
5806 filter->dlist[direct].alist =
5807 NULL;
5808 }
5809 }
5810 }
5811 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
5812 FOREACH_AFI_SAFI (afi, safi) {
5813 filter = &group->conf->filter[afi][safi];
5814
5815 for (direct = FILTER_IN; direct < FILTER_MAX;
5816 direct++) {
5817 if (filter->dlist[direct].name)
5818 filter->dlist[direct]
5819 .alist = access_list_lookup(
5820 afi,
5821 filter->dlist[direct]
5822 .name);
5823 else
5824 filter->dlist[direct].alist =
5825 NULL;
5826 }
5827 }
5828 }
5829 #ifdef ENABLE_BGP_VNC
5830 vnc_prefix_list_update(bgp);
5831 #endif
5832 }
5833 }
5834
5835 /* Set prefix list to the peer. */
5836 int peer_prefix_list_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5837 const char *name)
5838 {
5839 struct peer *member;
5840 struct bgp_filter *filter;
5841 struct listnode *node, *nnode;
5842
5843 if (direct != FILTER_IN && direct != FILTER_OUT)
5844 return BGP_ERR_INVALID_VALUE;
5845
5846 /* Set configuration on peer. */
5847 filter = &peer->filter[afi][safi];
5848 if (filter->dlist[direct].name)
5849 return BGP_ERR_PEER_FILTER_CONFLICT;
5850 if (filter->plist[direct].name)
5851 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[direct].name);
5852 filter->plist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5853 filter->plist[direct].plist = prefix_list_lookup(afi, name);
5854
5855 /* Check if handling a regular peer. */
5856 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5857 /* Set override-flag and process peer route updates. */
5858 SET_FLAG(peer->filter_override[afi][safi][direct],
5859 PEER_FT_PREFIX_LIST);
5860 peer_on_policy_change(peer, afi, safi,
5861 (direct == FILTER_OUT) ? 1 : 0);
5862
5863 /* Skip peer-group mechanics for regular peers. */
5864 return 0;
5865 }
5866
5867 /*
5868 * Set configuration on all peer-group members, unless they are
5869 * explicitely overriding peer-group configuration.
5870 */
5871 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5872 /* Skip peers with overridden configuration. */
5873 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5874 PEER_FT_PREFIX_LIST))
5875 continue;
5876
5877 /* Set configuration on peer-group member. */
5878 filter = &member->filter[afi][safi];
5879 if (filter->plist[direct].name)
5880 XFREE(MTYPE_BGP_FILTER_NAME,
5881 filter->plist[direct].name);
5882 filter->plist[direct].name =
5883 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5884 filter->plist[direct].plist = prefix_list_lookup(afi, name);
5885
5886 /* Process peer route updates. */
5887 peer_on_policy_change(member, afi, safi,
5888 (direct == FILTER_OUT) ? 1 : 0);
5889 }
5890
5891 return 0;
5892 }
5893
5894 int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi,
5895 int direct)
5896 {
5897 struct peer *member;
5898 struct bgp_filter *filter;
5899 struct listnode *node, *nnode;
5900
5901 if (direct != FILTER_IN && direct != FILTER_OUT)
5902 return BGP_ERR_INVALID_VALUE;
5903
5904 /* Unset override-flag unconditionally. */
5905 UNSET_FLAG(peer->filter_override[afi][safi][direct],
5906 PEER_FT_PREFIX_LIST);
5907
5908 /* Inherit configuration from peer-group if peer is member. */
5909 if (peer_group_active(peer)) {
5910 PEER_STR_ATTR_INHERIT(peer, peer->group,
5911 filter[afi][safi].plist[direct].name,
5912 MTYPE_BGP_FILTER_NAME);
5913 PEER_ATTR_INHERIT(peer, peer->group,
5914 filter[afi][safi].plist[direct].plist);
5915 } else {
5916 /* Otherwise remove configuration from peer. */
5917 filter = &peer->filter[afi][safi];
5918 if (filter->plist[direct].name)
5919 XFREE(MTYPE_BGP_FILTER_NAME,
5920 filter->plist[direct].name);
5921 filter->plist[direct].name = NULL;
5922 filter->plist[direct].plist = NULL;
5923 }
5924
5925 /* Check if handling a regular peer. */
5926 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5927 /* Process peer route updates. */
5928 peer_on_policy_change(peer, afi, safi,
5929 (direct == FILTER_OUT) ? 1 : 0);
5930
5931 /* Skip peer-group mechanics for regular peers. */
5932 return 0;
5933 }
5934
5935 /*
5936 * Remove configuration on all peer-group members, unless they are
5937 * explicitely overriding peer-group configuration.
5938 */
5939 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
5940 /* Skip peers with overridden configuration. */
5941 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
5942 PEER_FT_PREFIX_LIST))
5943 continue;
5944
5945 /* Remove configuration on peer-group member. */
5946 filter = &member->filter[afi][safi];
5947 if (filter->plist[direct].name)
5948 XFREE(MTYPE_BGP_FILTER_NAME,
5949 filter->plist[direct].name);
5950 filter->plist[direct].name = NULL;
5951 filter->plist[direct].plist = NULL;
5952
5953 /* Process peer route updates. */
5954 peer_on_policy_change(member, afi, safi,
5955 (direct == FILTER_OUT) ? 1 : 0);
5956 }
5957
5958 return 0;
5959 }
5960
5961 /* Update prefix-list list. */
5962 static void peer_prefix_list_update(struct prefix_list *plist)
5963 {
5964 struct listnode *mnode, *mnnode;
5965 struct listnode *node, *nnode;
5966 struct bgp *bgp;
5967 struct peer *peer;
5968 struct peer_group *group;
5969 struct bgp_filter *filter;
5970 afi_t afi;
5971 safi_t safi;
5972 int direct;
5973
5974 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5975
5976 /*
5977 * Update the prefix-list on update groups.
5978 */
5979 update_group_policy_update(
5980 bgp, BGP_POLICY_PREFIX_LIST,
5981 plist ? prefix_list_name(plist) : NULL, 0, 0);
5982
5983 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5984 FOREACH_AFI_SAFI (afi, safi) {
5985 filter = &peer->filter[afi][safi];
5986
5987 for (direct = FILTER_IN; direct < FILTER_MAX;
5988 direct++) {
5989 if (filter->plist[direct].name)
5990 filter->plist[direct]
5991 .plist = prefix_list_lookup(
5992 afi,
5993 filter->plist[direct]
5994 .name);
5995 else
5996 filter->plist[direct].plist =
5997 NULL;
5998 }
5999 }
6000 }
6001 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6002 FOREACH_AFI_SAFI (afi, safi) {
6003 filter = &group->conf->filter[afi][safi];
6004
6005 for (direct = FILTER_IN; direct < FILTER_MAX;
6006 direct++) {
6007 if (filter->plist[direct].name)
6008 filter->plist[direct]
6009 .plist = prefix_list_lookup(
6010 afi,
6011 filter->plist[direct]
6012 .name);
6013 else
6014 filter->plist[direct].plist =
6015 NULL;
6016 }
6017 }
6018 }
6019 }
6020 }
6021
6022 int peer_aslist_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6023 const char *name)
6024 {
6025 struct peer *member;
6026 struct bgp_filter *filter;
6027 struct listnode *node, *nnode;
6028
6029 if (direct != FILTER_IN && direct != FILTER_OUT)
6030 return BGP_ERR_INVALID_VALUE;
6031
6032 /* Set configuration on peer. */
6033 filter = &peer->filter[afi][safi];
6034 if (filter->aslist[direct].name)
6035 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[direct].name);
6036 filter->aslist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6037 filter->aslist[direct].aslist = as_list_lookup(name);
6038
6039 /* Check if handling a regular peer. */
6040 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6041 /* Set override-flag and process peer route updates. */
6042 SET_FLAG(peer->filter_override[afi][safi][direct],
6043 PEER_FT_FILTER_LIST);
6044 peer_on_policy_change(peer, afi, safi,
6045 (direct == FILTER_OUT) ? 1 : 0);
6046
6047 /* Skip peer-group mechanics for regular peers. */
6048 return 0;
6049 }
6050
6051 /*
6052 * Set configuration on all peer-group members, unless they are
6053 * explicitely overriding peer-group configuration.
6054 */
6055 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6056 /* Skip peers with overridden configuration. */
6057 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6058 PEER_FT_FILTER_LIST))
6059 continue;
6060
6061 /* Set configuration on peer-group member. */
6062 filter = &member->filter[afi][safi];
6063 if (filter->aslist[direct].name)
6064 XFREE(MTYPE_BGP_FILTER_NAME,
6065 filter->aslist[direct].name);
6066 filter->aslist[direct].name =
6067 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6068 filter->aslist[direct].aslist = as_list_lookup(name);
6069
6070 /* Process peer route updates. */
6071 peer_on_policy_change(member, afi, safi,
6072 (direct == FILTER_OUT) ? 1 : 0);
6073 }
6074
6075 return 0;
6076 }
6077
6078 int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
6079 {
6080 struct peer *member;
6081 struct bgp_filter *filter;
6082 struct listnode *node, *nnode;
6083
6084 if (direct != FILTER_IN && direct != FILTER_OUT)
6085 return BGP_ERR_INVALID_VALUE;
6086
6087 /* Unset override-flag unconditionally. */
6088 UNSET_FLAG(peer->filter_override[afi][safi][direct],
6089 PEER_FT_FILTER_LIST);
6090
6091 /* Inherit configuration from peer-group if peer is member. */
6092 if (peer_group_active(peer)) {
6093 PEER_STR_ATTR_INHERIT(peer, peer->group,
6094 filter[afi][safi].aslist[direct].name,
6095 MTYPE_BGP_FILTER_NAME);
6096 PEER_ATTR_INHERIT(peer, peer->group,
6097 filter[afi][safi].aslist[direct].aslist);
6098 } else {
6099 /* Otherwise remove configuration from peer. */
6100 filter = &peer->filter[afi][safi];
6101 if (filter->aslist[direct].name)
6102 XFREE(MTYPE_BGP_FILTER_NAME,
6103 filter->aslist[direct].name);
6104 filter->aslist[direct].name = NULL;
6105 filter->aslist[direct].aslist = NULL;
6106 }
6107
6108 /* Check if handling a regular peer. */
6109 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6110 /* Process peer route updates. */
6111 peer_on_policy_change(peer, afi, safi,
6112 (direct == FILTER_OUT) ? 1 : 0);
6113
6114 /* Skip peer-group mechanics for regular peers. */
6115 return 0;
6116 }
6117
6118 /*
6119 * Remove configuration on all peer-group members, unless they are
6120 * explicitely overriding peer-group configuration.
6121 */
6122 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6123 /* Skip peers with overridden configuration. */
6124 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6125 PEER_FT_FILTER_LIST))
6126 continue;
6127
6128 /* Remove configuration on peer-group member. */
6129 filter = &member->filter[afi][safi];
6130 if (filter->aslist[direct].name)
6131 XFREE(MTYPE_BGP_FILTER_NAME,
6132 filter->aslist[direct].name);
6133 filter->aslist[direct].name = NULL;
6134 filter->aslist[direct].aslist = NULL;
6135
6136 /* Process peer route updates. */
6137 peer_on_policy_change(member, afi, safi,
6138 (direct == FILTER_OUT) ? 1 : 0);
6139 }
6140
6141 return 0;
6142 }
6143
6144 static void peer_aslist_update(const char *aslist_name)
6145 {
6146 afi_t afi;
6147 safi_t safi;
6148 int direct;
6149 struct listnode *mnode, *mnnode;
6150 struct listnode *node, *nnode;
6151 struct bgp *bgp;
6152 struct peer *peer;
6153 struct peer_group *group;
6154 struct bgp_filter *filter;
6155
6156 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
6157 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
6158 aslist_name, 0, 0);
6159
6160 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
6161 FOREACH_AFI_SAFI (afi, safi) {
6162 filter = &peer->filter[afi][safi];
6163
6164 for (direct = FILTER_IN; direct < FILTER_MAX;
6165 direct++) {
6166 if (filter->aslist[direct].name)
6167 filter->aslist[direct]
6168 .aslist = as_list_lookup(
6169 filter->aslist[direct]
6170 .name);
6171 else
6172 filter->aslist[direct].aslist =
6173 NULL;
6174 }
6175 }
6176 }
6177 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
6178 FOREACH_AFI_SAFI (afi, safi) {
6179 filter = &group->conf->filter[afi][safi];
6180
6181 for (direct = FILTER_IN; direct < FILTER_MAX;
6182 direct++) {
6183 if (filter->aslist[direct].name)
6184 filter->aslist[direct]
6185 .aslist = as_list_lookup(
6186 filter->aslist[direct]
6187 .name);
6188 else
6189 filter->aslist[direct].aslist =
6190 NULL;
6191 }
6192 }
6193 }
6194 }
6195 }
6196
6197 static void peer_aslist_add(char *aslist_name)
6198 {
6199 peer_aslist_update(aslist_name);
6200 route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_ADDED);
6201 }
6202
6203 static void peer_aslist_del(const char *aslist_name)
6204 {
6205 peer_aslist_update(aslist_name);
6206 route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_DELETED);
6207 }
6208
6209
6210 int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
6211 const char *name, struct route_map *route_map)
6212 {
6213 struct peer *member;
6214 struct bgp_filter *filter;
6215 struct listnode *node, *nnode;
6216
6217 if (direct != RMAP_IN && direct != RMAP_OUT)
6218 return BGP_ERR_INVALID_VALUE;
6219
6220 /* Set configuration on peer. */
6221 filter = &peer->filter[afi][safi];
6222 if (filter->map[direct].name) {
6223 /* If the neighbor is configured with the same route-map
6224 * again then, ignore the duplicate configuration.
6225 */
6226 if (strcmp(filter->map[direct].name, name) == 0)
6227 return 0;
6228
6229 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6230 }
6231 route_map_counter_decrement(filter->map[direct].map);
6232 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6233 filter->map[direct].map = route_map;
6234 route_map_counter_increment(route_map);
6235
6236 /* Check if handling a regular peer. */
6237 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6238 /* Set override-flag and process peer route updates. */
6239 SET_FLAG(peer->filter_override[afi][safi][direct],
6240 PEER_FT_ROUTE_MAP);
6241 peer_on_policy_change(peer, afi, safi,
6242 (direct == RMAP_OUT) ? 1 : 0);
6243
6244 /* Skip peer-group mechanics for regular peers. */
6245 return 0;
6246 }
6247
6248 /*
6249 * Set configuration on all peer-group members, unless they are
6250 * explicitely overriding peer-group configuration.
6251 */
6252 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6253 /* Skip peers with overridden configuration. */
6254 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6255 PEER_FT_ROUTE_MAP))
6256 continue;
6257
6258 /* Set configuration on peer-group member. */
6259 filter = &member->filter[afi][safi];
6260 if (filter->map[direct].name)
6261 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6262 route_map_counter_decrement(filter->map[direct].map);
6263 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6264 filter->map[direct].map = route_map;
6265 route_map_counter_increment(route_map);
6266
6267 /* Process peer route updates. */
6268 peer_on_policy_change(member, afi, safi,
6269 (direct == RMAP_OUT) ? 1 : 0);
6270 }
6271 return 0;
6272 }
6273
6274 /* Unset route-map from the peer. */
6275 int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
6276 {
6277 struct peer *member;
6278 struct bgp_filter *filter;
6279 struct listnode *node, *nnode;
6280
6281 if (direct != RMAP_IN && direct != RMAP_OUT)
6282 return BGP_ERR_INVALID_VALUE;
6283
6284 /* Unset override-flag unconditionally. */
6285 UNSET_FLAG(peer->filter_override[afi][safi][direct], PEER_FT_ROUTE_MAP);
6286
6287 /* Inherit configuration from peer-group if peer is member. */
6288 if (peer_group_active(peer)) {
6289 PEER_STR_ATTR_INHERIT(peer, peer->group,
6290 filter[afi][safi].map[direct].name,
6291 MTYPE_BGP_FILTER_NAME);
6292 PEER_ATTR_INHERIT(peer, peer->group,
6293 filter[afi][safi].map[direct].map);
6294 } else {
6295 /* Otherwise remove configuration from peer. */
6296 filter = &peer->filter[afi][safi];
6297 if (filter->map[direct].name)
6298 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6299 route_map_counter_decrement(filter->map[direct].map);
6300 filter->map[direct].name = NULL;
6301 filter->map[direct].map = NULL;
6302 }
6303
6304 /* Check if handling a regular peer. */
6305 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6306 /* Process peer route updates. */
6307 peer_on_policy_change(peer, afi, safi,
6308 (direct == RMAP_OUT) ? 1 : 0);
6309
6310 /* Skip peer-group mechanics for regular peers. */
6311 return 0;
6312 }
6313
6314 /*
6315 * Remove configuration on all peer-group members, unless they are
6316 * explicitely overriding peer-group configuration.
6317 */
6318 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6319 /* Skip peers with overridden configuration. */
6320 if (CHECK_FLAG(member->filter_override[afi][safi][direct],
6321 PEER_FT_ROUTE_MAP))
6322 continue;
6323
6324 /* Remove configuration on peer-group member. */
6325 filter = &member->filter[afi][safi];
6326 if (filter->map[direct].name)
6327 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
6328 route_map_counter_decrement(filter->map[direct].map);
6329 filter->map[direct].name = NULL;
6330 filter->map[direct].map = NULL;
6331
6332 /* Process peer route updates. */
6333 peer_on_policy_change(member, afi, safi,
6334 (direct == RMAP_OUT) ? 1 : 0);
6335 }
6336
6337 return 0;
6338 }
6339
6340 /* Set unsuppress-map to the peer. */
6341 int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
6342 const char *name, struct route_map *route_map)
6343 {
6344 struct peer *member;
6345 struct bgp_filter *filter;
6346 struct listnode *node, *nnode;
6347
6348 /* Set configuration on peer. */
6349 filter = &peer->filter[afi][safi];
6350 if (filter->usmap.name)
6351 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6352 route_map_counter_decrement(filter->usmap.map);
6353 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6354 filter->usmap.map = route_map;
6355 route_map_counter_increment(route_map);
6356
6357 /* Check if handling a regular peer. */
6358 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6359 /* Set override-flag and process peer route updates. */
6360 SET_FLAG(peer->filter_override[afi][safi][0],
6361 PEER_FT_UNSUPPRESS_MAP);
6362 peer_on_policy_change(peer, afi, safi, 1);
6363
6364 /* Skip peer-group mechanics for regular peers. */
6365 return 0;
6366 }
6367
6368 /*
6369 * Set configuration on all peer-group members, unless they are
6370 * explicitely overriding peer-group configuration.
6371 */
6372 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6373 /* Skip peers with overridden configuration. */
6374 if (CHECK_FLAG(member->filter_override[afi][safi][0],
6375 PEER_FT_UNSUPPRESS_MAP))
6376 continue;
6377
6378 /* Set configuration on peer-group member. */
6379 filter = &member->filter[afi][safi];
6380 if (filter->usmap.name)
6381 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6382 route_map_counter_decrement(filter->usmap.map);
6383 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
6384 filter->usmap.map = route_map;
6385 route_map_counter_increment(route_map);
6386
6387 /* Process peer route updates. */
6388 peer_on_policy_change(member, afi, safi, 1);
6389 }
6390
6391 return 0;
6392 }
6393
6394 /* Unset route-map from the peer. */
6395 int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
6396 {
6397 struct peer *member;
6398 struct bgp_filter *filter;
6399 struct listnode *node, *nnode;
6400
6401 /* Unset override-flag unconditionally. */
6402 UNSET_FLAG(peer->filter_override[afi][safi][0], PEER_FT_UNSUPPRESS_MAP);
6403
6404 /* Inherit configuration from peer-group if peer is member. */
6405 if (peer_group_active(peer)) {
6406 PEER_STR_ATTR_INHERIT(peer, peer->group,
6407 filter[afi][safi].usmap.name,
6408 MTYPE_BGP_FILTER_NAME);
6409 PEER_ATTR_INHERIT(peer, peer->group,
6410 filter[afi][safi].usmap.map);
6411 } else {
6412 /* Otherwise remove configuration from peer. */
6413 filter = &peer->filter[afi][safi];
6414 if (filter->usmap.name)
6415 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6416 route_map_counter_decrement(filter->usmap.map);
6417 filter->usmap.name = NULL;
6418 filter->usmap.map = NULL;
6419 }
6420
6421 /* Check if handling a regular peer. */
6422 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6423 /* Process peer route updates. */
6424 peer_on_policy_change(peer, afi, safi, 1);
6425
6426 /* Skip peer-group mechanics for regular peers. */
6427 return 0;
6428 }
6429
6430 /*
6431 * Remove configuration on all peer-group members, unless they are
6432 * explicitely overriding peer-group configuration.
6433 */
6434 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6435 /* Skip peers with overridden configuration. */
6436 if (CHECK_FLAG(member->filter_override[afi][safi][0],
6437 PEER_FT_UNSUPPRESS_MAP))
6438 continue;
6439
6440 /* Remove configuration on peer-group member. */
6441 filter = &member->filter[afi][safi];
6442 if (filter->usmap.name)
6443 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
6444 route_map_counter_decrement(filter->usmap.map);
6445 filter->usmap.name = NULL;
6446 filter->usmap.map = NULL;
6447
6448 /* Process peer route updates. */
6449 peer_on_policy_change(member, afi, safi, 1);
6450 }
6451
6452 return 0;
6453 }
6454
6455 int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
6456 uint32_t max, uint8_t threshold, int warning,
6457 uint16_t restart)
6458 {
6459 struct peer *member;
6460 struct listnode *node, *nnode;
6461
6462 /* Set flags and configuration on peer. */
6463 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
6464 if (warning)
6465 peer_af_flag_set(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
6466 else
6467 peer_af_flag_unset(peer, afi, safi,
6468 PEER_FLAG_MAX_PREFIX_WARNING);
6469
6470 peer->pmax[afi][safi] = max;
6471 peer->pmax_threshold[afi][safi] = threshold;
6472 peer->pmax_restart[afi][safi] = restart;
6473
6474 /* Check if handling a regular peer. */
6475 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6476 /* Re-check if peer violates maximum-prefix. */
6477 if ((peer->status == Established) && (peer->afc[afi][safi]))
6478 bgp_maximum_prefix_overflow(peer, afi, safi, 1);
6479
6480 /* Skip peer-group mechanics for regular peers. */
6481 return 0;
6482 }
6483
6484 /*
6485 * Set flags and configuration on all peer-group members, unless they
6486 * are explicitely overriding peer-group configuration.
6487 */
6488 for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
6489 /* Skip peers with overridden configuration. */
6490 if (CHECK_FLAG(member->af_flags_override[afi][safi],
6491 PEER_FLAG_MAX_PREFIX))
6492 continue;
6493
6494 /* Set flag and configuration on peer-group member. */
6495 member->pmax[afi][safi] = max;
6496 member->pmax_threshold[afi][safi] = threshold;
6497 member->pmax_restart[afi][safi] = restart;
6498 if (warning)
6499 SET_FLAG(member->af_flags[afi][safi],
6500 PEER_FLAG_MAX_PREFIX_WARNING);
6501 else
6502 UNSET_FLAG(member->af_flags[afi][safi],
6503 PEER_FLAG_MAX_PREFIX_WARNING);
6504
6505 /* Re-check if peer violates maximum-prefix. */
6506 if ((member->status == Established) && (member->afc[afi][safi]))
6507 bgp_maximum_prefix_overflow(member, afi, safi, 1);
6508 }
6509
6510 return 0;
6511 }
6512
6513 int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
6514 {
6515 /* Inherit configuration from peer-group if peer is member. */
6516 if (peer_group_active(peer)) {
6517 peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
6518 peer_af_flag_inherit(peer, afi, safi,
6519 PEER_FLAG_MAX_PREFIX_WARNING);
6520 PEER_ATTR_INHERIT(peer, peer->group, pmax[afi][safi]);
6521 PEER_ATTR_INHERIT(peer, peer->group, pmax_threshold[afi][safi]);
6522 PEER_ATTR_INHERIT(peer, peer->group, pmax_restart[afi][safi]);
6523
6524 return 0;
6525 }
6526
6527 /* Remove flags and configuration from peer. */
6528 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX);
6529 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING);
6530 peer->pmax[afi][safi] = 0;
6531 peer->pmax_threshold[afi][safi] = 0;
6532 peer->pmax_restart[afi][safi] = 0;
6533
6534 /*
6535 * Remove flags and configuration from all peer-group members, unless
6536 * they are explicitely overriding peer-group configuration.
6537 */
6538 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6539 struct peer *member;
6540 struct listnode *node;
6541
6542 for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) {
6543 /* Skip peers with overridden configuration. */
6544 if (CHECK_FLAG(member->af_flags_override[afi][safi],
6545 PEER_FLAG_MAX_PREFIX))
6546 continue;
6547
6548 /* Remove flag and configuration on peer-group member.
6549 */
6550 UNSET_FLAG(member->af_flags[afi][safi],
6551 PEER_FLAG_MAX_PREFIX);
6552 UNSET_FLAG(member->af_flags[afi][safi],
6553 PEER_FLAG_MAX_PREFIX_WARNING);
6554 member->pmax[afi][safi] = 0;
6555 member->pmax_threshold[afi][safi] = 0;
6556 member->pmax_restart[afi][safi] = 0;
6557 }
6558 }
6559
6560 return 0;
6561 }
6562
6563 int is_ebgp_multihop_configured(struct peer *peer)
6564 {
6565 struct peer_group *group;
6566 struct listnode *node, *nnode;
6567 struct peer *peer1;
6568
6569 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6570 group = peer->group;
6571 if ((peer_sort(peer) != BGP_PEER_IBGP)
6572 && (group->conf->ttl != BGP_DEFAULT_TTL))
6573 return 1;
6574
6575 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer1)) {
6576 if ((peer_sort(peer1) != BGP_PEER_IBGP)
6577 && (peer1->ttl != BGP_DEFAULT_TTL))
6578 return 1;
6579 }
6580 } else {
6581 if ((peer_sort(peer) != BGP_PEER_IBGP)
6582 && (peer->ttl != BGP_DEFAULT_TTL))
6583 return 1;
6584 }
6585 return 0;
6586 }
6587
6588 /* Set # of hops between us and BGP peer. */
6589 int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops)
6590 {
6591 struct peer_group *group;
6592 struct listnode *node, *nnode;
6593 int ret;
6594
6595 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6596 gtsm_hops, peer->host);
6597
6598 /* We cannot configure ttl-security hops when ebgp-multihop is already
6599 set. For non peer-groups, the check is simple. For peer-groups,
6600 it's
6601 slightly messy, because we need to check both the peer-group
6602 structure
6603 and all peer-group members for any trace of ebgp-multihop
6604 configuration
6605 before actually applying the ttl-security rules. Cisco really made a
6606 mess of this configuration parameter, and OpenBGPD got it right.
6607 */
6608
6609 if ((peer->gtsm_hops == BGP_GTSM_HOPS_DISABLED)
6610 && (peer->sort != BGP_PEER_IBGP)) {
6611 if (is_ebgp_multihop_configured(peer))
6612 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
6613
6614 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6615 peer->gtsm_hops = gtsm_hops;
6616
6617 /* Calling ebgp multihop also resets the session.
6618 * On restart, NHT will get setup correctly as will the
6619 * min & max ttls on the socket. The return value is
6620 * irrelevant.
6621 */
6622 ret = peer_ebgp_multihop_set(peer, MAXTTL);
6623
6624 if (ret != 0)
6625 return ret;
6626 } else {
6627 group = peer->group;
6628 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
6629 peer)) {
6630 peer->gtsm_hops = group->conf->gtsm_hops;
6631
6632 /* Calling ebgp multihop also resets the
6633 * session.
6634 * On restart, NHT will get setup correctly as
6635 * will the
6636 * min & max ttls on the socket. The return
6637 * value is
6638 * irrelevant.
6639 */
6640 peer_ebgp_multihop_set(peer, MAXTTL);
6641 }
6642 }
6643 } else {
6644 /* Post the first gtsm setup or if its ibgp, maxttl setting
6645 * isn't
6646 * necessary, just set the minttl.
6647 */
6648 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6649 peer->gtsm_hops = gtsm_hops;
6650
6651 if (peer->fd >= 0)
6652 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
6653 MAXTTL + 1 - gtsm_hops);
6654 if ((peer->status < Established) && peer->doppelganger
6655 && (peer->doppelganger->fd >= 0))
6656 sockopt_minttl(peer->su.sa.sa_family,
6657 peer->doppelganger->fd,
6658 MAXTTL + 1 - gtsm_hops);
6659 } else {
6660 group = peer->group;
6661 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
6662 peer)) {
6663 peer->gtsm_hops = group->conf->gtsm_hops;
6664
6665 /* Change setting of existing peer
6666 * established then change value (may break
6667 * connectivity)
6668 * not established yet (teardown session and
6669 * restart)
6670 * no session then do nothing (will get
6671 * handled by next connection)
6672 */
6673 if (peer->fd >= 0
6674 && peer->gtsm_hops
6675 != BGP_GTSM_HOPS_DISABLED)
6676 sockopt_minttl(
6677 peer->su.sa.sa_family, peer->fd,
6678 MAXTTL + 1 - peer->gtsm_hops);
6679 if ((peer->status < Established)
6680 && peer->doppelganger
6681 && (peer->doppelganger->fd >= 0))
6682 sockopt_minttl(peer->su.sa.sa_family,
6683 peer->doppelganger->fd,
6684 MAXTTL + 1 - gtsm_hops);
6685 }
6686 }
6687 }
6688
6689 return 0;
6690 }
6691
6692 int peer_ttl_security_hops_unset(struct peer *peer)
6693 {
6694 struct peer_group *group;
6695 struct listnode *node, *nnode;
6696 int ret = 0;
6697
6698 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6699 peer->host);
6700
6701 /* if a peer-group member, then reset to peer-group default rather than
6702 * 0 */
6703 if (peer_group_active(peer))
6704 peer->gtsm_hops = peer->group->conf->gtsm_hops;
6705 else
6706 peer->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
6707
6708 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6709 /* Invoking ebgp_multihop_set will set the TTL back to the
6710 * original
6711 * value as well as restting the NHT and such. The session is
6712 * reset.
6713 */
6714 if (peer->sort == BGP_PEER_EBGP)
6715 ret = peer_ebgp_multihop_unset(peer);
6716 else {
6717 if (peer->fd >= 0)
6718 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
6719 0);
6720
6721 if ((peer->status < Established) && peer->doppelganger
6722 && (peer->doppelganger->fd >= 0))
6723 sockopt_minttl(peer->su.sa.sa_family,
6724 peer->doppelganger->fd, 0);
6725 }
6726 } else {
6727 group = peer->group;
6728 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
6729 peer->gtsm_hops = BGP_GTSM_HOPS_DISABLED;
6730 if (peer->sort == BGP_PEER_EBGP)
6731 ret = peer_ebgp_multihop_unset(peer);
6732 else {
6733 if (peer->fd >= 0)
6734 sockopt_minttl(peer->su.sa.sa_family,
6735 peer->fd, 0);
6736
6737 if ((peer->status < Established)
6738 && peer->doppelganger
6739 && (peer->doppelganger->fd >= 0))
6740 sockopt_minttl(peer->su.sa.sa_family,
6741 peer->doppelganger->fd,
6742 0);
6743 }
6744 }
6745 }
6746
6747 return ret;
6748 }
6749
6750 /*
6751 * If peer clear is invoked in a loop for all peers on the BGP instance,
6752 * it may end up freeing the doppelganger, and if this was the next node
6753 * to the current node, we would end up accessing the freed next node.
6754 * Pass along additional parameter which can be updated if next node
6755 * is freed; only required when walking the peer list on BGP instance.
6756 */
6757 int peer_clear(struct peer *peer, struct listnode **nnode)
6758 {
6759 if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) {
6760 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) {
6761 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
6762 if (peer->t_pmax_restart) {
6763 BGP_TIMER_OFF(peer->t_pmax_restart);
6764 if (bgp_debug_neighbor_events(peer))
6765 zlog_debug(
6766 "%s Maximum-prefix restart timer canceled",
6767 peer->host);
6768 }
6769 BGP_EVENT_ADD(peer, BGP_Start);
6770 return 0;
6771 }
6772
6773 peer->v_start = BGP_INIT_START_TIMER;
6774 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6775 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6776 BGP_NOTIFY_CEASE_ADMIN_RESET);
6777 else
6778 bgp_session_reset_safe(peer, nnode);
6779 }
6780 return 0;
6781 }
6782
6783 int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi,
6784 enum bgp_clear_type stype)
6785 {
6786 struct peer_af *paf;
6787
6788 if (peer->status != Established)
6789 return 0;
6790
6791 if (!peer->afc[afi][safi])
6792 return BGP_ERR_AF_UNCONFIGURED;
6793
6794 peer->rtt = sockopt_tcp_rtt(peer->fd);
6795
6796 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) {
6797 /* Clear the "neighbor x.x.x.x default-originate" flag */
6798 paf = peer_af_find(peer, afi, safi);
6799 if (paf && paf->subgroup
6800 && CHECK_FLAG(paf->subgroup->sflags,
6801 SUBGRP_STATUS_DEFAULT_ORIGINATE))
6802 UNSET_FLAG(paf->subgroup->sflags,
6803 SUBGRP_STATUS_DEFAULT_ORIGINATE);
6804
6805 bgp_announce_route(peer, afi, safi);
6806 }
6807
6808 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
6809 if (CHECK_FLAG(peer->af_cap[afi][safi],
6810 PEER_CAP_ORF_PREFIX_SM_ADV)
6811 && (CHECK_FLAG(peer->af_cap[afi][safi],
6812 PEER_CAP_ORF_PREFIX_RM_RCV)
6813 || CHECK_FLAG(peer->af_cap[afi][safi],
6814 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))) {
6815 struct bgp_filter *filter = &peer->filter[afi][safi];
6816 uint8_t prefix_type;
6817
6818 if (CHECK_FLAG(peer->af_cap[afi][safi],
6819 PEER_CAP_ORF_PREFIX_RM_RCV))
6820 prefix_type = ORF_TYPE_PREFIX;
6821 else
6822 prefix_type = ORF_TYPE_PREFIX_OLD;
6823
6824 if (filter->plist[FILTER_IN].plist) {
6825 if (CHECK_FLAG(peer->af_sflags[afi][safi],
6826 PEER_STATUS_ORF_PREFIX_SEND))
6827 bgp_route_refresh_send(
6828 peer, afi, safi, prefix_type,
6829 REFRESH_DEFER, 1);
6830 bgp_route_refresh_send(peer, afi, safi,
6831 prefix_type,
6832 REFRESH_IMMEDIATE, 0);
6833 } else {
6834 if (CHECK_FLAG(peer->af_sflags[afi][safi],
6835 PEER_STATUS_ORF_PREFIX_SEND))
6836 bgp_route_refresh_send(
6837 peer, afi, safi, prefix_type,
6838 REFRESH_IMMEDIATE, 1);
6839 else
6840 bgp_route_refresh_send(peer, afi, safi,
6841 0, 0, 0);
6842 }
6843 return 0;
6844 }
6845 }
6846
6847 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
6848 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
6849 /* If neighbor has soft reconfiguration inbound flag.
6850 Use Adj-RIB-In database. */
6851 if (CHECK_FLAG(peer->af_flags[afi][safi],
6852 PEER_FLAG_SOFT_RECONFIG))
6853 bgp_soft_reconfig_in(peer, afi, safi);
6854 else {
6855 /* If neighbor has route refresh capability, send route
6856 refresh
6857 message to the peer. */
6858 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
6859 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
6860 bgp_route_refresh_send(peer, afi, safi, 0, 0,
6861 0);
6862 else
6863 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
6864 }
6865 }
6866 return 0;
6867 }
6868
6869 /* Display peer uptime.*/
6870 char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
6871 json_object *json)
6872 {
6873 time_t uptime1, epoch_tbuf;
6874 struct tm tm;
6875
6876 /* If there is no connection has been done before print `never'. */
6877 if (uptime2 == 0) {
6878 if (use_json) {
6879 json_object_string_add(json, "peerUptime", "never");
6880 json_object_int_add(json, "peerUptimeMsec", 0);
6881 } else
6882 snprintf(buf, len, "never");
6883 return buf;
6884 }
6885
6886 /* Get current time. */
6887 uptime1 = bgp_clock();
6888 uptime1 -= uptime2;
6889 gmtime_r(&uptime1, &tm);
6890
6891 if (uptime1 < ONE_DAY_SECOND)
6892 snprintf(buf, len, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min,
6893 tm.tm_sec);
6894 else if (uptime1 < ONE_WEEK_SECOND)
6895 snprintf(buf, len, "%dd%02dh%02dm", tm.tm_yday, tm.tm_hour,
6896 tm.tm_min);
6897 else if (uptime1 < ONE_YEAR_SECOND)
6898 snprintf(buf, len, "%02dw%dd%02dh", tm.tm_yday / 7,
6899 tm.tm_yday - ((tm.tm_yday / 7) * 7), tm.tm_hour);
6900 else
6901 snprintf(buf, len, "%02dy%02dw%dd", tm.tm_year - 70,
6902 tm.tm_yday / 7,
6903 tm.tm_yday - ((tm.tm_yday / 7) * 7));
6904
6905 if (use_json) {
6906 epoch_tbuf = time(NULL) - uptime1;
6907 json_object_string_add(json, "peerUptime", buf);
6908 json_object_int_add(json, "peerUptimeMsec", uptime1 * 1000);
6909 json_object_int_add(json, "peerUptimeEstablishedEpoch",
6910 epoch_tbuf);
6911 }
6912
6913 return buf;
6914 }
6915
6916 void bgp_master_init(struct thread_master *master, const int buffer_size)
6917 {
6918 qobj_init();
6919
6920 memset(&bgp_master, 0, sizeof(struct bgp_master));
6921
6922 bm = &bgp_master;
6923 bm->bgp = list_new();
6924 bm->listen_sockets = list_new();
6925 bm->port = BGP_PORT_DEFAULT;
6926 bm->master = master;
6927 bm->start_time = bgp_clock();
6928 bm->t_rmap_update = NULL;
6929 bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
6930 bm->terminating = false;
6931 bm->socket_buffer = buffer_size;
6932
6933 bgp_process_queue_init();
6934
6935 bgp_mac_init();
6936 /* init the rd id space.
6937 assign 0th index in the bitfield,
6938 so that we start with id 1
6939 */
6940 bf_init(bm->rd_idspace, UINT16_MAX);
6941 bf_assign_zero_index(bm->rd_idspace);
6942
6943 /* mpls label dynamic allocation pool */
6944 bgp_lp_init(bm->master, &bm->labelpool);
6945
6946 QOBJ_REG(bm, bgp_master);
6947 }
6948
6949 /*
6950 * Free up connected routes and interfaces for a BGP instance. Invoked upon
6951 * instance delete (non-default only) or BGP exit.
6952 */
6953 static void bgp_if_finish(struct bgp *bgp)
6954 {
6955 struct vrf *vrf;
6956 struct interface *ifp;
6957
6958 vrf = bgp_vrf_lookup_by_instance_type(bgp);
6959
6960 if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW || !vrf)
6961 return;
6962
6963 FOR_ALL_INTERFACES (vrf, ifp) {
6964 struct listnode *c_node, *c_nnode;
6965 struct connected *c;
6966
6967 for (ALL_LIST_ELEMENTS(ifp->connected, c_node, c_nnode, c))
6968 bgp_connected_delete(bgp, c);
6969 }
6970 }
6971
6972 static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
6973 {
6974 struct vrf *vrf = NULL;
6975 struct listnode *next;
6976 struct bgp *bgp;
6977
6978 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
6979 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
6980
6981 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
6982 if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
6983 continue;
6984
6985 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bgp->name));
6986 }
6987 }
6988
6989 static void bgp_instasn_autocomplete(vector comps, struct cmd_token *token)
6990 {
6991 struct listnode *next, *next2;
6992 struct bgp *bgp, *bgp2;
6993 char buf[11];
6994
6995 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
6996 /* deduplicate */
6997 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next2, bgp2)) {
6998 if (bgp2->as == bgp->as)
6999 break;
7000 if (bgp2 == bgp)
7001 break;
7002 }
7003 if (bgp2 != bgp)
7004 continue;
7005
7006 snprintf(buf, sizeof(buf), "%u", bgp->as);
7007 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, buf));
7008 }
7009 }
7010
7011 static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = {
7012 {.tokenname = "VIEWVRFNAME", .completions = bgp_viewvrf_autocomplete},
7013 {.varname = "instasn", .completions = bgp_instasn_autocomplete},
7014 {.completions = NULL},
7015 };
7016
7017 struct frr_pthread *bgp_pth_io;
7018 struct frr_pthread *bgp_pth_ka;
7019
7020 static void bgp_pthreads_init(void)
7021 {
7022 assert(!bgp_pth_io);
7023 assert(!bgp_pth_ka);
7024
7025 struct frr_pthread_attr io = {
7026 .start = frr_pthread_attr_default.start,
7027 .stop = frr_pthread_attr_default.stop,
7028 };
7029 struct frr_pthread_attr ka = {
7030 .start = bgp_keepalives_start,
7031 .stop = bgp_keepalives_stop,
7032 };
7033 bgp_pth_io = frr_pthread_new(&io, "BGP I/O thread", "bgpd_io");
7034 bgp_pth_ka = frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
7035 }
7036
7037 void bgp_pthreads_run(void)
7038 {
7039 frr_pthread_run(bgp_pth_io, NULL);
7040 frr_pthread_run(bgp_pth_ka, NULL);
7041
7042 /* Wait until threads are ready. */
7043 frr_pthread_wait_running(bgp_pth_io);
7044 frr_pthread_wait_running(bgp_pth_ka);
7045 }
7046
7047 void bgp_pthreads_finish(void)
7048 {
7049 frr_pthread_stop_all();
7050 }
7051
7052 void bgp_init(unsigned short instance)
7053 {
7054
7055 /* allocates some vital data structures used by peer commands in
7056 * vty_init */
7057
7058 /* pre-init pthreads */
7059 bgp_pthreads_init();
7060
7061 /* Init zebra. */
7062 bgp_zebra_init(bm->master, instance);
7063
7064 #ifdef ENABLE_BGP_VNC
7065 vnc_zebra_init(bm->master);
7066 #endif
7067
7068 /* BGP VTY commands installation. */
7069 bgp_vty_init();
7070
7071 /* BGP inits. */
7072 bgp_attr_init();
7073 bgp_debug_init();
7074 bgp_dump_init();
7075 bgp_route_init();
7076 bgp_route_map_init();
7077 bgp_scan_vty_init();
7078 bgp_mplsvpn_init();
7079 #ifdef ENABLE_BGP_VNC
7080 rfapi_init();
7081 #endif
7082 bgp_ethernetvpn_init();
7083 bgp_flowspec_vty_init();
7084
7085 /* Access list initialize. */
7086 access_list_init();
7087 access_list_add_hook(peer_distribute_update);
7088 access_list_delete_hook(peer_distribute_update);
7089
7090 /* Filter list initialize. */
7091 bgp_filter_init();
7092 as_list_add_hook(peer_aslist_add);
7093 as_list_delete_hook(peer_aslist_del);
7094
7095 /* Prefix list initialize.*/
7096 prefix_list_init();
7097 prefix_list_add_hook(peer_prefix_list_update);
7098 prefix_list_delete_hook(peer_prefix_list_update);
7099
7100 /* Community list initialize. */
7101 bgp_clist = community_list_init();
7102
7103 /* BFD init */
7104 bgp_bfd_init();
7105
7106 cmd_variable_handler_register(bgp_viewvrf_var_handlers);
7107 }
7108
7109 void bgp_terminate(void)
7110 {
7111 struct bgp *bgp;
7112 struct peer *peer;
7113 struct listnode *node, *nnode;
7114 struct listnode *mnode, *mnnode;
7115
7116 QOBJ_UNREG(bm);
7117
7118 /* Close the listener sockets first as this prevents peers from
7119 * attempting
7120 * to reconnect on receiving the peer unconfig message. In the presence
7121 * of a large number of peers this will ensure that no peer is left with
7122 * a dangling connection
7123 */
7124 /* reverse bgp_master_init */
7125 bgp_close();
7126
7127 if (bm->listen_sockets)
7128 list_delete(&bm->listen_sockets);
7129
7130 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
7131 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
7132 if (peer->status == Established
7133 || peer->status == OpenSent
7134 || peer->status == OpenConfirm)
7135 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
7136 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
7137
7138 if (bm->process_main_queue)
7139 work_queue_free_and_null(&bm->process_main_queue);
7140
7141 if (bm->t_rmap_update)
7142 BGP_TIMER_OFF(bm->t_rmap_update);
7143
7144 bgp_mac_finish();
7145 }
7146
7147 struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
7148 const char *ip_str, bool use_json)
7149 {
7150 int ret;
7151 struct peer *peer;
7152 union sockunion su;
7153
7154 /* Get peer sockunion. */
7155 ret = str2sockunion(ip_str, &su);
7156 if (ret < 0) {
7157 peer = peer_lookup_by_conf_if(bgp, ip_str);
7158 if (!peer) {
7159 peer = peer_lookup_by_hostname(bgp, ip_str);
7160
7161 if (!peer) {
7162 if (use_json) {
7163 json_object *json_no = NULL;
7164 json_no = json_object_new_object();
7165 json_object_string_add(
7166 json_no,
7167 "malformedAddressOrName",
7168 ip_str);
7169 vty_out(vty, "%s\n",
7170 json_object_to_json_string_ext(
7171 json_no,
7172 JSON_C_TO_STRING_PRETTY));
7173 json_object_free(json_no);
7174 } else
7175 vty_out(vty,
7176 "%% Malformed address or name: %s\n",
7177 ip_str);
7178 return NULL;
7179 }
7180 }
7181 return peer;
7182 }
7183
7184 /* Peer structure lookup. */
7185 peer = peer_lookup(bgp, &su);
7186 if (!peer) {
7187 if (use_json) {
7188 json_object *json_no = NULL;
7189 json_no = json_object_new_object();
7190 json_object_string_add(json_no, "warning",
7191 "No such neighbor in this view/vrf");
7192 vty_out(vty, "%s\n",
7193 json_object_to_json_string_ext(
7194 json_no, JSON_C_TO_STRING_PRETTY));
7195 json_object_free(json_no);
7196 } else
7197 vty_out(vty, "No such neighbor in this view/vrf\n");
7198 return NULL;
7199 }
7200
7201 return peer;
7202 }
7203
7204 void bgp_gr_apply_running_config(void)
7205 {
7206 struct peer *peer = NULL;
7207 struct bgp *bgp = NULL;
7208 struct listnode *node, *nnode;
7209 bool gr_router_detected = false;
7210
7211 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
7212 zlog_debug("[BGP_GR] %s called !", __func__);
7213
7214 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
7215 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7216 bgp_peer_gr_flags_update(peer);
7217 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART))
7218 gr_router_detected = true;
7219 }
7220
7221 if (gr_router_detected
7222 && bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
7223 bgp_zebra_send_capabilities(bgp, true);
7224 } else if (!gr_router_detected
7225 && bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
7226 bgp_zebra_send_capabilities(bgp, false);
7227 }
7228
7229 gr_router_detected = false;
7230 }
7231 }