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