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