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