]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgpd.c
[cleanup] Convert XMALLOC/memset to XCALLOC
[mirror_frr.git] / bgpd / bgpd.c
1 /* BGP-4, BGP-4+ daemon program
2 Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include <zebra.h>
22
23 #include "prefix.h"
24 #include "thread.h"
25 #include "buffer.h"
26 #include "stream.h"
27 #include "command.h"
28 #include "sockunion.h"
29 #include "network.h"
30 #include "memory.h"
31 #include "filter.h"
32 #include "routemap.h"
33 #include "str.h"
34 #include "log.h"
35 #include "plist.h"
36 #include "linklist.h"
37 #include "workqueue.h"
38
39 #include "bgpd/bgpd.h"
40 #include "bgpd/bgp_table.h"
41 #include "bgpd/bgp_aspath.h"
42 #include "bgpd/bgp_route.h"
43 #include "bgpd/bgp_dump.h"
44 #include "bgpd/bgp_debug.h"
45 #include "bgpd/bgp_community.h"
46 #include "bgpd/bgp_attr.h"
47 #include "bgpd/bgp_regex.h"
48 #include "bgpd/bgp_clist.h"
49 #include "bgpd/bgp_fsm.h"
50 #include "bgpd/bgp_packet.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_open.h"
53 #include "bgpd/bgp_filter.h"
54 #include "bgpd/bgp_nexthop.h"
55 #include "bgpd/bgp_damp.h"
56 #include "bgpd/bgp_mplsvpn.h"
57 #include "bgpd/bgp_advertise.h"
58 #include "bgpd/bgp_network.h"
59 #include "bgpd/bgp_vty.h"
60 #ifdef HAVE_SNMP
61 #include "bgpd/bgp_snmp.h"
62 #endif /* HAVE_SNMP */
63 \f
64 /* BGP process wide configuration. */
65 static struct bgp_master bgp_master;
66
67 extern struct in_addr router_id_zebra;
68
69 /* BGP process wide configuration pointer to export. */
70 struct bgp_master *bm;
71
72 /* BGP community-list. */
73 struct community_list_handler *bgp_clist;
74 \f
75 /* BGP global flag manipulation. */
76 int
77 bgp_option_set (int flag)
78 {
79 switch (flag)
80 {
81 case BGP_OPT_NO_FIB:
82 case BGP_OPT_MULTIPLE_INSTANCE:
83 case BGP_OPT_CONFIG_CISCO:
84 SET_FLAG (bm->options, flag);
85 break;
86 default:
87 return BGP_ERR_INVALID_FLAG;
88 }
89 return 0;
90 }
91
92 int
93 bgp_option_unset (int flag)
94 {
95 switch (flag)
96 {
97 case BGP_OPT_MULTIPLE_INSTANCE:
98 if (listcount (bm->bgp) > 1)
99 return BGP_ERR_MULTIPLE_INSTANCE_USED;
100 /* Fall through. */
101 case BGP_OPT_NO_FIB:
102 case BGP_OPT_CONFIG_CISCO:
103 UNSET_FLAG (bm->options, flag);
104 break;
105 default:
106 return BGP_ERR_INVALID_FLAG;
107 }
108 return 0;
109 }
110
111 int
112 bgp_option_check (int flag)
113 {
114 return CHECK_FLAG (bm->options, flag);
115 }
116 \f
117 /* BGP flag manipulation. */
118 int
119 bgp_flag_set (struct bgp *bgp, int flag)
120 {
121 SET_FLAG (bgp->flags, flag);
122 return 0;
123 }
124
125 int
126 bgp_flag_unset (struct bgp *bgp, int flag)
127 {
128 UNSET_FLAG (bgp->flags, flag);
129 return 0;
130 }
131
132 int
133 bgp_flag_check (struct bgp *bgp, int flag)
134 {
135 return CHECK_FLAG (bgp->flags, flag);
136 }
137 \f
138 /* Internal function to set BGP structure configureation flag. */
139 static void
140 bgp_config_set (struct bgp *bgp, int config)
141 {
142 SET_FLAG (bgp->config, config);
143 }
144
145 static void
146 bgp_config_unset (struct bgp *bgp, int config)
147 {
148 UNSET_FLAG (bgp->config, config);
149 }
150
151 static int
152 bgp_config_check (struct bgp *bgp, int config)
153 {
154 return CHECK_FLAG (bgp->config, config);
155 }
156 \f
157 /* Set BGP router identifier. */
158 int
159 bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
160 {
161 struct peer *peer;
162 struct listnode *node, *nnode;
163
164 if (bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID)
165 && IPV4_ADDR_SAME (&bgp->router_id, id))
166 return 0;
167
168 IPV4_ADDR_COPY (&bgp->router_id, id);
169 bgp_config_set (bgp, BGP_CONFIG_ROUTER_ID);
170
171 /* Set all peer's local identifier with this value. */
172 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
173 {
174 IPV4_ADDR_COPY (&peer->local_id, id);
175
176 if (peer->status == Established)
177 {
178 peer->last_reset = PEER_DOWN_RID_CHANGE;
179 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
180 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
181 }
182 }
183 return 0;
184 }
185
186 /* BGP's cluster-id control. */
187 int
188 bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
189 {
190 struct peer *peer;
191 struct listnode *node, *nnode;
192
193 if (bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID)
194 && IPV4_ADDR_SAME (&bgp->cluster_id, cluster_id))
195 return 0;
196
197 IPV4_ADDR_COPY (&bgp->cluster_id, cluster_id);
198 bgp_config_set (bgp, BGP_CONFIG_CLUSTER_ID);
199
200 /* Clear all IBGP peer. */
201 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
202 {
203 if (peer_sort (peer) != BGP_PEER_IBGP)
204 continue;
205
206 if (peer->status == Established)
207 {
208 peer->last_reset = PEER_DOWN_CLID_CHANGE;
209 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
210 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
211 }
212 }
213 return 0;
214 }
215
216 int
217 bgp_cluster_id_unset (struct bgp *bgp)
218 {
219 struct peer *peer;
220 struct listnode *node, *nnode;
221
222 if (! bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID))
223 return 0;
224
225 bgp->cluster_id.s_addr = 0;
226 bgp_config_unset (bgp, BGP_CONFIG_CLUSTER_ID);
227
228 /* Clear all IBGP peer. */
229 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
230 {
231 if (peer_sort (peer) != BGP_PEER_IBGP)
232 continue;
233
234 if (peer->status == Established)
235 {
236 peer->last_reset = PEER_DOWN_CLID_CHANGE;
237 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
238 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
239 }
240 }
241 return 0;
242 }
243 \f
244 /* BGP timer configuration. */
245 int
246 bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime)
247 {
248 bgp->default_keepalive = (keepalive < holdtime / 3
249 ? keepalive : holdtime / 3);
250 bgp->default_holdtime = holdtime;
251
252 return 0;
253 }
254
255 int
256 bgp_timers_unset (struct bgp *bgp)
257 {
258 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
259 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
260
261 return 0;
262 }
263 \f
264 /* BGP confederation configuration. */
265 int
266 bgp_confederation_id_set (struct bgp *bgp, as_t as)
267 {
268 struct peer *peer;
269 struct listnode *node, *nnode;
270 int already_confed;
271
272 if (as == 0)
273 return BGP_ERR_INVALID_AS;
274
275 /* Remember - were we doing confederation before? */
276 already_confed = bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION);
277 bgp->confed_id = as;
278 bgp_config_set (bgp, BGP_CONFIG_CONFEDERATION);
279
280 /* If we were doing confederation already, this is just an external
281 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
282 were not doing confederation before, reset all EBGP sessions. */
283 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
284 {
285 /* We're looking for peers who's AS is not local or part of our
286 confederation. */
287 if (already_confed)
288 {
289 if (peer_sort (peer) == BGP_PEER_EBGP)
290 {
291 peer->local_as = as;
292 if (peer->status == Established)
293 {
294 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
295 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
296 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
297 }
298
299 else
300 BGP_EVENT_ADD (peer, BGP_Stop);
301 }
302 }
303 else
304 {
305 /* Not doign confederation before, so reset every non-local
306 session */
307 if (peer_sort (peer) != BGP_PEER_IBGP)
308 {
309 /* Reset the local_as to be our EBGP one */
310 if (peer_sort (peer) == BGP_PEER_EBGP)
311 peer->local_as = as;
312 if (peer->status == Established)
313 {
314 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
315 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
316 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
317 }
318 else
319 BGP_EVENT_ADD (peer, BGP_Stop);
320 }
321 }
322 }
323 return 0;
324 }
325
326 int
327 bgp_confederation_id_unset (struct bgp *bgp)
328 {
329 struct peer *peer;
330 struct listnode *node, *nnode;
331
332 bgp->confed_id = 0;
333 bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
334
335 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
336 {
337 /* We're looking for peers who's AS is not local */
338 if (peer_sort (peer) != BGP_PEER_IBGP)
339 {
340 peer->local_as = bgp->as;
341 if (peer->status == Established)
342 {
343 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
344 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
345 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
346 }
347
348 else
349 BGP_EVENT_ADD (peer, BGP_Stop);
350 }
351 }
352 return 0;
353 }
354
355 /* Is an AS part of the confed or not? */
356 int
357 bgp_confederation_peers_check (struct bgp *bgp, as_t as)
358 {
359 int i;
360
361 if (! bgp)
362 return 0;
363
364 for (i = 0; i < bgp->confed_peers_cnt; i++)
365 if (bgp->confed_peers[i] == as)
366 return 1;
367
368 return 0;
369 }
370
371 /* Add an AS to the confederation set. */
372 int
373 bgp_confederation_peers_add (struct bgp *bgp, as_t as)
374 {
375 struct peer *peer;
376 struct listnode *node, *nnode;
377
378 if (! bgp)
379 return BGP_ERR_INVALID_BGP;
380
381 if (bgp->as == as)
382 return BGP_ERR_INVALID_AS;
383
384 if (bgp_confederation_peers_check (bgp, as))
385 return -1;
386
387 if (bgp->confed_peers)
388 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
389 bgp->confed_peers,
390 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
391 else
392 bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST,
393 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
394
395 bgp->confed_peers[bgp->confed_peers_cnt] = as;
396 bgp->confed_peers_cnt++;
397
398 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
399 {
400 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
401 {
402 if (peer->as == as)
403 {
404 peer->local_as = bgp->as;
405 if (peer->status == Established)
406 {
407 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
408 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
409 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
410 }
411 else
412 BGP_EVENT_ADD (peer, BGP_Stop);
413 }
414 }
415 }
416 return 0;
417 }
418
419 /* Delete an AS from the confederation set. */
420 int
421 bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
422 {
423 int i;
424 int j;
425 struct peer *peer;
426 struct listnode *node, *nnode;
427
428 if (! bgp)
429 return -1;
430
431 if (! bgp_confederation_peers_check (bgp, as))
432 return -1;
433
434 for (i = 0; i < bgp->confed_peers_cnt; i++)
435 if (bgp->confed_peers[i] == as)
436 for(j = i + 1; j < bgp->confed_peers_cnt; j++)
437 bgp->confed_peers[j - 1] = bgp->confed_peers[j];
438
439 bgp->confed_peers_cnt--;
440
441 if (bgp->confed_peers_cnt == 0)
442 {
443 if (bgp->confed_peers)
444 XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
445 bgp->confed_peers = NULL;
446 }
447 else
448 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
449 bgp->confed_peers,
450 bgp->confed_peers_cnt * sizeof (as_t));
451
452 /* Now reset any peer who's remote AS has just been removed from the
453 CONFED */
454 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
455 {
456 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
457 {
458 if (peer->as == as)
459 {
460 peer->local_as = bgp->confed_id;
461 if (peer->status == Established)
462 {
463 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
464 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
465 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
466 }
467 else
468 BGP_EVENT_ADD (peer, BGP_Stop);
469 }
470 }
471 }
472
473 return 0;
474 }
475 \f
476 /* Local preference configuration. */
477 int
478 bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
479 {
480 if (! bgp)
481 return -1;
482
483 bgp->default_local_pref = local_pref;
484
485 return 0;
486 }
487
488 int
489 bgp_default_local_preference_unset (struct bgp *bgp)
490 {
491 if (! bgp)
492 return -1;
493
494 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
495
496 return 0;
497 }
498 \f
499 /* If peer is RSERVER_CLIENT in at least one address family and is not member
500 of a peer_group for that family, return 1.
501 Used to check wether the peer is included in list bgp->rsclient. */
502 int
503 peer_rsclient_active (struct peer *peer)
504 {
505 int i;
506 int j;
507
508 for (i=AFI_IP; i < AFI_MAX; i++)
509 for (j=SAFI_UNICAST; j < SAFI_MAX; j++)
510 if (CHECK_FLAG(peer->af_flags[i][j], PEER_FLAG_RSERVER_CLIENT)
511 && ! peer->af_group[i][j])
512 return 1;
513 return 0;
514 }
515
516 /* Peer comparison function for sorting. */
517 static int
518 peer_cmp (struct peer *p1, struct peer *p2)
519 {
520 return sockunion_cmp (&p1->su, &p2->su);
521 }
522
523 int
524 peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
525 {
526 return CHECK_FLAG (peer->af_flags[afi][safi], flag);
527 }
528
529 /* Reset all address family specific configuration. */
530 static void
531 peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
532 {
533 int i;
534 struct bgp_filter *filter;
535 char orf_name[BUFSIZ];
536
537 filter = &peer->filter[afi][safi];
538
539 /* Clear neighbor filter and route-map */
540 for (i = FILTER_IN; i < FILTER_MAX; i++)
541 {
542 if (filter->dlist[i].name)
543 {
544 free (filter->dlist[i].name);
545 filter->dlist[i].name = NULL;
546 }
547 if (filter->plist[i].name)
548 {
549 free (filter->plist[i].name);
550 filter->plist[i].name = NULL;
551 }
552 if (filter->aslist[i].name)
553 {
554 free (filter->aslist[i].name);
555 filter->aslist[i].name = NULL;
556 }
557 }
558 for (i = RMAP_IN; i < RMAP_MAX; i++)
559 {
560 if (filter->map[i].name)
561 {
562 free (filter->map[i].name);
563 filter->map[i].name = NULL;
564 }
565 }
566
567 /* Clear unsuppress map. */
568 if (filter->usmap.name)
569 free (filter->usmap.name);
570 filter->usmap.name = NULL;
571 filter->usmap.map = NULL;
572
573 /* Clear neighbor's all address family flags. */
574 peer->af_flags[afi][safi] = 0;
575
576 /* Clear neighbor's all address family sflags. */
577 peer->af_sflags[afi][safi] = 0;
578
579 /* Clear neighbor's all address family capabilities. */
580 peer->af_cap[afi][safi] = 0;
581
582 /* Clear ORF info */
583 peer->orf_plist[afi][safi] = NULL;
584 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
585 prefix_bgp_orf_remove_all (orf_name);
586
587 /* Set default neighbor send-community. */
588 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
589 {
590 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
591 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
592 }
593
594 /* Clear neighbor default_originate_rmap */
595 if (peer->default_rmap[afi][safi].name)
596 free (peer->default_rmap[afi][safi].name);
597 peer->default_rmap[afi][safi].name = NULL;
598 peer->default_rmap[afi][safi].map = NULL;
599
600 /* Clear neighbor maximum-prefix */
601 peer->pmax[afi][safi] = 0;
602 peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
603 }
604
605 /* peer global config reset */
606 static void
607 peer_global_config_reset (struct peer *peer)
608 {
609 peer->weight = 0;
610 peer->change_local_as = 0;
611 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
612 if (peer->update_source)
613 {
614 sockunion_free (peer->update_source);
615 peer->update_source = NULL;
616 }
617 if (peer->update_if)
618 {
619 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
620 peer->update_if = NULL;
621 }
622
623 if (peer_sort (peer) == BGP_PEER_IBGP)
624 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
625 else
626 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
627
628 peer->flags = 0;
629 peer->config = 0;
630 peer->holdtime = 0;
631 peer->keepalive = 0;
632 peer->connect = 0;
633 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
634 }
635
636 /* Check peer's AS number and determin is this peer IBGP or EBGP */
637 int
638 peer_sort (struct peer *peer)
639 {
640 struct bgp *bgp;
641
642 bgp = peer->bgp;
643
644 /* Peer-group */
645 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
646 {
647 if (peer->as)
648 return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP);
649 else
650 {
651 struct peer *peer1;
652 peer1 = listnode_head (peer->group->peer);
653 if (peer1)
654 return (peer1->local_as == peer1->as
655 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
656 }
657 return BGP_PEER_INTERNAL;
658 }
659
660 /* Normal peer */
661 if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
662 {
663 if (peer->local_as == 0)
664 return BGP_PEER_INTERNAL;
665
666 if (peer->local_as == peer->as)
667 {
668 if (peer->local_as == bgp->confed_id)
669 return BGP_PEER_EBGP;
670 else
671 return BGP_PEER_IBGP;
672 }
673
674 if (bgp_confederation_peers_check (bgp, peer->as))
675 return BGP_PEER_CONFED;
676
677 return BGP_PEER_EBGP;
678 }
679 else
680 {
681 return (peer->local_as == 0
682 ? BGP_PEER_INTERNAL : peer->local_as == peer->as
683 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
684 }
685 }
686
687 static inline void
688 peer_free (struct peer *peer)
689 {
690 assert (peer->status == Deleted);
691
692 /* this /ought/ to have been done already through bgp_stop earlier,
693 * but just to be sure..
694 */
695 bgp_timer_set (peer);
696 BGP_READ_OFF (peer->t_read);
697 BGP_WRITE_OFF (peer->t_write);
698 BGP_EVENT_FLUSH (peer);
699
700 if (peer->desc)
701 XFREE (MTYPE_PEER_DESC, peer->desc);
702
703 /* Free allocated host character. */
704 if (peer->host)
705 XFREE (MTYPE_BGP_PEER_HOST, peer->host);
706
707 /* Update source configuration. */
708 if (peer->update_source)
709 sockunion_free (peer->update_source);
710
711 if (peer->update_if)
712 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
713
714 if (peer->clear_node_queue)
715 work_queue_free (peer->clear_node_queue);
716
717 bgp_sync_delete (peer);
718 memset (peer, 0, sizeof (struct peer));
719
720 XFREE (MTYPE_BGP_PEER, peer);
721 }
722
723 /* increase reference count on a struct peer */
724 struct peer *
725 peer_lock (struct peer *peer)
726 {
727 assert (peer && (peer->lock >= 0));
728 assert (peer->status != Deleted);
729
730 peer->lock++;
731
732 return peer;
733 }
734
735 /* decrease reference count on a struct peer
736 * struct peer is freed and NULL returned if last reference
737 */
738 struct peer *
739 peer_unlock (struct peer *peer)
740 {
741 assert (peer && (peer->lock > 0));
742
743 peer->lock--;
744
745 if (peer->lock == 0)
746 {
747 #if 0
748 zlog_debug ("unlocked and freeing");
749 zlog_backtrace (LOG_DEBUG);
750 #endif
751 peer_free (peer);
752 return NULL;
753 }
754
755 #if 0
756 if (peer->lock == 1)
757 {
758 zlog_debug ("unlocked to 1");
759 zlog_backtrace (LOG_DEBUG);
760 }
761 #endif
762
763 return peer;
764 }
765
766 /* Allocate new peer object, implicitely locked. */
767 static struct peer *
768 peer_new (struct bgp *bgp)
769 {
770 afi_t afi;
771 safi_t safi;
772 struct peer *peer;
773 struct servent *sp;
774
775 /* bgp argument is absolutely required */
776 assert (bgp);
777 if (!bgp)
778 return NULL;
779
780 /* Allocate new peer. */
781 peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
782
783 /* Set default value. */
784 peer->fd = -1;
785 peer->v_start = BGP_INIT_START_TIMER;
786 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
787 peer->v_asorig = BGP_DEFAULT_ASORIGINATE;
788 peer->status = Idle;
789 peer->ostatus = Idle;
790 peer->weight = 0;
791 peer->password = NULL;
792 peer->bgp = bgp;
793 peer = peer_lock (peer); /* initial reference */
794
795 /* Set default flags. */
796 for (afi = AFI_IP; afi < AFI_MAX; afi++)
797 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
798 {
799 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
800 {
801 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
802 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
803 }
804 peer->orf_plist[afi][safi] = NULL;
805 }
806 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
807
808 /* Create buffers. */
809 peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);
810 peer->obuf = stream_fifo_new ();
811 peer->work = stream_new (BGP_MAX_PACKET_SIZE);
812
813 bgp_sync_init (peer);
814
815 /* Get service port number. */
816 sp = getservbyname ("bgp", "tcp");
817 peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
818
819 return peer;
820 }
821
822 /* Create new BGP peer. */
823 static struct peer *
824 peer_create (union sockunion *su, struct bgp *bgp, as_t local_as,
825 as_t remote_as, afi_t afi, safi_t safi)
826 {
827 int active;
828 struct peer *peer;
829 char buf[SU_ADDRSTRLEN];
830
831 peer = peer_new (bgp);
832 peer->su = *su;
833 peer->local_as = local_as;
834 peer->as = remote_as;
835 peer->local_id = bgp->router_id;
836 peer->v_holdtime = bgp->default_holdtime;
837 peer->v_keepalive = bgp->default_keepalive;
838 if (peer_sort (peer) == BGP_PEER_IBGP)
839 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
840 else
841 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
842
843 peer = peer_lock (peer); /* bgp peer list reference */
844 listnode_add_sort (bgp->peer, peer);
845
846 active = peer_active (peer);
847
848 if (afi && safi)
849 peer->afc[afi][safi] = 1;
850
851 /* Last read time set */
852 peer->readtime = time (NULL);
853
854 /* Last reset time set */
855 peer->resettime = time (NULL);
856
857 /* Default TTL set. */
858 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
859
860 /* Make peer's address string. */
861 sockunion2str (su, buf, SU_ADDRSTRLEN);
862 peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
863
864 /* Set up peer's events and timers. */
865 if (! active && peer_active (peer))
866 bgp_timer_set (peer);
867
868 return peer;
869 }
870
871 /* Make accept BGP peer. Called from bgp_accept (). */
872 struct peer *
873 peer_create_accept (struct bgp *bgp)
874 {
875 struct peer *peer;
876
877 peer = peer_new (bgp);
878
879 peer = peer_lock (peer); /* bgp peer list reference */
880 listnode_add_sort (bgp->peer, peer);
881
882 return peer;
883 }
884
885 /* Change peer's AS number. */
886 static void
887 peer_as_change (struct peer *peer, as_t as)
888 {
889 int type;
890
891 /* Stop peer. */
892 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
893 {
894 if (peer->status == Established)
895 {
896 peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
897 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
898 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
899 }
900 else
901 BGP_EVENT_ADD (peer, BGP_Stop);
902 }
903 type = peer_sort (peer);
904 peer->as = as;
905
906 if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION)
907 && ! bgp_confederation_peers_check (peer->bgp, as)
908 && peer->bgp->as != as)
909 peer->local_as = peer->bgp->confed_id;
910 else
911 peer->local_as = peer->bgp->as;
912
913 /* Advertisement-interval reset */
914 if (peer_sort (peer) == BGP_PEER_IBGP)
915 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
916 else
917 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
918
919 /* TTL reset */
920 if (peer_sort (peer) == BGP_PEER_IBGP)
921 peer->ttl = 255;
922 else if (type == BGP_PEER_IBGP)
923 peer->ttl = 1;
924
925 /* reflector-client reset */
926 if (peer_sort (peer) != BGP_PEER_IBGP)
927 {
928 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
929 PEER_FLAG_REFLECTOR_CLIENT);
930 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
931 PEER_FLAG_REFLECTOR_CLIENT);
932 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
933 PEER_FLAG_REFLECTOR_CLIENT);
934 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
935 PEER_FLAG_REFLECTOR_CLIENT);
936 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
937 PEER_FLAG_REFLECTOR_CLIENT);
938 }
939
940 /* local-as reset */
941 if (peer_sort (peer) != BGP_PEER_EBGP)
942 {
943 peer->change_local_as = 0;
944 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
945 }
946 }
947
948 /* If peer does not exist, create new one. If peer already exists,
949 set AS number to the peer. */
950 int
951 peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as,
952 afi_t afi, safi_t safi)
953 {
954 struct peer *peer;
955 as_t local_as;
956
957 peer = peer_lookup (bgp, su);
958
959 if (peer)
960 {
961 /* When this peer is a member of peer-group. */
962 if (peer->group)
963 {
964 if (peer->group->conf->as)
965 {
966 /* Return peer group's AS number. */
967 *as = peer->group->conf->as;
968 return BGP_ERR_PEER_GROUP_MEMBER;
969 }
970 if (peer_sort (peer->group->conf) == BGP_PEER_IBGP)
971 {
972 if (bgp->as != *as)
973 {
974 *as = peer->as;
975 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
976 }
977 }
978 else
979 {
980 if (bgp->as == *as)
981 {
982 *as = peer->as;
983 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
984 }
985 }
986 }
987
988 /* Existing peer's AS number change. */
989 if (peer->as != *as)
990 peer_as_change (peer, *as);
991 }
992 else
993 {
994
995 /* If the peer is not part of our confederation, and its not an
996 iBGP peer then spoof the source AS */
997 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION)
998 && ! bgp_confederation_peers_check (bgp, *as)
999 && bgp->as != *as)
1000 local_as = bgp->confed_id;
1001 else
1002 local_as = bgp->as;
1003
1004 /* If this is IPv4 unicast configuration and "no bgp default
1005 ipv4-unicast" is specified. */
1006
1007 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
1008 && afi == AFI_IP && safi == SAFI_UNICAST)
1009 peer = peer_create (su, bgp, local_as, *as, 0, 0);
1010 else
1011 peer = peer_create (su, bgp, local_as, *as, afi, safi);
1012 }
1013
1014 return 0;
1015 }
1016
1017 /* Activate the peer or peer group for specified AFI and SAFI. */
1018 int
1019 peer_activate (struct peer *peer, afi_t afi, safi_t safi)
1020 {
1021 int active;
1022
1023 if (peer->afc[afi][safi])
1024 return 0;
1025
1026 /* Activate the address family configuration. */
1027 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1028 peer->afc[afi][safi] = 1;
1029 else
1030 {
1031 active = peer_active (peer);
1032
1033 peer->afc[afi][safi] = 1;
1034
1035 if (! active && peer_active (peer))
1036 bgp_timer_set (peer);
1037 else
1038 {
1039 if (peer->status == Established)
1040 {
1041 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1042 {
1043 peer->afc_adv[afi][safi] = 1;
1044 bgp_capability_send (peer, afi, safi,
1045 CAPABILITY_CODE_MP,
1046 CAPABILITY_ACTION_SET);
1047 if (peer->afc_recv[afi][safi])
1048 {
1049 peer->afc_nego[afi][safi] = 1;
1050 bgp_announce_route (peer, afi, safi);
1051 }
1052 }
1053 else
1054 {
1055 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
1056 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1057 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1058 }
1059 }
1060 }
1061 }
1062 return 0;
1063 }
1064
1065 int
1066 peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
1067 {
1068 struct peer_group *group;
1069 struct peer *peer1;
1070 struct listnode *node, *nnode;
1071
1072 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1073 {
1074 group = peer->group;
1075
1076 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
1077 {
1078 if (peer1->af_group[afi][safi])
1079 return BGP_ERR_PEER_GROUP_MEMBER_EXISTS;
1080 }
1081 }
1082 else
1083 {
1084 if (peer->af_group[afi][safi])
1085 return BGP_ERR_PEER_BELONGS_TO_GROUP;
1086 }
1087
1088 if (! peer->afc[afi][safi])
1089 return 0;
1090
1091 /* De-activate the address family configuration. */
1092 peer->afc[afi][safi] = 0;
1093 peer_af_flag_reset (peer, afi, safi);
1094
1095 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1096 {
1097 if (peer->status == Established)
1098 {
1099 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1100 {
1101 peer->afc_adv[afi][safi] = 0;
1102 peer->afc_nego[afi][safi] = 0;
1103
1104 if (peer_active_nego (peer))
1105 {
1106 bgp_capability_send (peer, afi, safi,
1107 CAPABILITY_CODE_MP,
1108 CAPABILITY_ACTION_UNSET);
1109 bgp_clear_route (peer, afi, safi);
1110 peer->pcount[afi][safi] = 0;
1111 }
1112 else
1113 {
1114 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1115 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1116 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1117 }
1118 }
1119 else
1120 {
1121 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1122 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1123 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1124 }
1125 }
1126 }
1127 return 0;
1128 }
1129
1130 void
1131 peer_nsf_stop (struct peer *peer)
1132 {
1133 afi_t afi;
1134 safi_t safi;
1135
1136 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1137 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1138
1139 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1140 for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
1141 peer->nsf[afi][safi] = 0;
1142
1143 if (peer->t_gr_restart)
1144 {
1145 BGP_TIMER_OFF (peer->t_gr_restart);
1146 if (BGP_DEBUG (events, EVENTS))
1147 zlog_debug ("%s graceful restart timer stopped", peer->host);
1148 }
1149 if (peer->t_gr_stale)
1150 {
1151 BGP_TIMER_OFF (peer->t_gr_stale);
1152 if (BGP_DEBUG (events, EVENTS))
1153 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1154 }
1155 bgp_clear_route_all (peer);
1156 }
1157
1158 /* Delete peer from confguration.
1159 *
1160 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
1161 * it to "cool off" and refcounts to hit 0, at which state it is freed.
1162 *
1163 * This function /should/ take care to be idempotent, to guard against
1164 * it being called multiple times through stray events that come in
1165 * that happen to result in this function being called again. That
1166 * said, getting here for a "Deleted" peer is a bug in the neighbour
1167 * FSM.
1168 */
1169 int
1170 peer_delete (struct peer *peer)
1171 {
1172 int i;
1173 afi_t afi;
1174 safi_t safi;
1175 struct bgp *bgp;
1176 struct bgp_filter *filter;
1177
1178 assert (peer->status != Deleted);
1179
1180 bgp = peer->bgp;
1181
1182 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
1183 peer_nsf_stop (peer);
1184
1185 /* If this peer belongs to peer group. Clearn up the
1186 relationship. */
1187 if (peer->group)
1188 {
1189 struct listnode *pn;
1190
1191 if ((pn = listnode_lookup (peer->group->peer, peer)))
1192 {
1193 peer = peer_unlock (peer); /* group->peer list reference */
1194 list_delete_node (peer->group->peer, pn);
1195 }
1196 peer->group = NULL;
1197 }
1198
1199 /* Withdraw all information from routing table. We can not use
1200 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
1201 * executed after peer structure is deleted.
1202 */
1203 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1204 bgp_stop (peer);
1205 bgp_fsm_change_status (peer, Deleted);
1206
1207 /* Password configuration */
1208 if (peer->password)
1209 {
1210 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1211 peer->password = NULL;
1212
1213 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1214 bgp_md5_set (peer);
1215 }
1216
1217 bgp_timer_set (peer); /* stops all timers for Deleted */
1218
1219 /* Delete from all peer list. */
1220 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1221 {
1222 struct listnode *pn;
1223
1224 if ((pn = listnode_lookup (bgp->peer, peer)))
1225 {
1226 peer_unlock (peer); /* bgp peer list reference */
1227 list_delete_node (bgp->peer, pn);
1228 }
1229
1230 if (peer_rsclient_active (peer)
1231 && (pn = listnode_lookup (bgp->rsclient, peer)))
1232 {
1233 peer_unlock (peer); /* rsclient list reference */
1234 list_delete_node (bgp->rsclient, pn);
1235 }
1236 }
1237
1238 /* Free RIB for any family in which peer is RSERVER_CLIENT, and is not
1239 member of a peer_group. */
1240 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1241 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1242 if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
1243 bgp_table_finish (&peer->rib[afi][safi]);
1244
1245 /* Buffers. */
1246 if (peer->ibuf)
1247 stream_free (peer->ibuf);
1248 if (peer->obuf)
1249 stream_fifo_free (peer->obuf);
1250 if (peer->work)
1251 stream_free (peer->work);
1252 peer->obuf = NULL;
1253 peer->work = peer->ibuf = NULL;
1254
1255 /* Local and remote addresses. */
1256 if (peer->su_local)
1257 sockunion_free (peer->su_local);
1258 if (peer->su_remote)
1259 sockunion_free (peer->su_remote);
1260 peer->su_local = peer->su_remote = NULL;
1261
1262 /* Free filter related memory. */
1263 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1264 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1265 {
1266 filter = &peer->filter[afi][safi];
1267
1268 for (i = FILTER_IN; i < FILTER_MAX; i++)
1269 {
1270 if (filter->dlist[i].name)
1271 free (filter->dlist[i].name);
1272 if (filter->plist[i].name)
1273 free (filter->plist[i].name);
1274 if (filter->aslist[i].name)
1275 free (filter->aslist[i].name);
1276
1277 filter->dlist[i].name = NULL;
1278 filter->plist[i].name = NULL;
1279 filter->aslist[i].name = NULL;
1280 }
1281 for (i = RMAP_IN; i < RMAP_MAX; i++)
1282 {
1283 if (filter->map[i].name)
1284 free (filter->map[i].name);
1285 filter->map[i].name = NULL;
1286 }
1287
1288 if (filter->usmap.name)
1289 free (filter->usmap.name);
1290
1291 if (peer->default_rmap[afi][safi].name)
1292 free (peer->default_rmap[afi][safi].name);
1293
1294 filter->usmap.name = NULL;
1295 peer->default_rmap[afi][safi].name = NULL;
1296 }
1297
1298 peer_unlock (peer); /* initial reference */
1299
1300 return 0;
1301 }
1302 \f
1303 static int
1304 peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
1305 {
1306 return strcmp (g1->name, g2->name);
1307 }
1308
1309 /* If peer is configured at least one address family return 1. */
1310 static int
1311 peer_group_active (struct peer *peer)
1312 {
1313 if (peer->af_group[AFI_IP][SAFI_UNICAST]
1314 || peer->af_group[AFI_IP][SAFI_MULTICAST]
1315 || peer->af_group[AFI_IP][SAFI_MPLS_VPN]
1316 || peer->af_group[AFI_IP6][SAFI_UNICAST]
1317 || peer->af_group[AFI_IP6][SAFI_MULTICAST])
1318 return 1;
1319 return 0;
1320 }
1321
1322 /* Peer group cofiguration. */
1323 static struct peer_group *
1324 peer_group_new ()
1325 {
1326 return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
1327 sizeof (struct peer_group));
1328 }
1329
1330 static void
1331 peer_group_free (struct peer_group *group)
1332 {
1333 XFREE (MTYPE_PEER_GROUP, group);
1334 }
1335
1336 struct peer_group *
1337 peer_group_lookup (struct bgp *bgp, const char *name)
1338 {
1339 struct peer_group *group;
1340 struct listnode *node, *nnode;
1341
1342 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
1343 {
1344 if (strcmp (group->name, name) == 0)
1345 return group;
1346 }
1347 return NULL;
1348 }
1349
1350 struct peer_group *
1351 peer_group_get (struct bgp *bgp, const char *name)
1352 {
1353 struct peer_group *group;
1354
1355 group = peer_group_lookup (bgp, name);
1356 if (group)
1357 return group;
1358
1359 group = peer_group_new ();
1360 group->bgp = bgp;
1361 group->name = strdup (name);
1362 group->peer = list_new ();
1363 group->conf = peer_new (bgp);
1364 if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
1365 group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
1366 group->conf->host = strdup (name);
1367 group->conf->group = group;
1368 group->conf->as = 0;
1369 group->conf->ttl = 1;
1370 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1371 UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
1372 UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
1373 group->conf->keepalive = 0;
1374 group->conf->holdtime = 0;
1375 group->conf->connect = 0;
1376 SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP);
1377 listnode_add_sort (bgp->group, group);
1378
1379 return 0;
1380 }
1381
1382 static void
1383 peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
1384 afi_t afi, safi_t safi)
1385 {
1386 int in = FILTER_IN;
1387 int out = FILTER_OUT;
1388 struct peer *conf;
1389 struct bgp_filter *pfilter;
1390 struct bgp_filter *gfilter;
1391
1392 conf = group->conf;
1393 pfilter = &peer->filter[afi][safi];
1394 gfilter = &conf->filter[afi][safi];
1395
1396 /* remote-as */
1397 if (conf->as)
1398 peer->as = conf->as;
1399
1400 /* remote-as */
1401 if (conf->change_local_as)
1402 peer->change_local_as = conf->change_local_as;
1403
1404 /* TTL */
1405 peer->ttl = conf->ttl;
1406
1407 /* Weight */
1408 peer->weight = conf->weight;
1409
1410 /* peer flags apply */
1411 peer->flags = conf->flags;
1412 /* peer af_flags apply */
1413 peer->af_flags[afi][safi] = conf->af_flags[afi][safi];
1414 /* peer config apply */
1415 peer->config = conf->config;
1416
1417 /* peer timers apply */
1418 peer->holdtime = conf->holdtime;
1419 peer->keepalive = conf->keepalive;
1420 peer->connect = conf->connect;
1421 if (CHECK_FLAG (conf->config, PEER_CONFIG_CONNECT))
1422 peer->v_connect = conf->connect;
1423 else
1424 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
1425
1426 /* advertisement-interval reset */
1427 if (peer_sort (peer) == BGP_PEER_IBGP)
1428 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
1429 else
1430 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1431
1432 /* password apply */
1433 if (peer->password)
1434 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1435
1436 if (conf->password)
1437 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
1438 else
1439 peer->password = NULL;
1440
1441 bgp_md5_set (peer);
1442
1443 /* maximum-prefix */
1444 peer->pmax[afi][safi] = conf->pmax[afi][safi];
1445 peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
1446 peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
1447
1448 /* allowas-in */
1449 peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
1450
1451 /* route-server-client */
1452 if (CHECK_FLAG(conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1453 {
1454 /* Make peer's RIB point to group's RIB. */
1455 peer->rib[afi][safi] = group->conf->rib[afi][safi];
1456
1457 /* Import policy. */
1458 if (pfilter->map[RMAP_IMPORT].name)
1459 free (pfilter->map[RMAP_IMPORT].name);
1460 if (gfilter->map[RMAP_IMPORT].name)
1461 {
1462 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1463 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1464 }
1465 else
1466 {
1467 pfilter->map[RMAP_IMPORT].name = NULL;
1468 pfilter->map[RMAP_IMPORT].map = NULL;
1469 }
1470
1471 /* Export policy. */
1472 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1473 {
1474 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1475 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1476 }
1477 }
1478
1479 /* default-originate route-map */
1480 if (conf->default_rmap[afi][safi].name)
1481 {
1482 if (peer->default_rmap[afi][safi].name)
1483 free (peer->default_rmap[afi][safi].name);
1484 peer->default_rmap[afi][safi].name = strdup (conf->default_rmap[afi][safi].name);
1485 peer->default_rmap[afi][safi].map = conf->default_rmap[afi][safi].map;
1486 }
1487
1488 /* update-source apply */
1489 if (conf->update_source)
1490 {
1491 if (peer->update_source)
1492 sockunion_free (peer->update_source);
1493 if (peer->update_if)
1494 {
1495 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1496 peer->update_if = NULL;
1497 }
1498 peer->update_source = sockunion_dup (conf->update_source);
1499 }
1500 else if (conf->update_if)
1501 {
1502 if (peer->update_if)
1503 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1504 if (peer->update_source)
1505 {
1506 sockunion_free (peer->update_source);
1507 peer->update_source = NULL;
1508 }
1509 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, conf->update_if);
1510 }
1511
1512 /* inbound filter apply */
1513 if (gfilter->dlist[in].name && ! pfilter->dlist[in].name)
1514 {
1515 if (pfilter->dlist[in].name)
1516 free (pfilter->dlist[in].name);
1517 pfilter->dlist[in].name = strdup (gfilter->dlist[in].name);
1518 pfilter->dlist[in].alist = gfilter->dlist[in].alist;
1519 }
1520 if (gfilter->plist[in].name && ! pfilter->plist[in].name)
1521 {
1522 if (pfilter->plist[in].name)
1523 free (pfilter->plist[in].name);
1524 pfilter->plist[in].name = strdup (gfilter->plist[in].name);
1525 pfilter->plist[in].plist = gfilter->plist[in].plist;
1526 }
1527 if (gfilter->aslist[in].name && ! pfilter->aslist[in].name)
1528 {
1529 if (pfilter->aslist[in].name)
1530 free (pfilter->aslist[in].name);
1531 pfilter->aslist[in].name = strdup (gfilter->aslist[in].name);
1532 pfilter->aslist[in].aslist = gfilter->aslist[in].aslist;
1533 }
1534 if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
1535 {
1536 if (pfilter->map[RMAP_IN].name)
1537 free (pfilter->map[RMAP_IN].name);
1538 pfilter->map[RMAP_IN].name = strdup (gfilter->map[RMAP_IN].name);
1539 pfilter->map[RMAP_IN].map = gfilter->map[RMAP_IN].map;
1540 }
1541
1542 /* outbound filter apply */
1543 if (gfilter->dlist[out].name)
1544 {
1545 if (pfilter->dlist[out].name)
1546 free (pfilter->dlist[out].name);
1547 pfilter->dlist[out].name = strdup (gfilter->dlist[out].name);
1548 pfilter->dlist[out].alist = gfilter->dlist[out].alist;
1549 }
1550 else
1551 {
1552 if (pfilter->dlist[out].name)
1553 free (pfilter->dlist[out].name);
1554 pfilter->dlist[out].name = NULL;
1555 pfilter->dlist[out].alist = NULL;
1556 }
1557 if (gfilter->plist[out].name)
1558 {
1559 if (pfilter->plist[out].name)
1560 free (pfilter->plist[out].name);
1561 pfilter->plist[out].name = strdup (gfilter->plist[out].name);
1562 pfilter->plist[out].plist = gfilter->plist[out].plist;
1563 }
1564 else
1565 {
1566 if (pfilter->plist[out].name)
1567 free (pfilter->plist[out].name);
1568 pfilter->plist[out].name = NULL;
1569 pfilter->plist[out].plist = NULL;
1570 }
1571 if (gfilter->aslist[out].name)
1572 {
1573 if (pfilter->aslist[out].name)
1574 free (pfilter->aslist[out].name);
1575 pfilter->aslist[out].name = strdup (gfilter->aslist[out].name);
1576 pfilter->aslist[out].aslist = gfilter->aslist[out].aslist;
1577 }
1578 else
1579 {
1580 if (pfilter->aslist[out].name)
1581 free (pfilter->aslist[out].name);
1582 pfilter->aslist[out].name = NULL;
1583 pfilter->aslist[out].aslist = NULL;
1584 }
1585 if (gfilter->map[RMAP_OUT].name)
1586 {
1587 if (pfilter->map[RMAP_OUT].name)
1588 free (pfilter->map[RMAP_OUT].name);
1589 pfilter->map[RMAP_OUT].name = strdup (gfilter->map[RMAP_OUT].name);
1590 pfilter->map[RMAP_OUT].map = gfilter->map[RMAP_OUT].map;
1591 }
1592 else
1593 {
1594 if (pfilter->map[RMAP_OUT].name)
1595 free (pfilter->map[RMAP_OUT].name);
1596 pfilter->map[RMAP_OUT].name = NULL;
1597 pfilter->map[RMAP_OUT].map = NULL;
1598 }
1599
1600 /* RS-client's import/export route-maps. */
1601 if (gfilter->map[RMAP_IMPORT].name)
1602 {
1603 if (pfilter->map[RMAP_IMPORT].name)
1604 free (pfilter->map[RMAP_IMPORT].name);
1605 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1606 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1607 }
1608 else
1609 {
1610 if (pfilter->map[RMAP_IMPORT].name)
1611 free (pfilter->map[RMAP_IMPORT].name);
1612 pfilter->map[RMAP_IMPORT].name = NULL;
1613 pfilter->map[RMAP_IMPORT].map = NULL;
1614 }
1615 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1616 {
1617 if (pfilter->map[RMAP_EXPORT].name)
1618 free (pfilter->map[RMAP_EXPORT].name);
1619 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1620 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1621 }
1622
1623 if (gfilter->usmap.name)
1624 {
1625 if (pfilter->usmap.name)
1626 free (pfilter->usmap.name);
1627 pfilter->usmap.name = strdup (gfilter->usmap.name);
1628 pfilter->usmap.map = gfilter->usmap.map;
1629 }
1630 else
1631 {
1632 if (pfilter->usmap.name)
1633 free (pfilter->usmap.name);
1634 pfilter->usmap.name = NULL;
1635 pfilter->usmap.map = NULL;
1636 }
1637 }
1638
1639 /* Peer group's remote AS configuration. */
1640 int
1641 peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
1642 {
1643 struct peer_group *group;
1644 struct peer *peer;
1645 struct listnode *node, *nnode;
1646
1647 group = peer_group_lookup (bgp, group_name);
1648 if (! group)
1649 return -1;
1650
1651 if (group->conf->as == *as)
1652 return 0;
1653
1654 /* When we setup peer-group AS number all peer group member's AS
1655 number must be updated to same number. */
1656 peer_as_change (group->conf, *as);
1657
1658 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1659 {
1660 if (peer->as != *as)
1661 peer_as_change (peer, *as);
1662 }
1663
1664 return 0;
1665 }
1666
1667 int
1668 peer_group_delete (struct peer_group *group)
1669 {
1670 struct bgp *bgp;
1671 struct peer *peer;
1672 struct listnode *node, *nnode;
1673
1674 bgp = group->bgp;
1675
1676 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1677 {
1678 peer->group = NULL;
1679 peer_delete (peer);
1680 }
1681 list_delete (group->peer);
1682
1683 free (group->name);
1684 group->name = NULL;
1685
1686 group->conf->group = NULL;
1687 peer_delete (group->conf);
1688
1689 /* Delete from all peer_group list. */
1690 listnode_delete (bgp->group, group);
1691
1692 peer_group_free (group);
1693
1694 return 0;
1695 }
1696
1697 int
1698 peer_group_remote_as_delete (struct peer_group *group)
1699 {
1700 struct peer *peer;
1701 struct listnode *node, *nnode;
1702
1703 if (! group->conf->as)
1704 return 0;
1705
1706 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1707 {
1708 peer->group = NULL;
1709 peer_delete (peer);
1710 }
1711 list_delete_all_node (group->peer);
1712
1713 group->conf->as = 0;
1714
1715 return 0;
1716 }
1717
1718 /* Bind specified peer to peer group. */
1719 int
1720 peer_group_bind (struct bgp *bgp, union sockunion *su,
1721 struct peer_group *group, afi_t afi, safi_t safi, as_t *as)
1722 {
1723 struct peer *peer;
1724 int first_member = 0;
1725
1726 /* Check peer group's address family. */
1727 if (! group->conf->afc[afi][safi])
1728 return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED;
1729
1730 /* Lookup the peer. */
1731 peer = peer_lookup (bgp, su);
1732
1733 /* Create a new peer. */
1734 if (! peer)
1735 {
1736 if (! group->conf->as)
1737 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
1738
1739 peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi);
1740 peer->group = group;
1741 peer->af_group[afi][safi] = 1;
1742
1743 peer = peer_lock (peer); /* group->peer list reference */
1744 listnode_add (group->peer, peer);
1745 peer_group2peer_config_copy (group, peer, afi, safi);
1746
1747 return 0;
1748 }
1749
1750 /* When the peer already belongs to peer group, check the consistency. */
1751 if (peer->af_group[afi][safi])
1752 {
1753 if (strcmp (peer->group->name, group->name) != 0)
1754 return BGP_ERR_PEER_GROUP_CANT_CHANGE;
1755
1756 return 0;
1757 }
1758
1759 /* Check current peer group configuration. */
1760 if (peer_group_active (peer)
1761 && strcmp (peer->group->name, group->name) != 0)
1762 return BGP_ERR_PEER_GROUP_MISMATCH;
1763
1764 if (! group->conf->as)
1765 {
1766 if (peer_sort (group->conf) != BGP_PEER_INTERNAL
1767 && peer_sort (group->conf) != peer_sort (peer))
1768 {
1769 if (as)
1770 *as = peer->as;
1771 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
1772 }
1773
1774 if (peer_sort (group->conf) == BGP_PEER_INTERNAL)
1775 first_member = 1;
1776 }
1777
1778 peer->af_group[afi][safi] = 1;
1779 peer->afc[afi][safi] = 1;
1780 if (! peer->group)
1781 {
1782 peer->group = group;
1783
1784 peer = peer_lock (peer); /* group->peer list reference */
1785 listnode_add (group->peer, peer);
1786 }
1787 else
1788 assert (group && peer->group == group);
1789
1790 if (first_member)
1791 {
1792 /* Advertisement-interval reset */
1793 if (peer_sort (group->conf) == BGP_PEER_IBGP)
1794 group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
1795 else
1796 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1797
1798 /* ebgp-multihop reset */
1799 if (peer_sort (group->conf) == BGP_PEER_IBGP)
1800 group->conf->ttl = 255;
1801
1802 /* local-as reset */
1803 if (peer_sort (group->conf) != BGP_PEER_EBGP)
1804 {
1805 group->conf->change_local_as = 0;
1806 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
1807 }
1808 }
1809
1810 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1811 {
1812 struct listnode *pn;
1813
1814 /* If it's not configured as RSERVER_CLIENT in any other address
1815 family, without being member of a peer_group, remove it from
1816 list bgp->rsclient.*/
1817 if (! peer_rsclient_active (peer)
1818 && (pn = listnode_lookup (bgp->rsclient, peer)))
1819 {
1820 peer_unlock (peer); /* peer rsclient reference */
1821 list_delete_node (bgp->rsclient, pn);
1822 }
1823
1824 bgp_table_finish (&peer->rib[afi][safi]);
1825
1826 /* Import policy. */
1827 if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
1828 {
1829 free (peer->filter[afi][safi].map[RMAP_IMPORT].name);
1830 peer->filter[afi][safi].map[RMAP_IMPORT].name = NULL;
1831 peer->filter[afi][safi].map[RMAP_IMPORT].map = NULL;
1832 }
1833
1834 /* Export policy. */
1835 if (! CHECK_FLAG(group->conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1836 && peer->filter[afi][safi].map[RMAP_EXPORT].name)
1837 {
1838 free (peer->filter[afi][safi].map[RMAP_EXPORT].name);
1839 peer->filter[afi][safi].map[RMAP_EXPORT].name = NULL;
1840 peer->filter[afi][safi].map[RMAP_EXPORT].map = NULL;
1841 }
1842 }
1843
1844 peer_group2peer_config_copy (group, peer, afi, safi);
1845
1846 if (peer->status == Established)
1847 {
1848 peer->last_reset = PEER_DOWN_RMAP_BIND;
1849 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1850 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1851 }
1852 else
1853 BGP_EVENT_ADD (peer, BGP_Stop);
1854
1855 return 0;
1856 }
1857
1858 int
1859 peer_group_unbind (struct bgp *bgp, struct peer *peer,
1860 struct peer_group *group, afi_t afi, safi_t safi)
1861 {
1862 if (! peer->af_group[afi][safi])
1863 return 0;
1864
1865 if (group != peer->group)
1866 return BGP_ERR_PEER_GROUP_MISMATCH;
1867
1868 peer->af_group[afi][safi] = 0;
1869 peer->afc[afi][safi] = 0;
1870 peer_af_flag_reset (peer, afi, safi);
1871
1872 if (peer->rib[afi][safi])
1873 peer->rib[afi][safi] = NULL;
1874
1875 if (! peer_group_active (peer))
1876 {
1877 assert (listnode_lookup (group->peer, peer));
1878 peer_unlock (peer); /* peer group list reference */
1879 listnode_delete (group->peer, peer);
1880 peer->group = NULL;
1881 if (group->conf->as)
1882 {
1883 peer_delete (peer);
1884 return 0;
1885 }
1886 peer_global_config_reset (peer);
1887 }
1888
1889 if (peer->status == Established)
1890 {
1891 peer->last_reset = PEER_DOWN_RMAP_UNBIND;
1892 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1893 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1894 }
1895 else
1896 BGP_EVENT_ADD (peer, BGP_Stop);
1897
1898 return 0;
1899 }
1900 \f
1901 /* BGP instance creation by `router bgp' commands. */
1902 static struct bgp *
1903 bgp_create (as_t *as, const char *name)
1904 {
1905 struct bgp *bgp;
1906 afi_t afi;
1907 safi_t safi;
1908
1909 if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
1910 return NULL;
1911
1912 bgp->peer_self = peer_new (bgp);
1913 bgp->peer_self->host = strdup ("Static announcement");
1914
1915 bgp->peer = list_new ();
1916 bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
1917
1918 bgp->group = list_new ();
1919 bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
1920
1921 bgp->rsclient = list_new ();
1922 bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
1923
1924 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1925 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1926 {
1927 bgp->route[afi][safi] = bgp_table_init (afi, safi);
1928 bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
1929 bgp->rib[afi][safi] = bgp_table_init (afi, safi);
1930 }
1931
1932 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
1933 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
1934 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
1935 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
1936 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
1937
1938 bgp->as = *as;
1939
1940 if (name)
1941 bgp->name = strdup (name);
1942
1943 return bgp;
1944 }
1945
1946 /* Return first entry of BGP. */
1947 struct bgp *
1948 bgp_get_default (void)
1949 {
1950 if (bm->bgp->head)
1951 return (listgetdata (listhead (bm->bgp)));
1952 return NULL;
1953 }
1954
1955 /* Lookup BGP entry. */
1956 struct bgp *
1957 bgp_lookup (as_t as, const char *name)
1958 {
1959 struct bgp *bgp;
1960 struct listnode *node, *nnode;
1961
1962 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
1963 if (bgp->as == as
1964 && ((bgp->name == NULL && name == NULL)
1965 || (bgp->name && name && strcmp (bgp->name, name) == 0)))
1966 return bgp;
1967 return NULL;
1968 }
1969
1970 /* Lookup BGP structure by view name. */
1971 struct bgp *
1972 bgp_lookup_by_name (const char *name)
1973 {
1974 struct bgp *bgp;
1975 struct listnode *node, *nnode;
1976
1977 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
1978 if ((bgp->name == NULL && name == NULL)
1979 || (bgp->name && name && strcmp (bgp->name, name) == 0))
1980 return bgp;
1981 return NULL;
1982 }
1983
1984 /* Called from VTY commands. */
1985 int
1986 bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
1987 {
1988 struct bgp *bgp;
1989
1990 /* Multiple instance check. */
1991 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
1992 {
1993 if (name)
1994 bgp = bgp_lookup_by_name (name);
1995 else
1996 bgp = bgp_get_default ();
1997
1998 /* Already exists. */
1999 if (bgp)
2000 {
2001 if (bgp->as != *as)
2002 {
2003 *as = bgp->as;
2004 return BGP_ERR_INSTANCE_MISMATCH;
2005 }
2006 *bgp_val = bgp;
2007 return 0;
2008 }
2009 }
2010 else
2011 {
2012 /* BGP instance name can not be specified for single instance. */
2013 if (name)
2014 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
2015
2016 /* Get default BGP structure if exists. */
2017 bgp = bgp_get_default ();
2018
2019 if (bgp)
2020 {
2021 if (bgp->as != *as)
2022 {
2023 *as = bgp->as;
2024 return BGP_ERR_AS_MISMATCH;
2025 }
2026 *bgp_val = bgp;
2027 return 0;
2028 }
2029 }
2030
2031 bgp = bgp_create (as, name);
2032 listnode_add (bm->bgp, bgp);
2033 bgp_router_id_set(bgp, &router_id_zebra);
2034 *bgp_val = bgp;
2035
2036 return 0;
2037 }
2038
2039 /* Delete BGP instance. */
2040 int
2041 bgp_delete (struct bgp *bgp)
2042 {
2043 struct peer *peer;
2044 struct peer_group *group;
2045 struct listnode *node;
2046 struct listnode *next;
2047 afi_t afi;
2048 safi_t safi;
2049 int i;
2050
2051 /* Delete static route. */
2052 bgp_static_delete (bgp);
2053
2054 /* Unset redistribution. */
2055 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2056 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2057 if (i != ZEBRA_ROUTE_BGP)
2058 bgp_redistribute_unset (bgp, afi, i);
2059
2060 for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
2061 peer_group_delete (group);
2062 list_delete (bgp->group);
2063
2064 for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
2065 peer_delete (peer);
2066 list_delete (bgp->peer);
2067
2068 for (ALL_LIST_ELEMENTS (bgp->rsclient, node, next, peer))
2069 peer_delete (peer);
2070 list_delete (bgp->rsclient);
2071
2072 listnode_delete (bm->bgp, bgp);
2073
2074 if (bgp->name)
2075 free (bgp->name);
2076
2077 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2078 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2079 {
2080 if (bgp->route[afi][safi])
2081 XFREE (MTYPE_ROUTE_TABLE, bgp->route[afi][safi]);
2082 if (bgp->aggregate[afi][safi])
2083 XFREE (MTYPE_ROUTE_TABLE,bgp->aggregate[afi][safi]) ;
2084 if (bgp->rib[afi][safi])
2085 XFREE (MTYPE_ROUTE_TABLE,bgp->rib[afi][safi]);
2086 }
2087 XFREE (MTYPE_BGP, bgp);
2088
2089 return 0;
2090 }
2091 \f
2092 struct peer *
2093 peer_lookup (struct bgp *bgp, union sockunion *su)
2094 {
2095 struct peer *peer;
2096 struct listnode *node, *nnode;
2097
2098 if (! bgp)
2099 bgp = bgp_get_default ();
2100
2101 if (! bgp)
2102 return NULL;
2103
2104 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2105 {
2106 if (sockunion_same (&peer->su, su)
2107 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2108 return peer;
2109 }
2110 return NULL;
2111 }
2112
2113 struct peer *
2114 peer_lookup_with_open (union sockunion *su, as_t remote_as,
2115 struct in_addr *remote_id, int *as)
2116 {
2117 struct peer *peer;
2118 struct listnode *node, *nnode;
2119 struct bgp *bgp;
2120
2121 bgp = bgp_get_default ();
2122 if (! bgp)
2123 return NULL;
2124
2125 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2126 {
2127 if (sockunion_same (&peer->su, su)
2128 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2129 {
2130 if (peer->as == remote_as
2131 && peer->remote_id.s_addr == remote_id->s_addr)
2132 return peer;
2133 if (peer->as == remote_as)
2134 *as = 1;
2135 }
2136 }
2137 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2138 {
2139 if (sockunion_same (&peer->su, su)
2140 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2141 {
2142 if (peer->as == remote_as
2143 && peer->remote_id.s_addr == 0)
2144 return peer;
2145 if (peer->as == remote_as)
2146 *as = 1;
2147 }
2148 }
2149 return NULL;
2150 }
2151 \f
2152 /* If peer is configured at least one address family return 1. */
2153 int
2154 peer_active (struct peer *peer)
2155 {
2156 if (peer->afc[AFI_IP][SAFI_UNICAST]
2157 || peer->afc[AFI_IP][SAFI_MULTICAST]
2158 || peer->afc[AFI_IP][SAFI_MPLS_VPN]
2159 || peer->afc[AFI_IP6][SAFI_UNICAST]
2160 || peer->afc[AFI_IP6][SAFI_MULTICAST])
2161 return 1;
2162 return 0;
2163 }
2164
2165 /* If peer is negotiated at least one address family return 1. */
2166 int
2167 peer_active_nego (struct peer *peer)
2168 {
2169 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
2170 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
2171 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
2172 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
2173 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
2174 return 1;
2175 return 0;
2176 }
2177 \f
2178 /* peer_flag_change_type. */
2179 enum peer_change_type
2180 {
2181 peer_change_none,
2182 peer_change_reset,
2183 peer_change_reset_in,
2184 peer_change_reset_out,
2185 };
2186
2187 static void
2188 peer_change_action (struct peer *peer, afi_t afi, safi_t safi,
2189 enum peer_change_type type)
2190 {
2191 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2192 return;
2193
2194 if (type == peer_change_reset)
2195 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2196 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2197 else if (type == peer_change_reset_in)
2198 {
2199 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
2200 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
2201 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
2202 else
2203 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2204 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2205 }
2206 else if (type == peer_change_reset_out)
2207 bgp_announce_route (peer, afi, safi);
2208 }
2209
2210 struct peer_flag_action
2211 {
2212 /* Peer's flag. */
2213 u_int32_t flag;
2214
2215 /* This flag can be set for peer-group member. */
2216 u_char not_for_member;
2217
2218 /* Action when the flag is changed. */
2219 enum peer_change_type type;
2220
2221 /* Peer down cause */
2222 u_char peer_down;
2223 };
2224
2225 struct peer_flag_action peer_flag_action_list[] =
2226 {
2227 { PEER_FLAG_PASSIVE, 0, peer_change_reset },
2228 { PEER_FLAG_SHUTDOWN, 0, peer_change_reset },
2229 { PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none },
2230 { PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none },
2231 { PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none },
2232 { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
2233 { PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
2234 { 0, 0, 0 }
2235 };
2236
2237 struct peer_flag_action peer_af_flag_action_list[] =
2238 {
2239 { PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out },
2240 { PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out },
2241 { PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out },
2242 { PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in },
2243 { PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset },
2244 { PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset },
2245 { PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out },
2246 { PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out },
2247 { PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out },
2248 { PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out },
2249 { PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in },
2250 { PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset },
2251 { PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
2252 { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
2253 { 0, 0, 0 }
2254 };
2255
2256 /* Proper action set. */
2257 static int
2258 peer_flag_action_set (struct peer_flag_action *action_list, int size,
2259 struct peer_flag_action *action, u_int32_t flag)
2260 {
2261 int i;
2262 int found = 0;
2263 int reset_in = 0;
2264 int reset_out = 0;
2265 struct peer_flag_action *match = NULL;
2266
2267 /* Check peer's frag action. */
2268 for (i = 0; i < size; i++)
2269 {
2270 match = &action_list[i];
2271
2272 if (match->flag == 0)
2273 break;
2274
2275 if (match->flag & flag)
2276 {
2277 found = 1;
2278
2279 if (match->type == peer_change_reset_in)
2280 reset_in = 1;
2281 if (match->type == peer_change_reset_out)
2282 reset_out = 1;
2283 if (match->type == peer_change_reset)
2284 {
2285 reset_in = 1;
2286 reset_out = 1;
2287 }
2288 if (match->not_for_member)
2289 action->not_for_member = 1;
2290 }
2291 }
2292
2293 /* Set peer clear type. */
2294 if (reset_in && reset_out)
2295 action->type = peer_change_reset;
2296 else if (reset_in)
2297 action->type = peer_change_reset_in;
2298 else if (reset_out)
2299 action->type = peer_change_reset_out;
2300 else
2301 action->type = peer_change_none;
2302
2303 return found;
2304 }
2305
2306 static void
2307 peer_flag_modify_action (struct peer *peer, u_int32_t flag)
2308 {
2309 if (flag == PEER_FLAG_SHUTDOWN)
2310 {
2311 if (CHECK_FLAG (peer->flags, flag))
2312 {
2313 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2314 peer_nsf_stop (peer);
2315
2316 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2317 if (peer->t_pmax_restart)
2318 {
2319 BGP_TIMER_OFF (peer->t_pmax_restart);
2320 if (BGP_DEBUG (events, EVENTS))
2321 zlog_debug ("%s Maximum-prefix restart timer canceled",
2322 peer->host);
2323 }
2324
2325 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2326 peer_nsf_stop (peer);
2327
2328 if (peer->status == Established)
2329 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2330 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2331 else
2332 BGP_EVENT_ADD (peer, BGP_Stop);
2333 }
2334 else
2335 {
2336 peer->v_start = BGP_INIT_START_TIMER;
2337 BGP_EVENT_ADD (peer, BGP_Stop);
2338 }
2339 }
2340 else if (peer->status == Established)
2341 {
2342 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
2343 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2344 else if (flag == PEER_FLAG_PASSIVE)
2345 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
2346 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
2347 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
2348
2349 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2350 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2351 }
2352 else
2353 BGP_EVENT_ADD (peer, BGP_Stop);
2354 }
2355
2356 /* Change specified peer flag. */
2357 static int
2358 peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
2359 {
2360 int found;
2361 int size;
2362 struct peer_group *group;
2363 struct listnode *node, *nnode;
2364 struct peer_flag_action action;
2365
2366 memset (&action, 0, sizeof (struct peer_flag_action));
2367 size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
2368
2369 found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
2370
2371 /* No flag action is found. */
2372 if (! found)
2373 return BGP_ERR_INVALID_FLAG;
2374
2375 /* Not for peer-group member. */
2376 if (action.not_for_member && peer_group_active (peer))
2377 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2378
2379 /* When unset the peer-group member's flag we have to check
2380 peer-group configuration. */
2381 if (! set && peer_group_active (peer))
2382 if (CHECK_FLAG (peer->group->conf->flags, flag))
2383 {
2384 if (flag == PEER_FLAG_SHUTDOWN)
2385 return BGP_ERR_PEER_GROUP_SHUTDOWN;
2386 else
2387 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2388 }
2389
2390 /* Flag conflict check. */
2391 if (set
2392 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
2393 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
2394 return BGP_ERR_PEER_FLAG_CONFLICT;
2395
2396 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2397 {
2398 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2399 return 0;
2400 if (! set && ! CHECK_FLAG (peer->flags, flag))
2401 return 0;
2402 }
2403
2404 if (set)
2405 SET_FLAG (peer->flags, flag);
2406 else
2407 UNSET_FLAG (peer->flags, flag);
2408
2409 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2410 {
2411 if (action.type == peer_change_reset)
2412 peer_flag_modify_action (peer, flag);
2413
2414 return 0;
2415 }
2416
2417 /* peer-group member updates. */
2418 group = peer->group;
2419
2420 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2421 {
2422 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2423 continue;
2424
2425 if (! set && ! CHECK_FLAG (peer->flags, flag))
2426 continue;
2427
2428 if (set)
2429 SET_FLAG (peer->flags, flag);
2430 else
2431 UNSET_FLAG (peer->flags, flag);
2432
2433 if (action.type == peer_change_reset)
2434 peer_flag_modify_action (peer, flag);
2435 }
2436 return 0;
2437 }
2438
2439 int
2440 peer_flag_set (struct peer *peer, u_int32_t flag)
2441 {
2442 return peer_flag_modify (peer, flag, 1);
2443 }
2444
2445 int
2446 peer_flag_unset (struct peer *peer, u_int32_t flag)
2447 {
2448 return peer_flag_modify (peer, flag, 0);
2449 }
2450
2451 static int
2452 peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
2453 {
2454 if (peer->af_group[afi][safi])
2455 return 1;
2456 return 0;
2457 }
2458
2459 static int
2460 peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
2461 int set)
2462 {
2463 int found;
2464 int size;
2465 struct listnode *node, *nnode;
2466 struct peer_group *group;
2467 struct peer_flag_action action;
2468
2469 memset (&action, 0, sizeof (struct peer_flag_action));
2470 size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action);
2471
2472 found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag);
2473
2474 /* No flag action is found. */
2475 if (! found)
2476 return BGP_ERR_INVALID_FLAG;
2477
2478 /* Adress family must be activated. */
2479 if (! peer->afc[afi][safi])
2480 return BGP_ERR_PEER_INACTIVE;
2481
2482 /* Not for peer-group member. */
2483 if (action.not_for_member && peer_is_group_member (peer, afi, safi))
2484 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2485
2486 /* Spcecial check for reflector client. */
2487 if (flag & PEER_FLAG_REFLECTOR_CLIENT
2488 && peer_sort (peer) != BGP_PEER_IBGP)
2489 return BGP_ERR_NOT_INTERNAL_PEER;
2490
2491 /* Spcecial check for remove-private-AS. */
2492 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
2493 && peer_sort (peer) == BGP_PEER_IBGP)
2494 return BGP_ERR_REMOVE_PRIVATE_AS;
2495
2496 /* When unset the peer-group member's flag we have to check
2497 peer-group configuration. */
2498 if (! set && peer->af_group[afi][safi])
2499 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
2500 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2501
2502 /* When current flag configuration is same as requested one. */
2503 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2504 {
2505 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2506 return 0;
2507 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2508 return 0;
2509 }
2510
2511 if (set)
2512 SET_FLAG (peer->af_flags[afi][safi], flag);
2513 else
2514 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2515
2516 /* Execute action when peer is established. */
2517 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2518 && peer->status == Established)
2519 {
2520 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2521 bgp_clear_adj_in (peer, afi, safi);
2522 else
2523 {
2524 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2525 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2526 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2527 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2528 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2529 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2530 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2531 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2532
2533 peer_change_action (peer, afi, safi, action.type);
2534 }
2535
2536 }
2537
2538 /* Peer group member updates. */
2539 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2540 {
2541 group = peer->group;
2542
2543 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2544 {
2545 if (! peer->af_group[afi][safi])
2546 continue;
2547
2548 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2549 continue;
2550
2551 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2552 continue;
2553
2554 if (set)
2555 SET_FLAG (peer->af_flags[afi][safi], flag);
2556 else
2557 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2558
2559 if (peer->status == Established)
2560 {
2561 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2562 bgp_clear_adj_in (peer, afi, safi);
2563 else
2564 {
2565 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2566 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2567 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2568 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2569 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2570 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2571 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2572 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2573
2574 peer_change_action (peer, afi, safi, action.type);
2575 }
2576 }
2577 }
2578 }
2579 return 0;
2580 }
2581
2582 int
2583 peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2584 {
2585 return peer_af_flag_modify (peer, afi, safi, flag, 1);
2586 }
2587
2588 int
2589 peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2590 {
2591 return peer_af_flag_modify (peer, afi, safi, flag, 0);
2592 }
2593 \f
2594 /* EBGP multihop configuration. */
2595 int
2596 peer_ebgp_multihop_set (struct peer *peer, int ttl)
2597 {
2598 struct peer_group *group;
2599 struct listnode *node, *nnode;
2600
2601 if (peer_sort (peer) == BGP_PEER_IBGP)
2602 return 0;
2603
2604 peer->ttl = ttl;
2605
2606 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2607 {
2608 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2609 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2610 }
2611 else
2612 {
2613 group = peer->group;
2614 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2615 {
2616 if (peer_sort (peer) == BGP_PEER_IBGP)
2617 continue;
2618
2619 peer->ttl = group->conf->ttl;
2620
2621 if (peer->fd >= 0)
2622 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2623 }
2624 }
2625 return 0;
2626 }
2627
2628 int
2629 peer_ebgp_multihop_unset (struct peer *peer)
2630 {
2631 struct peer_group *group;
2632 struct listnode *node, *nnode;
2633
2634 if (peer_sort (peer) == BGP_PEER_IBGP)
2635 return 0;
2636
2637 if (peer_group_active (peer))
2638 peer->ttl = peer->group->conf->ttl;
2639 else
2640 peer->ttl = 1;
2641
2642 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2643 {
2644 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2645 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2646 }
2647 else
2648 {
2649 group = peer->group;
2650 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2651 {
2652 if (peer_sort (peer) == BGP_PEER_IBGP)
2653 continue;
2654
2655 peer->ttl = 1;
2656
2657 if (peer->fd >= 0)
2658 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2659 }
2660 }
2661 return 0;
2662 }
2663 \f
2664 /* Neighbor description. */
2665 int
2666 peer_description_set (struct peer *peer, char *desc)
2667 {
2668 if (peer->desc)
2669 XFREE (MTYPE_PEER_DESC, peer->desc);
2670
2671 peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
2672
2673 return 0;
2674 }
2675
2676 int
2677 peer_description_unset (struct peer *peer)
2678 {
2679 if (peer->desc)
2680 XFREE (MTYPE_PEER_DESC, peer->desc);
2681
2682 peer->desc = NULL;
2683
2684 return 0;
2685 }
2686 \f
2687 /* Neighbor update-source. */
2688 int
2689 peer_update_source_if_set (struct peer *peer, const char *ifname)
2690 {
2691 struct peer_group *group;
2692 struct listnode *node, *nnode;
2693
2694 if (peer->update_if)
2695 {
2696 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2697 && strcmp (peer->update_if, ifname) == 0)
2698 return 0;
2699
2700 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2701 peer->update_if = NULL;
2702 }
2703
2704 if (peer->update_source)
2705 {
2706 sockunion_free (peer->update_source);
2707 peer->update_source = NULL;
2708 }
2709
2710 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2711
2712 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2713 {
2714 if (peer->status == Established)
2715 {
2716 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2717 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2718 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2719 }
2720 else
2721 BGP_EVENT_ADD (peer, BGP_Stop);
2722 return 0;
2723 }
2724
2725 /* peer-group member updates. */
2726 group = peer->group;
2727 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2728 {
2729 if (peer->update_if)
2730 {
2731 if (strcmp (peer->update_if, ifname) == 0)
2732 continue;
2733
2734 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2735 peer->update_if = NULL;
2736 }
2737
2738 if (peer->update_source)
2739 {
2740 sockunion_free (peer->update_source);
2741 peer->update_source = NULL;
2742 }
2743
2744 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2745
2746 if (peer->status == Established)
2747 {
2748 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2749 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2750 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2751 }
2752 else
2753 BGP_EVENT_ADD (peer, BGP_Stop);
2754 }
2755 return 0;
2756 }
2757
2758 int
2759 peer_update_source_addr_set (struct peer *peer, union sockunion *su)
2760 {
2761 struct peer_group *group;
2762 struct listnode *node, *nnode;
2763
2764 if (peer->update_source)
2765 {
2766 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2767 && sockunion_cmp (peer->update_source, su) == 0)
2768 return 0;
2769 sockunion_free (peer->update_source);
2770 peer->update_source = NULL;
2771 }
2772
2773 if (peer->update_if)
2774 {
2775 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2776 peer->update_if = NULL;
2777 }
2778
2779 peer->update_source = sockunion_dup (su);
2780
2781 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2782 {
2783 if (peer->status == Established)
2784 {
2785 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2786 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2787 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2788 }
2789 else
2790 BGP_EVENT_ADD (peer, BGP_Stop);
2791 return 0;
2792 }
2793
2794 /* peer-group member updates. */
2795 group = peer->group;
2796 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2797 {
2798 if (peer->update_source)
2799 {
2800 if (sockunion_cmp (peer->update_source, su) == 0)
2801 continue;
2802 sockunion_free (peer->update_source);
2803 peer->update_source = NULL;
2804 }
2805
2806 if (peer->update_if)
2807 {
2808 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2809 peer->update_if = NULL;
2810 }
2811
2812 peer->update_source = sockunion_dup (su);
2813
2814 if (peer->status == Established)
2815 {
2816 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2817 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2818 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2819 }
2820 else
2821 BGP_EVENT_ADD (peer, BGP_Stop);
2822 }
2823 return 0;
2824 }
2825
2826 int
2827 peer_update_source_unset (struct peer *peer)
2828 {
2829 union sockunion *su;
2830 struct peer_group *group;
2831 struct listnode *node, *nnode;
2832
2833 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2834 && ! peer->update_source
2835 && ! peer->update_if)
2836 return 0;
2837
2838 if (peer->update_source)
2839 {
2840 sockunion_free (peer->update_source);
2841 peer->update_source = NULL;
2842 }
2843 if (peer->update_if)
2844 {
2845 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2846 peer->update_if = NULL;
2847 }
2848
2849 if (peer_group_active (peer))
2850 {
2851 group = peer->group;
2852
2853 if (group->conf->update_source)
2854 {
2855 su = sockunion_dup (group->conf->update_source);
2856 peer->update_source = su;
2857 }
2858 else if (group->conf->update_if)
2859 peer->update_if =
2860 XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
2861 }
2862
2863 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2864 {
2865 if (peer->status == Established)
2866 {
2867 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2868 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2869 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2870 }
2871 else
2872 BGP_EVENT_ADD (peer, BGP_Stop);
2873 return 0;
2874 }
2875
2876 /* peer-group member updates. */
2877 group = peer->group;
2878 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2879 {
2880 if (! peer->update_source && ! peer->update_if)
2881 continue;
2882
2883 if (peer->update_source)
2884 {
2885 sockunion_free (peer->update_source);
2886 peer->update_source = NULL;
2887 }
2888
2889 if (peer->update_if)
2890 {
2891 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2892 peer->update_if = NULL;
2893 }
2894
2895 if (peer->status == Established)
2896 {
2897 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2898 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2899 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2900 }
2901 else
2902 BGP_EVENT_ADD (peer, BGP_Stop);
2903 }
2904 return 0;
2905 }
2906 \f
2907 int
2908 peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
2909 const char *rmap)
2910 {
2911 struct peer_group *group;
2912 struct listnode *node, *nnode;
2913
2914 /* Adress family must be activated. */
2915 if (! peer->afc[afi][safi])
2916 return BGP_ERR_PEER_INACTIVE;
2917
2918 /* Default originate can't be used for peer group memeber. */
2919 if (peer_is_group_member (peer, afi, safi))
2920 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2921
2922 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
2923 || (rmap && ! peer->default_rmap[afi][safi].name)
2924 || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
2925 {
2926 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
2927
2928 if (rmap)
2929 {
2930 if (peer->default_rmap[afi][safi].name)
2931 free (peer->default_rmap[afi][safi].name);
2932 peer->default_rmap[afi][safi].name = strdup (rmap);
2933 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
2934 }
2935 }
2936
2937 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2938 {
2939 if (peer->status == Established && peer->afc_nego[afi][safi])
2940 bgp_default_originate (peer, afi, safi, 0);
2941 return 0;
2942 }
2943
2944 /* peer-group member updates. */
2945 group = peer->group;
2946 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2947 {
2948 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
2949
2950 if (rmap)
2951 {
2952 if (peer->default_rmap[afi][safi].name)
2953 free (peer->default_rmap[afi][safi].name);
2954 peer->default_rmap[afi][safi].name = strdup (rmap);
2955 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
2956 }
2957
2958 if (peer->status == Established && peer->afc_nego[afi][safi])
2959 bgp_default_originate (peer, afi, safi, 0);
2960 }
2961 return 0;
2962 }
2963
2964 int
2965 peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
2966 {
2967 struct peer_group *group;
2968 struct listnode *node, *nnode;
2969
2970 /* Adress family must be activated. */
2971 if (! peer->afc[afi][safi])
2972 return BGP_ERR_PEER_INACTIVE;
2973
2974 /* Default originate can't be used for peer group memeber. */
2975 if (peer_is_group_member (peer, afi, safi))
2976 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2977
2978 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
2979 {
2980 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
2981
2982 if (peer->default_rmap[afi][safi].name)
2983 free (peer->default_rmap[afi][safi].name);
2984 peer->default_rmap[afi][safi].name = NULL;
2985 peer->default_rmap[afi][safi].map = NULL;
2986 }
2987
2988 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2989 {
2990 if (peer->status == Established && peer->afc_nego[afi][safi])
2991 bgp_default_originate (peer, afi, safi, 1);
2992 return 0;
2993 }
2994
2995 /* peer-group member updates. */
2996 group = peer->group;
2997 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2998 {
2999 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3000
3001 if (peer->default_rmap[afi][safi].name)
3002 free (peer->default_rmap[afi][safi].name);
3003 peer->default_rmap[afi][safi].name = NULL;
3004 peer->default_rmap[afi][safi].map = NULL;
3005
3006 if (peer->status == Established && peer->afc_nego[afi][safi])
3007 bgp_default_originate (peer, afi, safi, 1);
3008 }
3009 return 0;
3010 }
3011 \f
3012 int
3013 peer_port_set (struct peer *peer, u_int16_t port)
3014 {
3015 peer->port = port;
3016 return 0;
3017 }
3018
3019 int
3020 peer_port_unset (struct peer *peer)
3021 {
3022 peer->port = BGP_PORT_DEFAULT;
3023 return 0;
3024 }
3025 \f
3026 /* neighbor weight. */
3027 int
3028 peer_weight_set (struct peer *peer, u_int16_t weight)
3029 {
3030 struct peer_group *group;
3031 struct listnode *node, *nnode;
3032
3033 SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3034 peer->weight = weight;
3035
3036 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3037 return 0;
3038
3039 /* peer-group member updates. */
3040 group = peer->group;
3041 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3042 {
3043 peer->weight = group->conf->weight;
3044 }
3045 return 0;
3046 }
3047
3048 int
3049 peer_weight_unset (struct peer *peer)
3050 {
3051 struct peer_group *group;
3052 struct listnode *node, *nnode;
3053
3054 /* Set default weight. */
3055 if (peer_group_active (peer))
3056 peer->weight = peer->group->conf->weight;
3057 else
3058 peer->weight = 0;
3059
3060 UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3061
3062 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3063 return 0;
3064
3065 /* peer-group member updates. */
3066 group = peer->group;
3067 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3068 {
3069 peer->weight = 0;
3070 }
3071 return 0;
3072 }
3073 \f
3074 int
3075 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
3076 {
3077 struct peer_group *group;
3078 struct listnode *node, *nnode;
3079
3080 /* Not for peer group memeber. */
3081 if (peer_group_active (peer))
3082 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3083
3084 /* keepalive value check. */
3085 if (keepalive > 65535)
3086 return BGP_ERR_INVALID_VALUE;
3087
3088 /* Holdtime value check. */
3089 if (holdtime > 65535)
3090 return BGP_ERR_INVALID_VALUE;
3091
3092 /* Holdtime value must be either 0 or greater than 3. */
3093 if (holdtime < 3 && holdtime != 0)
3094 return BGP_ERR_INVALID_VALUE;
3095
3096 /* Set value to the configuration. */
3097 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3098 peer->holdtime = holdtime;
3099 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
3100
3101 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3102 return 0;
3103
3104 /* peer-group member updates. */
3105 group = peer->group;
3106 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3107 {
3108 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3109 peer->holdtime = group->conf->holdtime;
3110 peer->keepalive = group->conf->keepalive;
3111 }
3112 return 0;
3113 }
3114
3115 int
3116 peer_timers_unset (struct peer *peer)
3117 {
3118 struct peer_group *group;
3119 struct listnode *node, *nnode;
3120
3121 if (peer_group_active (peer))
3122 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3123
3124 /* Clear configuration. */
3125 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3126 peer->keepalive = 0;
3127 peer->holdtime = 0;
3128
3129 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3130 return 0;
3131
3132 /* peer-group member updates. */
3133 group = peer->group;
3134 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3135 {
3136 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3137 peer->holdtime = 0;
3138 peer->keepalive = 0;
3139 }
3140
3141 return 0;
3142 }
3143 \f
3144 int
3145 peer_timers_connect_set (struct peer *peer, u_int32_t connect)
3146 {
3147 if (peer_group_active (peer))
3148 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3149
3150 if (connect > 65535)
3151 return BGP_ERR_INVALID_VALUE;
3152
3153 /* Set value to the configuration. */
3154 SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3155 peer->connect = connect;
3156
3157 /* Set value to timer setting. */
3158 peer->v_connect = connect;
3159
3160 return 0;
3161 }
3162
3163 int
3164 peer_timers_connect_unset (struct peer *peer)
3165 {
3166 if (peer_group_active (peer))
3167 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3168
3169 /* Clear configuration. */
3170 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3171 peer->connect = 0;
3172
3173 /* Set timer setting to default value. */
3174 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
3175
3176 return 0;
3177 }
3178 \f
3179 int
3180 peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
3181 {
3182 if (peer_group_active (peer))
3183 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3184
3185 if (routeadv > 600)
3186 return BGP_ERR_INVALID_VALUE;
3187
3188 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3189 peer->routeadv = routeadv;
3190 peer->v_routeadv = routeadv;
3191
3192 return 0;
3193 }
3194
3195 int
3196 peer_advertise_interval_unset (struct peer *peer)
3197 {
3198 if (peer_group_active (peer))
3199 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3200
3201 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3202 peer->routeadv = 0;
3203
3204 if (peer_sort (peer) == BGP_PEER_IBGP)
3205 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
3206 else
3207 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
3208
3209 return 0;
3210 }
3211 \f
3212 /* neighbor interface */
3213 int
3214 peer_interface_set (struct peer *peer, const char *str)
3215 {
3216 if (peer->ifname)
3217 free (peer->ifname);
3218 peer->ifname = strdup (str);
3219
3220 return 0;
3221 }
3222
3223 int
3224 peer_interface_unset (struct peer *peer)
3225 {
3226 if (peer->ifname)
3227 free (peer->ifname);
3228 peer->ifname = NULL;
3229
3230 return 0;
3231 }
3232 \f
3233 /* Allow-as in. */
3234 int
3235 peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
3236 {
3237 struct peer_group *group;
3238 struct listnode *node, *nnode;
3239
3240 if (allow_num < 1 || allow_num > 10)
3241 return BGP_ERR_INVALID_VALUE;
3242
3243 if (peer->allowas_in[afi][safi] != allow_num)
3244 {
3245 peer->allowas_in[afi][safi] = allow_num;
3246 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3247 peer_change_action (peer, afi, safi, peer_change_reset_in);
3248 }
3249
3250 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3251 return 0;
3252
3253 group = peer->group;
3254 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3255 {
3256 if (peer->allowas_in[afi][safi] != allow_num)
3257 {
3258 peer->allowas_in[afi][safi] = allow_num;
3259 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3260 peer_change_action (peer, afi, safi, peer_change_reset_in);
3261 }
3262
3263 }
3264 return 0;
3265 }
3266
3267 int
3268 peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
3269 {
3270 struct peer_group *group;
3271 struct listnode *node, *nnode;
3272
3273 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3274 {
3275 peer->allowas_in[afi][safi] = 0;
3276 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3277 }
3278
3279 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3280 return 0;
3281
3282 group = peer->group;
3283 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3284 {
3285 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3286 {
3287 peer->allowas_in[afi][safi] = 0;
3288 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3289 }
3290 }
3291 return 0;
3292 }
3293 \f
3294 int
3295 peer_local_as_set (struct peer *peer, as_t as, int no_prepend)
3296 {
3297 struct bgp *bgp = peer->bgp;
3298 struct peer_group *group;
3299 struct listnode *node, *nnode;
3300
3301 if (peer_sort (peer) != BGP_PEER_EBGP
3302 && peer_sort (peer) != BGP_PEER_INTERNAL)
3303 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
3304
3305 if (bgp->as == as)
3306 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
3307
3308 if (peer_group_active (peer))
3309 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3310
3311 if (peer->change_local_as == as &&
3312 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
3313 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)))
3314 return 0;
3315
3316 peer->change_local_as = as;
3317 if (no_prepend)
3318 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3319 else
3320 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3321
3322 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3323 {
3324 if (peer->status == Established)
3325 {
3326 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3327 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3328 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3329 }
3330 else
3331 BGP_EVENT_ADD (peer, BGP_Stop);
3332
3333 return 0;
3334 }
3335
3336 group = peer->group;
3337 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3338 {
3339 peer->change_local_as = as;
3340 if (no_prepend)
3341 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3342 else
3343 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3344
3345 if (peer->status == Established)
3346 {
3347 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3348 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3349 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3350 }
3351 else
3352 BGP_EVENT_ADD (peer, BGP_Stop);
3353 }
3354
3355 return 0;
3356 }
3357
3358 int
3359 peer_local_as_unset (struct peer *peer)
3360 {
3361 struct peer_group *group;
3362 struct listnode *node, *nnode;
3363
3364 if (peer_group_active (peer))
3365 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3366
3367 if (! peer->change_local_as)
3368 return 0;
3369
3370 peer->change_local_as = 0;
3371 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3372
3373 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3374 {
3375 if (peer->status == Established)
3376 {
3377 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3378 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3379 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3380 }
3381 else
3382 BGP_EVENT_ADD (peer, BGP_Stop);
3383
3384 return 0;
3385 }
3386
3387 group = peer->group;
3388 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3389 {
3390 peer->change_local_as = 0;
3391 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3392
3393 if (peer->status == Established)
3394 {
3395 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3396 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3397 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3398 }
3399 else
3400 BGP_EVENT_ADD (peer, BGP_Stop);
3401 }
3402 return 0;
3403 }
3404 \f
3405 /* Set password for authenticating with the peer. */
3406 int
3407 peer_password_set (struct peer *peer, const char *password)
3408 {
3409 struct listnode *nn, *nnode;
3410 int len = password ? strlen(password) : 0;
3411 int ret = BGP_SUCCESS;
3412
3413 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
3414 return BGP_ERR_INVALID_VALUE;
3415
3416 if (peer->password && strcmp (peer->password, password) == 0
3417 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3418 return 0;
3419
3420 if (peer->password)
3421 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3422
3423 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
3424
3425 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3426 {
3427 if (peer->status == Established)
3428 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3429 else
3430 BGP_EVENT_ADD (peer, BGP_Stop);
3431
3432 return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
3433 }
3434
3435 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3436 {
3437 if (peer->password && strcmp (peer->password, password) == 0)
3438 continue;
3439
3440 if (peer->password)
3441 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3442
3443 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
3444
3445 if (peer->status == Established)
3446 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3447 else
3448 BGP_EVENT_ADD (peer, BGP_Stop);
3449
3450 if (bgp_md5_set (peer) < 0)
3451 ret = BGP_ERR_TCPSIG_FAILED;
3452 }
3453
3454 return ret;
3455 }
3456
3457 int
3458 peer_password_unset (struct peer *peer)
3459 {
3460 struct listnode *nn, *nnode;
3461
3462 if (!peer->password
3463 && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3464 return 0;
3465
3466 if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3467 {
3468 if (peer_group_active (peer)
3469 && peer->group->conf->password
3470 && strcmp (peer->group->conf->password, peer->password) == 0)
3471 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
3472
3473 if (peer->status == Established)
3474 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3475 else
3476 BGP_EVENT_ADD (peer, BGP_Stop);
3477
3478 if (peer->password)
3479 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3480
3481 peer->password = NULL;
3482
3483 bgp_md5_set (peer);
3484
3485 return 0;
3486 }
3487
3488 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3489 peer->password = NULL;
3490
3491 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3492 {
3493 if (!peer->password)
3494 continue;
3495
3496 if (peer->status == Established)
3497 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3498 else
3499 BGP_EVENT_ADD (peer, BGP_Stop);
3500
3501 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3502 peer->password = NULL;
3503
3504 bgp_md5_set (peer);
3505 }
3506
3507 return 0;
3508 }
3509 \f
3510 /* Set distribute list to the peer. */
3511 int
3512 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3513 const char *name)
3514 {
3515 struct bgp_filter *filter;
3516 struct peer_group *group;
3517 struct listnode *node, *nnode;
3518
3519 if (! peer->afc[afi][safi])
3520 return BGP_ERR_PEER_INACTIVE;
3521
3522 if (direct != FILTER_IN && direct != FILTER_OUT)
3523 return BGP_ERR_INVALID_VALUE;
3524
3525 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3526 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3527
3528 filter = &peer->filter[afi][safi];
3529
3530 if (filter->plist[direct].name)
3531 return BGP_ERR_PEER_FILTER_CONFLICT;
3532
3533 if (filter->dlist[direct].name)
3534 free (filter->dlist[direct].name);
3535 filter->dlist[direct].name = strdup (name);
3536 filter->dlist[direct].alist = access_list_lookup (afi, name);
3537
3538 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3539 return 0;
3540
3541 group = peer->group;
3542 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3543 {
3544 filter = &peer->filter[afi][safi];
3545
3546 if (! peer->af_group[afi][safi])
3547 continue;
3548
3549 if (filter->dlist[direct].name)
3550 free (filter->dlist[direct].name);
3551 filter->dlist[direct].name = strdup (name);
3552 filter->dlist[direct].alist = access_list_lookup (afi, name);
3553 }
3554
3555 return 0;
3556 }
3557
3558 int
3559 peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3560 {
3561 struct bgp_filter *filter;
3562 struct bgp_filter *gfilter;
3563 struct peer_group *group;
3564 struct listnode *node, *nnode;
3565
3566 if (! peer->afc[afi][safi])
3567 return BGP_ERR_PEER_INACTIVE;
3568
3569 if (direct != FILTER_IN && direct != FILTER_OUT)
3570 return BGP_ERR_INVALID_VALUE;
3571
3572 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3573 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3574
3575 filter = &peer->filter[afi][safi];
3576
3577 /* apply peer-group filter */
3578 if (peer->af_group[afi][safi])
3579 {
3580 gfilter = &peer->group->conf->filter[afi][safi];
3581
3582 if (gfilter->dlist[direct].name)
3583 {
3584 if (filter->dlist[direct].name)
3585 free (filter->dlist[direct].name);
3586 filter->dlist[direct].name = strdup (gfilter->dlist[direct].name);
3587 filter->dlist[direct].alist = gfilter->dlist[direct].alist;
3588 return 0;
3589 }
3590 }
3591
3592 if (filter->dlist[direct].name)
3593 free (filter->dlist[direct].name);
3594 filter->dlist[direct].name = NULL;
3595 filter->dlist[direct].alist = NULL;
3596
3597 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3598 return 0;
3599
3600 group = peer->group;
3601 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3602 {
3603 filter = &peer->filter[afi][safi];
3604
3605 if (! peer->af_group[afi][safi])
3606 continue;
3607
3608 if (filter->dlist[direct].name)
3609 free (filter->dlist[direct].name);
3610 filter->dlist[direct].name = NULL;
3611 filter->dlist[direct].alist = NULL;
3612 }
3613
3614 return 0;
3615 }
3616
3617 /* Update distribute list. */
3618 static void
3619 peer_distribute_update (struct access_list *access)
3620 {
3621 afi_t afi;
3622 safi_t safi;
3623 int direct;
3624 struct listnode *mnode, *mnnode;
3625 struct listnode *node, *nnode;
3626 struct bgp *bgp;
3627 struct peer *peer;
3628 struct peer_group *group;
3629 struct bgp_filter *filter;
3630
3631 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3632 {
3633 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3634 {
3635 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3636 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3637 {
3638 filter = &peer->filter[afi][safi];
3639
3640 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3641 {
3642 if (filter->dlist[direct].name)
3643 filter->dlist[direct].alist =
3644 access_list_lookup (afi, filter->dlist[direct].name);
3645 else
3646 filter->dlist[direct].alist = NULL;
3647 }
3648 }
3649 }
3650 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3651 {
3652 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3653 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3654 {
3655 filter = &group->conf->filter[afi][safi];
3656
3657 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3658 {
3659 if (filter->dlist[direct].name)
3660 filter->dlist[direct].alist =
3661 access_list_lookup (afi, filter->dlist[direct].name);
3662 else
3663 filter->dlist[direct].alist = NULL;
3664 }
3665 }
3666 }
3667 }
3668 }
3669 \f
3670 /* Set prefix list to the peer. */
3671 int
3672 peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3673 const char *name)
3674 {
3675 struct bgp_filter *filter;
3676 struct peer_group *group;
3677 struct listnode *node, *nnode;
3678
3679 if (! peer->afc[afi][safi])
3680 return BGP_ERR_PEER_INACTIVE;
3681
3682 if (direct != FILTER_IN && direct != FILTER_OUT)
3683 return BGP_ERR_INVALID_VALUE;
3684
3685 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3686 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3687
3688 filter = &peer->filter[afi][safi];
3689
3690 if (filter->dlist[direct].name)
3691 return BGP_ERR_PEER_FILTER_CONFLICT;
3692
3693 if (filter->plist[direct].name)
3694 free (filter->plist[direct].name);
3695 filter->plist[direct].name = strdup (name);
3696 filter->plist[direct].plist = prefix_list_lookup (afi, name);
3697
3698 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3699 return 0;
3700
3701 group = peer->group;
3702 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3703 {
3704 filter = &peer->filter[afi][safi];
3705
3706 if (! peer->af_group[afi][safi])
3707 continue;
3708
3709 if (filter->plist[direct].name)
3710 free (filter->plist[direct].name);
3711 filter->plist[direct].name = strdup (name);
3712 filter->plist[direct].plist = prefix_list_lookup (afi, name);
3713 }
3714 return 0;
3715 }
3716
3717 int
3718 peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3719 {
3720 struct bgp_filter *filter;
3721 struct bgp_filter *gfilter;
3722 struct peer_group *group;
3723 struct listnode *node, *nnode;
3724
3725 if (! peer->afc[afi][safi])
3726 return BGP_ERR_PEER_INACTIVE;
3727
3728 if (direct != FILTER_IN && direct != FILTER_OUT)
3729 return BGP_ERR_INVALID_VALUE;
3730
3731 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3732 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3733
3734 filter = &peer->filter[afi][safi];
3735
3736 /* apply peer-group filter */
3737 if (peer->af_group[afi][safi])
3738 {
3739 gfilter = &peer->group->conf->filter[afi][safi];
3740
3741 if (gfilter->plist[direct].name)
3742 {
3743 if (filter->plist[direct].name)
3744 free (filter->plist[direct].name);
3745 filter->plist[direct].name = strdup (gfilter->plist[direct].name);
3746 filter->plist[direct].plist = gfilter->plist[direct].plist;
3747 return 0;
3748 }
3749 }
3750
3751 if (filter->plist[direct].name)
3752 free (filter->plist[direct].name);
3753 filter->plist[direct].name = NULL;
3754 filter->plist[direct].plist = NULL;
3755
3756 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3757 return 0;
3758
3759 group = peer->group;
3760 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3761 {
3762 filter = &peer->filter[afi][safi];
3763
3764 if (! peer->af_group[afi][safi])
3765 continue;
3766
3767 if (filter->plist[direct].name)
3768 free (filter->plist[direct].name);
3769 filter->plist[direct].name = NULL;
3770 filter->plist[direct].plist = NULL;
3771 }
3772
3773 return 0;
3774 }
3775
3776 /* Update prefix-list list. */
3777 static void
3778 peer_prefix_list_update (struct prefix_list *plist)
3779 {
3780 struct listnode *mnode, *mnnode;
3781 struct listnode *node, *nnode;
3782 struct bgp *bgp;
3783 struct peer *peer;
3784 struct peer_group *group;
3785 struct bgp_filter *filter;
3786 afi_t afi;
3787 safi_t safi;
3788 int direct;
3789
3790 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3791 {
3792 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3793 {
3794 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3795 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3796 {
3797 filter = &peer->filter[afi][safi];
3798
3799 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3800 {
3801 if (filter->plist[direct].name)
3802 filter->plist[direct].plist =
3803 prefix_list_lookup (afi, filter->plist[direct].name);
3804 else
3805 filter->plist[direct].plist = NULL;
3806 }
3807 }
3808 }
3809 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3810 {
3811 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3812 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3813 {
3814 filter = &group->conf->filter[afi][safi];
3815
3816 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3817 {
3818 if (filter->plist[direct].name)
3819 filter->plist[direct].plist =
3820 prefix_list_lookup (afi, filter->plist[direct].name);
3821 else
3822 filter->plist[direct].plist = NULL;
3823 }
3824 }
3825 }
3826 }
3827 }
3828 \f
3829 int
3830 peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3831 const char *name)
3832 {
3833 struct bgp_filter *filter;
3834 struct peer_group *group;
3835 struct listnode *node, *nnode;
3836
3837 if (! peer->afc[afi][safi])
3838 return BGP_ERR_PEER_INACTIVE;
3839
3840 if (direct != FILTER_IN && direct != FILTER_OUT)
3841 return BGP_ERR_INVALID_VALUE;
3842
3843 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3844 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3845
3846 filter = &peer->filter[afi][safi];
3847
3848 if (filter->aslist[direct].name)
3849 free (filter->aslist[direct].name);
3850 filter->aslist[direct].name = strdup (name);
3851 filter->aslist[direct].aslist = as_list_lookup (name);
3852
3853 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3854 return 0;
3855
3856 group = peer->group;
3857 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3858 {
3859 filter = &peer->filter[afi][safi];
3860
3861 if (! peer->af_group[afi][safi])
3862 continue;
3863
3864 if (filter->aslist[direct].name)
3865 free (filter->aslist[direct].name);
3866 filter->aslist[direct].name = strdup (name);
3867 filter->aslist[direct].aslist = as_list_lookup (name);
3868 }
3869 return 0;
3870 }
3871
3872 int
3873 peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
3874 {
3875 struct bgp_filter *filter;
3876 struct bgp_filter *gfilter;
3877 struct peer_group *group;
3878 struct listnode *node, *nnode;
3879
3880 if (! peer->afc[afi][safi])
3881 return BGP_ERR_PEER_INACTIVE;
3882
3883 if (direct != FILTER_IN && direct != FILTER_OUT)
3884 return BGP_ERR_INVALID_VALUE;
3885
3886 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3887 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3888
3889 filter = &peer->filter[afi][safi];
3890
3891 /* apply peer-group filter */
3892 if (peer->af_group[afi][safi])
3893 {
3894 gfilter = &peer->group->conf->filter[afi][safi];
3895
3896 if (gfilter->aslist[direct].name)
3897 {
3898 if (filter->aslist[direct].name)
3899 free (filter->aslist[direct].name);
3900 filter->aslist[direct].name = strdup (gfilter->aslist[direct].name);
3901 filter->aslist[direct].aslist = gfilter->aslist[direct].aslist;
3902 return 0;
3903 }
3904 }
3905
3906 if (filter->aslist[direct].name)
3907 free (filter->aslist[direct].name);
3908 filter->aslist[direct].name = NULL;
3909 filter->aslist[direct].aslist = NULL;
3910
3911 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3912 return 0;
3913
3914 group = peer->group;
3915 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3916 {
3917 filter = &peer->filter[afi][safi];
3918
3919 if (! peer->af_group[afi][safi])
3920 continue;
3921
3922 if (filter->aslist[direct].name)
3923 free (filter->aslist[direct].name);
3924 filter->aslist[direct].name = NULL;
3925 filter->aslist[direct].aslist = NULL;
3926 }
3927
3928 return 0;
3929 }
3930
3931 static void
3932 peer_aslist_update ()
3933 {
3934 afi_t afi;
3935 safi_t safi;
3936 int direct;
3937 struct listnode *mnode, *mnnode;
3938 struct listnode *node, *nnode;
3939 struct bgp *bgp;
3940 struct peer *peer;
3941 struct peer_group *group;
3942 struct bgp_filter *filter;
3943
3944 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3945 {
3946 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3947 {
3948 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3949 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3950 {
3951 filter = &peer->filter[afi][safi];
3952
3953 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3954 {
3955 if (filter->aslist[direct].name)
3956 filter->aslist[direct].aslist =
3957 as_list_lookup (filter->aslist[direct].name);
3958 else
3959 filter->aslist[direct].aslist = NULL;
3960 }
3961 }
3962 }
3963 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3964 {
3965 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3966 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3967 {
3968 filter = &group->conf->filter[afi][safi];
3969
3970 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3971 {
3972 if (filter->aslist[direct].name)
3973 filter->aslist[direct].aslist =
3974 as_list_lookup (filter->aslist[direct].name);
3975 else
3976 filter->aslist[direct].aslist = NULL;
3977 }
3978 }
3979 }
3980 }
3981 }
3982 \f
3983 /* Set route-map to the peer. */
3984 int
3985 peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3986 const char *name)
3987 {
3988 struct bgp_filter *filter;
3989 struct peer_group *group;
3990 struct listnode *node, *nnode;
3991
3992 if (! peer->afc[afi][safi])
3993 return BGP_ERR_PEER_INACTIVE;
3994
3995 if (direct != RMAP_IN && direct != RMAP_OUT &&
3996 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
3997 return BGP_ERR_INVALID_VALUE;
3998
3999 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4000 && peer_is_group_member (peer, afi, safi))
4001 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4002
4003 filter = &peer->filter[afi][safi];
4004
4005 if (filter->map[direct].name)
4006 free (filter->map[direct].name);
4007
4008 filter->map[direct].name = strdup (name);
4009 filter->map[direct].map = route_map_lookup_by_name (name);
4010
4011 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4012 return 0;
4013
4014 group = peer->group;
4015 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4016 {
4017 filter = &peer->filter[afi][safi];
4018
4019 if (! peer->af_group[afi][safi])
4020 continue;
4021
4022 if (filter->map[direct].name)
4023 free (filter->map[direct].name);
4024 filter->map[direct].name = strdup (name);
4025 filter->map[direct].map = route_map_lookup_by_name (name);
4026 }
4027 return 0;
4028 }
4029
4030 /* Unset route-map from the peer. */
4031 int
4032 peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
4033 {
4034 struct bgp_filter *filter;
4035 struct bgp_filter *gfilter;
4036 struct peer_group *group;
4037 struct listnode *node, *nnode;
4038
4039 if (! peer->afc[afi][safi])
4040 return BGP_ERR_PEER_INACTIVE;
4041
4042 if (direct != RMAP_IN && direct != RMAP_OUT &&
4043 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4044 return BGP_ERR_INVALID_VALUE;
4045
4046 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4047 && peer_is_group_member (peer, afi, safi))
4048 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4049
4050 filter = &peer->filter[afi][safi];
4051
4052 /* apply peer-group filter */
4053 if (peer->af_group[afi][safi])
4054 {
4055 gfilter = &peer->group->conf->filter[afi][safi];
4056
4057 if (gfilter->map[direct].name)
4058 {
4059 if (filter->map[direct].name)
4060 free (filter->map[direct].name);
4061 filter->map[direct].name = strdup (gfilter->map[direct].name);
4062 filter->map[direct].map = gfilter->map[direct].map;
4063 return 0;
4064 }
4065 }
4066
4067 if (filter->map[direct].name)
4068 free (filter->map[direct].name);
4069 filter->map[direct].name = NULL;
4070 filter->map[direct].map = NULL;
4071
4072 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4073 return 0;
4074
4075 group = peer->group;
4076 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4077 {
4078 filter = &peer->filter[afi][safi];
4079
4080 if (! peer->af_group[afi][safi])
4081 continue;
4082
4083 if (filter->map[direct].name)
4084 free (filter->map[direct].name);
4085 filter->map[direct].name = NULL;
4086 filter->map[direct].map = NULL;
4087 }
4088 return 0;
4089 }
4090 \f
4091 /* Set unsuppress-map to the peer. */
4092 int
4093 peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
4094 const char *name)
4095 {
4096 struct bgp_filter *filter;
4097 struct peer_group *group;
4098 struct listnode *node, *nnode;
4099
4100 if (! peer->afc[afi][safi])
4101 return BGP_ERR_PEER_INACTIVE;
4102
4103 if (peer_is_group_member (peer, afi, safi))
4104 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4105
4106 filter = &peer->filter[afi][safi];
4107
4108 if (filter->usmap.name)
4109 free (filter->usmap.name);
4110
4111 filter->usmap.name = strdup (name);
4112 filter->usmap.map = route_map_lookup_by_name (name);
4113
4114 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4115 return 0;
4116
4117 group = peer->group;
4118 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4119 {
4120 filter = &peer->filter[afi][safi];
4121
4122 if (! peer->af_group[afi][safi])
4123 continue;
4124
4125 if (filter->usmap.name)
4126 free (filter->usmap.name);
4127 filter->usmap.name = strdup (name);
4128 filter->usmap.map = route_map_lookup_by_name (name);
4129 }
4130 return 0;
4131 }
4132
4133 /* Unset route-map from the peer. */
4134 int
4135 peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
4136 {
4137 struct bgp_filter *filter;
4138 struct peer_group *group;
4139 struct listnode *node, *nnode;
4140
4141 if (! peer->afc[afi][safi])
4142 return BGP_ERR_PEER_INACTIVE;
4143
4144 if (peer_is_group_member (peer, afi, safi))
4145 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4146
4147 filter = &peer->filter[afi][safi];
4148
4149 if (filter->usmap.name)
4150 free (filter->usmap.name);
4151 filter->usmap.name = NULL;
4152 filter->usmap.map = NULL;
4153
4154 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4155 return 0;
4156
4157 group = peer->group;
4158 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4159 {
4160 filter = &peer->filter[afi][safi];
4161
4162 if (! peer->af_group[afi][safi])
4163 continue;
4164
4165 if (filter->usmap.name)
4166 free (filter->usmap.name);
4167 filter->usmap.name = NULL;
4168 filter->usmap.map = NULL;
4169 }
4170 return 0;
4171 }
4172 \f
4173 int
4174 peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
4175 u_int32_t max, u_char threshold,
4176 int warning, u_int16_t restart)
4177 {
4178 struct peer_group *group;
4179 struct listnode *node, *nnode;
4180
4181 if (! peer->afc[afi][safi])
4182 return BGP_ERR_PEER_INACTIVE;
4183
4184 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4185 peer->pmax[afi][safi] = max;
4186 peer->pmax_threshold[afi][safi] = threshold;
4187 peer->pmax_restart[afi][safi] = restart;
4188 if (warning)
4189 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4190 else
4191 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4192
4193 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4194 return 0;
4195
4196 group = peer->group;
4197 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4198 {
4199 if (! peer->af_group[afi][safi])
4200 continue;
4201
4202 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4203 peer->pmax[afi][safi] = max;
4204 peer->pmax_threshold[afi][safi] = threshold;
4205 peer->pmax_restart[afi][safi] = restart;
4206 if (warning)
4207 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4208 else
4209 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4210 }
4211 return 0;
4212 }
4213
4214 int
4215 peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
4216 {
4217 struct peer_group *group;
4218 struct listnode *node, *nnode;
4219
4220 if (! peer->afc[afi][safi])
4221 return BGP_ERR_PEER_INACTIVE;
4222
4223 /* apply peer-group config */
4224 if (peer->af_group[afi][safi])
4225 {
4226 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4227 PEER_FLAG_MAX_PREFIX))
4228 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4229 else
4230 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4231
4232 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4233 PEER_FLAG_MAX_PREFIX_WARNING))
4234 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4235 else
4236 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4237
4238 peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
4239 peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
4240 peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
4241 return 0;
4242 }
4243
4244 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4245 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4246 peer->pmax[afi][safi] = 0;
4247 peer->pmax_threshold[afi][safi] = 0;
4248 peer->pmax_restart[afi][safi] = 0;
4249
4250 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4251 return 0;
4252
4253 group = peer->group;
4254 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4255 {
4256 if (! peer->af_group[afi][safi])
4257 continue;
4258
4259 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4260 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4261 peer->pmax[afi][safi] = 0;
4262 peer->pmax_threshold[afi][safi] = 0;
4263 peer->pmax_restart[afi][safi] = 0;
4264 }
4265 return 0;
4266 }
4267 \f
4268 int
4269 peer_clear (struct peer *peer)
4270 {
4271 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4272 {
4273 if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4274 {
4275 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4276 if (peer->t_pmax_restart)
4277 {
4278 BGP_TIMER_OFF (peer->t_pmax_restart);
4279 if (BGP_DEBUG (events, EVENTS))
4280 zlog_debug ("%s Maximum-prefix restart timer canceled",
4281 peer->host);
4282 }
4283 BGP_EVENT_ADD (peer, BGP_Start);
4284 return 0;
4285 }
4286
4287 peer->v_start = BGP_INIT_START_TIMER;
4288 if (peer->status == Established)
4289 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
4290 BGP_NOTIFY_CEASE_ADMIN_RESET);
4291 else
4292 BGP_EVENT_ADD (peer, BGP_Stop);
4293 }
4294 return 0;
4295 }
4296
4297 int
4298 peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
4299 enum bgp_clear_type stype)
4300 {
4301 if (peer->status != Established)
4302 return 0;
4303
4304 if (! peer->afc[afi][safi])
4305 return BGP_ERR_AF_UNCONFIGURED;
4306
4307 if (stype == BGP_CLEAR_SOFT_RSCLIENT)
4308 {
4309 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
4310 return 0;
4311 bgp_check_local_routes_rsclient (peer, afi, safi);
4312 bgp_soft_reconfig_rsclient (peer, afi, safi);
4313 }
4314
4315 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
4316 bgp_announce_route (peer, afi, safi);
4317
4318 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4319 {
4320 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)
4321 && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
4322 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
4323 {
4324 struct bgp_filter *filter = &peer->filter[afi][safi];
4325 u_char prefix_type;
4326
4327 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
4328 prefix_type = ORF_TYPE_PREFIX;
4329 else
4330 prefix_type = ORF_TYPE_PREFIX_OLD;
4331
4332 if (filter->plist[FILTER_IN].plist)
4333 {
4334 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4335 bgp_route_refresh_send (peer, afi, safi,
4336 prefix_type, REFRESH_DEFER, 1);
4337 bgp_route_refresh_send (peer, afi, safi, prefix_type,
4338 REFRESH_IMMEDIATE, 0);
4339 }
4340 else
4341 {
4342 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4343 bgp_route_refresh_send (peer, afi, safi,
4344 prefix_type, REFRESH_IMMEDIATE, 1);
4345 else
4346 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4347 }
4348 return 0;
4349 }
4350 }
4351
4352 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
4353 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4354 {
4355 /* If neighbor has soft reconfiguration inbound flag.
4356 Use Adj-RIB-In database. */
4357 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4358 bgp_soft_reconfig_in (peer, afi, safi);
4359 else
4360 {
4361 /* If neighbor has route refresh capability, send route refresh
4362 message to the peer. */
4363 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4364 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4365 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4366 else
4367 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
4368 }
4369 }
4370 return 0;
4371 }
4372 \f
4373 /* Display peer uptime.*/
4374 /* XXX: why does this function return char * when it takes buffer? */
4375 char *
4376 peer_uptime (time_t uptime2, char *buf, size_t len)
4377 {
4378 time_t uptime1;
4379 struct tm *tm;
4380
4381 /* Check buffer length. */
4382 if (len < BGP_UPTIME_LEN)
4383 {
4384 zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
4385 /* XXX: should return status instead of buf... */
4386 snprintf (buf, len, "<error> ");
4387 return buf;
4388 }
4389
4390 /* If there is no connection has been done before print `never'. */
4391 if (uptime2 == 0)
4392 {
4393 snprintf (buf, len, "never ");
4394 return buf;
4395 }
4396
4397 /* Get current time. */
4398 uptime1 = time (NULL);
4399 uptime1 -= uptime2;
4400 tm = gmtime (&uptime1);
4401
4402 /* Making formatted timer strings. */
4403 #define ONE_DAY_SECOND 60*60*24
4404 #define ONE_WEEK_SECOND 60*60*24*7
4405
4406 if (uptime1 < ONE_DAY_SECOND)
4407 snprintf (buf, len, "%02d:%02d:%02d",
4408 tm->tm_hour, tm->tm_min, tm->tm_sec);
4409 else if (uptime1 < ONE_WEEK_SECOND)
4410 snprintf (buf, len, "%dd%02dh%02dm",
4411 tm->tm_yday, tm->tm_hour, tm->tm_min);
4412 else
4413 snprintf (buf, len, "%02dw%dd%02dh",
4414 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
4415 return buf;
4416 }
4417 \f
4418 static void
4419 bgp_config_write_filter (struct vty *vty, struct peer *peer,
4420 afi_t afi, safi_t safi)
4421 {
4422 struct bgp_filter *filter;
4423 struct bgp_filter *gfilter = NULL;
4424 char *addr;
4425 int in = FILTER_IN;
4426 int out = FILTER_OUT;
4427
4428 addr = peer->host;
4429 filter = &peer->filter[afi][safi];
4430 if (peer->af_group[afi][safi])
4431 gfilter = &peer->group->conf->filter[afi][safi];
4432
4433 /* distribute-list. */
4434 if (filter->dlist[in].name)
4435 if (! gfilter || ! gfilter->dlist[in].name
4436 || strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
4437 vty_out (vty, " neighbor %s distribute-list %s in%s", addr,
4438 filter->dlist[in].name, VTY_NEWLINE);
4439 if (filter->dlist[out].name && ! gfilter)
4440 vty_out (vty, " neighbor %s distribute-list %s out%s", addr,
4441 filter->dlist[out].name, VTY_NEWLINE);
4442
4443 /* prefix-list. */
4444 if (filter->plist[in].name)
4445 if (! gfilter || ! gfilter->plist[in].name
4446 || strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
4447 vty_out (vty, " neighbor %s prefix-list %s in%s", addr,
4448 filter->plist[in].name, VTY_NEWLINE);
4449 if (filter->plist[out].name && ! gfilter)
4450 vty_out (vty, " neighbor %s prefix-list %s out%s", addr,
4451 filter->plist[out].name, VTY_NEWLINE);
4452
4453 /* route-map. */
4454 if (filter->map[RMAP_IN].name)
4455 if (! gfilter || ! gfilter->map[RMAP_IN].name
4456 || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
4457 vty_out (vty, " neighbor %s route-map %s in%s", addr,
4458 filter->map[RMAP_IN].name, VTY_NEWLINE);
4459 if (filter->map[RMAP_OUT].name && ! gfilter)
4460 vty_out (vty, " neighbor %s route-map %s out%s", addr,
4461 filter->map[RMAP_OUT].name, VTY_NEWLINE);
4462 if (filter->map[RMAP_IMPORT].name && ! gfilter)
4463 vty_out (vty, " neighbor %s route-map %s import%s", addr,
4464 filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
4465 if (filter->map[RMAP_EXPORT].name)
4466 if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
4467 || strcmp (filter->map[RMAP_EXPORT].name,
4468 gfilter->map[RMAP_EXPORT].name) != 0)
4469 vty_out (vty, " neighbor %s route-map %s export%s", addr,
4470 filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
4471
4472 /* unsuppress-map */
4473 if (filter->usmap.name && ! gfilter)
4474 vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
4475 filter->usmap.name, VTY_NEWLINE);
4476
4477 /* filter-list. */
4478 if (filter->aslist[in].name)
4479 if (! gfilter || ! gfilter->aslist[in].name
4480 || strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
4481 vty_out (vty, " neighbor %s filter-list %s in%s", addr,
4482 filter->aslist[in].name, VTY_NEWLINE);
4483 if (filter->aslist[out].name && ! gfilter)
4484 vty_out (vty, " neighbor %s filter-list %s out%s", addr,
4485 filter->aslist[out].name, VTY_NEWLINE);
4486 }
4487
4488 /* BGP peer configuration display function. */
4489 static void
4490 bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
4491 struct peer *peer, afi_t afi, safi_t safi)
4492 {
4493 struct bgp_filter *filter;
4494 struct peer *g_peer = NULL;
4495 char buf[SU_ADDRSTRLEN];
4496 char *addr;
4497
4498 filter = &peer->filter[afi][safi];
4499 addr = peer->host;
4500 if (peer_group_active (peer))
4501 g_peer = peer->group->conf;
4502
4503 /************************************
4504 ****** Global to the neighbor ******
4505 ************************************/
4506 if (afi == AFI_IP && safi == SAFI_UNICAST)
4507 {
4508 /* remote-as. */
4509 if (! peer_group_active (peer))
4510 {
4511 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4512 vty_out (vty, " neighbor %s peer-group%s", addr,
4513 VTY_NEWLINE);
4514 if (peer->as)
4515 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4516 VTY_NEWLINE);
4517 }
4518 else
4519 {
4520 if (! g_peer->as)
4521 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4522 VTY_NEWLINE);
4523 if (peer->af_group[AFI_IP][SAFI_UNICAST])
4524 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4525 peer->group->name, VTY_NEWLINE);
4526 }
4527
4528 /* local-as. */
4529 if (peer->change_local_as)
4530 if (! peer_group_active (peer))
4531 vty_out (vty, " neighbor %s local-as %u%s%s", addr,
4532 peer->change_local_as,
4533 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
4534 " no-prepend" : "", VTY_NEWLINE);
4535
4536 /* Description. */
4537 if (peer->desc)
4538 vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
4539 VTY_NEWLINE);
4540
4541 /* Shutdown. */
4542 if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4543 if (! peer_group_active (peer) ||
4544 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
4545 vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
4546
4547 /* Password. */
4548 if (peer->password)
4549 if (!peer_group_active (peer)
4550 || ! g_peer->password
4551 || strcmp (peer->password, g_peer->password) != 0)
4552 vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
4553 VTY_NEWLINE);
4554
4555 /* BGP port. */
4556 if (peer->port != BGP_PORT_DEFAULT)
4557 vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
4558 VTY_NEWLINE);
4559
4560 /* Local interface name. */
4561 if (peer->ifname)
4562 vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
4563 VTY_NEWLINE);
4564
4565 /* Passive. */
4566 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
4567 if (! peer_group_active (peer) ||
4568 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
4569 vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
4570
4571 /* EBGP multihop. */
4572 if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
4573 if (! peer_group_active (peer) ||
4574 g_peer->ttl != peer->ttl)
4575 vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
4576 VTY_NEWLINE);
4577
4578 /* disable-connected-check. */
4579 if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4580 if (! peer_group_active (peer) ||
4581 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4582 vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
4583
4584 /* Update-source. */
4585 if (peer->update_if)
4586 if (! peer_group_active (peer) || ! g_peer->update_if
4587 || strcmp (g_peer->update_if, peer->update_if) != 0)
4588 vty_out (vty, " neighbor %s update-source %s%s", addr,
4589 peer->update_if, VTY_NEWLINE);
4590 if (peer->update_source)
4591 if (! peer_group_active (peer) || ! g_peer->update_source
4592 || sockunion_cmp (g_peer->update_source,
4593 peer->update_source) != 0)
4594 vty_out (vty, " neighbor %s update-source %s%s", addr,
4595 sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN),
4596 VTY_NEWLINE);
4597
4598 /* advertisement-interval */
4599 if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV))
4600 vty_out (vty, " neighbor %s advertisement-interval %d%s",
4601 addr, peer->v_routeadv, VTY_NEWLINE);
4602
4603 /* timers. */
4604 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
4605 && ! peer_group_active (peer))
4606 vty_out (vty, " neighbor %s timers %d %d%s", addr,
4607 peer->keepalive, peer->holdtime, VTY_NEWLINE);
4608
4609 if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT))
4610 vty_out (vty, " neighbor %s timers connect %d%s", addr,
4611 peer->connect, VTY_NEWLINE);
4612
4613 /* Default weight. */
4614 if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
4615 if (! peer_group_active (peer) ||
4616 g_peer->weight != peer->weight)
4617 vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
4618 VTY_NEWLINE);
4619
4620 /* Dynamic capability. */
4621 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
4622 if (! peer_group_active (peer) ||
4623 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
4624 vty_out (vty, " neighbor %s capability dynamic%s", addr,
4625 VTY_NEWLINE);
4626
4627 /* dont capability negotiation. */
4628 if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
4629 if (! peer_group_active (peer) ||
4630 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
4631 vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
4632 VTY_NEWLINE);
4633
4634 /* override capability negotiation. */
4635 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
4636 if (! peer_group_active (peer) ||
4637 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
4638 vty_out (vty, " neighbor %s override-capability%s", addr,
4639 VTY_NEWLINE);
4640
4641 /* strict capability negotiation. */
4642 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
4643 if (! peer_group_active (peer) ||
4644 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
4645 vty_out (vty, " neighbor %s strict-capability-match%s", addr,
4646 VTY_NEWLINE);
4647
4648 if (! peer_group_active (peer))
4649 {
4650 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
4651 {
4652 if (peer->afc[AFI_IP][SAFI_UNICAST])
4653 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4654 }
4655 else
4656 {
4657 if (! peer->afc[AFI_IP][SAFI_UNICAST])
4658 vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
4659 }
4660 }
4661 }
4662
4663
4664 /************************************
4665 ****** Per AF to the neighbor ******
4666 ************************************/
4667
4668 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
4669 {
4670 if (peer->af_group[afi][safi])
4671 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4672 peer->group->name, VTY_NEWLINE);
4673 else
4674 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4675 }
4676
4677 /* ORF capability. */
4678 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
4679 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
4680 if (! peer->af_group[afi][safi])
4681 {
4682 vty_out (vty, " neighbor %s capability orf prefix-list", addr);
4683
4684 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
4685 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
4686 vty_out (vty, " both");
4687 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
4688 vty_out (vty, " send");
4689 else
4690 vty_out (vty, " receive");
4691 vty_out (vty, "%s", VTY_NEWLINE);
4692 }
4693
4694 /* Route reflector client. */
4695 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
4696 && ! peer->af_group[afi][safi])
4697 vty_out (vty, " neighbor %s route-reflector-client%s", addr,
4698 VTY_NEWLINE);
4699
4700 /* Nexthop self. */
4701 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
4702 && ! peer->af_group[afi][safi])
4703 vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
4704
4705 /* Remove private AS. */
4706 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
4707 && ! peer->af_group[afi][safi])
4708 vty_out (vty, " neighbor %s remove-private-AS%s",
4709 addr, VTY_NEWLINE);
4710
4711 /* send-community print. */
4712 if (! peer->af_group[afi][safi])
4713 {
4714 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4715 {
4716 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
4717 && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4718 vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE);
4719 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4720 vty_out (vty, " neighbor %s send-community extended%s",
4721 addr, VTY_NEWLINE);
4722 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
4723 vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
4724 }
4725 else
4726 {
4727 if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
4728 && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4729 vty_out (vty, " no neighbor %s send-community both%s",
4730 addr, VTY_NEWLINE);
4731 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4732 vty_out (vty, " no neighbor %s send-community extended%s",
4733 addr, VTY_NEWLINE);
4734 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
4735 vty_out (vty, " no neighbor %s send-community%s",
4736 addr, VTY_NEWLINE);
4737 }
4738 }
4739
4740 /* Default information */
4741 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
4742 && ! peer->af_group[afi][safi])
4743 {
4744 vty_out (vty, " neighbor %s default-originate", addr);
4745 if (peer->default_rmap[afi][safi].name)
4746 vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
4747 vty_out (vty, "%s", VTY_NEWLINE);
4748 }
4749
4750 /* Soft reconfiguration inbound. */
4751 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4752 if (! peer->af_group[afi][safi] ||
4753 ! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4754 vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
4755 VTY_NEWLINE);
4756
4757 /* maximum-prefix. */
4758 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
4759 if (! peer->af_group[afi][safi]
4760 || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
4761 || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
4762 || CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
4763 != CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
4764 {
4765 vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
4766 if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
4767 vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
4768 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
4769 vty_out (vty, " warning-only");
4770 if (peer->pmax_restart[afi][safi])
4771 vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]);
4772 vty_out (vty, "%s", VTY_NEWLINE);
4773 }
4774
4775 /* Route server client. */
4776 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
4777 && ! peer->af_group[afi][safi])
4778 vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
4779
4780 /* Allow AS in. */
4781 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
4782 if (! peer_group_active (peer)
4783 || ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
4784 || peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
4785 {
4786 if (peer->allowas_in[afi][safi] == 3)
4787 vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
4788 else
4789 vty_out (vty, " neighbor %s allowas-in %d%s", addr,
4790 peer->allowas_in[afi][safi], VTY_NEWLINE);
4791 }
4792
4793 /* Filter. */
4794 bgp_config_write_filter (vty, peer, afi, safi);
4795
4796 /* atribute-unchanged. */
4797 if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
4798 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
4799 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
4800 && ! peer->af_group[afi][safi])
4801 {
4802 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
4803 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
4804 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
4805 vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE);
4806 else
4807 vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr,
4808 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ?
4809 " as-path" : "",
4810 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ?
4811 " next-hop" : "",
4812 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
4813 " med" : "", VTY_NEWLINE);
4814 }
4815 }
4816
4817 /* Display "address-family" configuration header. */
4818 void
4819 bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
4820 int *write)
4821 {
4822 if (*write)
4823 return;
4824
4825 if (afi == AFI_IP && safi == SAFI_UNICAST)
4826 return;
4827
4828 vty_out (vty, "!%s address-family ", VTY_NEWLINE);
4829
4830 if (afi == AFI_IP)
4831 {
4832 if (safi == SAFI_MULTICAST)
4833 vty_out (vty, "ipv4 multicast");
4834 else if (safi == SAFI_MPLS_VPN)
4835 vty_out (vty, "vpnv4 unicast");
4836 }
4837 else if (afi == AFI_IP6)
4838 {
4839 vty_out (vty, "ipv6");
4840
4841 if (safi == SAFI_MULTICAST)
4842 vty_out (vty, " multicast");
4843 }
4844
4845 vty_out (vty, "%s", VTY_NEWLINE);
4846
4847 *write = 1;
4848 }
4849
4850 /* Address family based peer configuration display. */
4851 static int
4852 bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
4853 safi_t safi)
4854 {
4855 int write = 0;
4856 struct peer *peer;
4857 struct peer_group *group;
4858 struct listnode *node, *nnode;
4859
4860 bgp_config_write_network (vty, bgp, afi, safi, &write);
4861
4862 bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
4863
4864 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4865 {
4866 if (group->conf->afc[afi][safi])
4867 {
4868 bgp_config_write_family_header (vty, afi, safi, &write);
4869 bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
4870 }
4871 }
4872 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4873 {
4874 if (peer->afc[afi][safi])
4875 {
4876 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
4877 {
4878 bgp_config_write_family_header (vty, afi, safi, &write);
4879 bgp_config_write_peer (vty, bgp, peer, afi, safi);
4880 }
4881 }
4882 }
4883 if (write)
4884 vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
4885
4886 return write;
4887 }
4888
4889 int
4890 bgp_config_write (struct vty *vty)
4891 {
4892 int write = 0;
4893 struct bgp *bgp;
4894 struct peer_group *group;
4895 struct peer *peer;
4896 struct listnode *node, *nnode;
4897 struct listnode *mnode, *mnnode;
4898
4899 /* BGP Multiple instance. */
4900 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
4901 {
4902 vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE);
4903 write++;
4904 }
4905
4906 /* BGP Config type. */
4907 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4908 {
4909 vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE);
4910 write++;
4911 }
4912
4913 /* BGP configuration. */
4914 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4915 {
4916 if (write)
4917 vty_out (vty, "!%s", VTY_NEWLINE);
4918
4919 /* Router bgp ASN */
4920 vty_out (vty, "router bgp %u", bgp->as);
4921
4922 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
4923 {
4924 if (bgp->name)
4925 vty_out (vty, " view %s", bgp->name);
4926 }
4927 vty_out (vty, "%s", VTY_NEWLINE);
4928
4929 /* No Synchronization */
4930 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4931 vty_out (vty, " no synchronization%s", VTY_NEWLINE);
4932
4933 /* BGP fast-external-failover. */
4934 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
4935 vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE);
4936
4937 /* BGP router ID. */
4938 if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID))
4939 vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id),
4940 VTY_NEWLINE);
4941
4942 /* BGP log-neighbor-changes. */
4943 if (bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
4944 vty_out (vty, " bgp log-neighbor-changes%s", VTY_NEWLINE);
4945
4946 /* BGP configuration. */
4947 if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
4948 vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
4949
4950 /* BGP default ipv4-unicast. */
4951 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
4952 vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE);
4953
4954 /* BGP default local-preference. */
4955 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
4956 vty_out (vty, " bgp default local-preference %d%s",
4957 bgp->default_local_pref, VTY_NEWLINE);
4958
4959 /* BGP client-to-client reflection. */
4960 if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
4961 vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE);
4962
4963 /* BGP cluster ID. */
4964 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID))
4965 vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id),
4966 VTY_NEWLINE);
4967
4968 /* Confederation identifier*/
4969 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
4970 vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
4971 VTY_NEWLINE);
4972
4973 /* Confederation peer */
4974 if (bgp->confed_peers_cnt > 0)
4975 {
4976 int i;
4977
4978 vty_out (vty, " bgp confederation peers");
4979
4980 for (i = 0; i < bgp->confed_peers_cnt; i++)
4981 vty_out(vty, " %u", bgp->confed_peers[i]);
4982
4983 vty_out (vty, "%s", VTY_NEWLINE);
4984 }
4985
4986 /* BGP enforce-first-as. */
4987 if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
4988 vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE);
4989
4990 /* BGP deterministic-med. */
4991 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
4992 vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
4993
4994 /* BGP graceful-restart. */
4995 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
4996 vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
4997 bgp->stalepath_time, VTY_NEWLINE);
4998 if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
4999 vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
5000
5001 /* BGP bestpath method. */
5002 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
5003 vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
5004 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
5005 vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
5006 if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
5007 vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
5008 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
5009 || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5010 {
5011 vty_out (vty, " bgp bestpath med");
5012 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED))
5013 vty_out (vty, " confed");
5014 if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5015 vty_out (vty, " missing-as-worst");
5016 vty_out (vty, "%s", VTY_NEWLINE);
5017 }
5018
5019 /* BGP network import check. */
5020 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
5021 vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
5022
5023 /* BGP scan interval. */
5024 bgp_config_write_scan_time (vty);
5025
5026 /* BGP flag dampening. */
5027 if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
5028 BGP_CONFIG_DAMPENING))
5029 bgp_config_write_damp (vty);
5030
5031 /* BGP static route configuration. */
5032 bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5033
5034 /* BGP redistribute configuration. */
5035 bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5036
5037 /* BGP timers configuration. */
5038 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
5039 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
5040 vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive,
5041 bgp->default_holdtime, VTY_NEWLINE);
5042
5043 /* peer-group */
5044 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5045 {
5046 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
5047 }
5048
5049 /* Normal neighbor configuration. */
5050 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5051 {
5052 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5053 bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
5054 }
5055
5056 /* Distance configuration. */
5057 bgp_config_write_distance (vty, bgp);
5058
5059 /* No auto-summary */
5060 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5061 vty_out (vty, " no auto-summary%s", VTY_NEWLINE);
5062
5063 /* IPv4 multicast configuration. */
5064 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
5065
5066 /* IPv4 VPN configuration. */
5067 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
5068
5069 /* IPv6 unicast configuration. */
5070 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
5071
5072 /* IPv6 multicast configuration. */
5073 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
5074
5075 write++;
5076 }
5077 return write;
5078 }
5079
5080 void
5081 bgp_master_init (void)
5082 {
5083 memset (&bgp_master, 0, sizeof (struct bgp_master));
5084
5085 bm = &bgp_master;
5086 bm->bgp = list_new ();
5087 bm->listen_sockets = list_new ();
5088 bm->port = BGP_PORT_DEFAULT;
5089 bm->master = thread_master_create ();
5090 bm->start_time = time (NULL);
5091 }
5092
5093 \f
5094 void
5095 bgp_init (void)
5096 {
5097 /* BGP VTY commands installation. */
5098 bgp_vty_init ();
5099
5100 /* Create BGP server socket. */
5101 bgp_socket (NULL, bm->port, bm->address);
5102
5103 /* Init zebra. */
5104 bgp_zebra_init ();
5105
5106 /* BGP inits. */
5107 bgp_attr_init ();
5108 bgp_debug_init ();
5109 bgp_dump_init ();
5110 bgp_route_init ();
5111 bgp_route_map_init ();
5112 bgp_scan_init ();
5113 bgp_mplsvpn_init ();
5114
5115 /* Access list initialize. */
5116 access_list_init ();
5117 access_list_add_hook (peer_distribute_update);
5118 access_list_delete_hook (peer_distribute_update);
5119
5120 /* Filter list initialize. */
5121 bgp_filter_init ();
5122 as_list_add_hook (peer_aslist_update);
5123 as_list_delete_hook (peer_aslist_update);
5124
5125 /* Prefix list initialize.*/
5126 prefix_list_init ();
5127 prefix_list_add_hook (peer_prefix_list_update);
5128 prefix_list_delete_hook (peer_prefix_list_update);
5129
5130 /* Community list initialize. */
5131 bgp_clist = community_list_init ();
5132
5133 #ifdef HAVE_SNMP
5134 bgp_snmp_init ();
5135 #endif /* HAVE_SNMP */
5136 }
5137
5138 void
5139 bgp_terminate ()
5140 {
5141 struct bgp *bgp;
5142 struct peer *peer;
5143 struct listnode *node, *nnode;
5144 struct listnode *mnode, *mnnode;
5145
5146 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5147 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5148 if (peer->status == Established)
5149 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
5150 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
5151
5152 bgp_cleanup_routes ();
5153
5154 if (bm->process_main_queue)
5155 {
5156 work_queue_free (bm->process_main_queue);
5157 bm->process_main_queue = NULL;
5158 }
5159 if (bm->process_rsclient_queue)
5160 {
5161 work_queue_free (bm->process_rsclient_queue);
5162 bm->process_rsclient_queue = NULL;
5163 }
5164 }