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