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