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