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