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