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