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