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