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