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