]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgpd.c
[bgpd] Make declarations match
[mirror_frr.git] / bgpd / bgpd.c
CommitLineData
718e3744 1/* BGP-4, BGP-4+ daemon program
2 Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-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"
200df115 37#include "workqueue.h"
718e3744 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. */
65static struct bgp_master bgp_master;
66
18a6dce6 67extern struct in_addr router_id_zebra;
68
718e3744 69/* BGP process wide configuration pointer to export. */
70struct bgp_master *bm;
71
72/* BGP community-list. */
73struct community_list_handler *bgp_clist;
74\f
75/* BGP global flag manipulation. */
76int
77bgp_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;
718e3744 88 }
89 return 0;
90}
91
92int
93bgp_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;
718e3744 107 }
108 return 0;
109}
110
111int
112bgp_option_check (int flag)
113{
114 return CHECK_FLAG (bm->options, flag);
115}
116\f
117/* BGP flag manipulation. */
118int
119bgp_flag_set (struct bgp *bgp, int flag)
120{
121 SET_FLAG (bgp->flags, flag);
122 return 0;
123}
124
125int
126bgp_flag_unset (struct bgp *bgp, int flag)
127{
128 UNSET_FLAG (bgp->flags, flag);
129 return 0;
130}
131
132int
133bgp_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. */
139static void
140bgp_config_set (struct bgp *bgp, int config)
141{
142 SET_FLAG (bgp->config, config);
143}
144
145static void
146bgp_config_unset (struct bgp *bgp, int config)
147{
148 UNSET_FLAG (bgp->config, config);
149}
150
151static int
152bgp_config_check (struct bgp *bgp, int config)
153{
154 return CHECK_FLAG (bgp->config, config);
155}
156\f
157/* Set BGP router identifier. */
158int
159bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
160{
161 struct peer *peer;
1eb8ef25 162 struct listnode *node, *nnode;
718e3744 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. */
1eb8ef25 172 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 173 {
174 IPV4_ADDR_COPY (&peer->local_id, id);
175
176 if (peer->status == Established)
e0701b79 177 {
178 peer->last_reset = PEER_DOWN_RID_CHANGE;
179 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
180 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
181 }
718e3744 182 }
183 return 0;
184}
185
718e3744 186/* BGP's cluster-id control. */
187int
188bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
189{
190 struct peer *peer;
1eb8ef25 191 struct listnode *node, *nnode;
718e3744 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. */
1eb8ef25 201 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 202 {
203 if (peer_sort (peer) != BGP_PEER_IBGP)
204 continue;
205
206 if (peer->status == Established)
e0701b79 207 {
208 peer->last_reset = PEER_DOWN_CLID_CHANGE;
209 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
210 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
211 }
718e3744 212 }
213 return 0;
214}
215
216int
217bgp_cluster_id_unset (struct bgp *bgp)
218{
219 struct peer *peer;
1eb8ef25 220 struct listnode *node, *nnode;
718e3744 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. */
1eb8ef25 229 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 230 {
231 if (peer_sort (peer) != BGP_PEER_IBGP)
232 continue;
233
234 if (peer->status == Established)
e0701b79 235 {
236 peer->last_reset = PEER_DOWN_CLID_CHANGE;
237 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
238 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
239 }
718e3744 240 }
241 return 0;
242}
243\f
244/* BGP timer configuration. */
245int
246bgp_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
255int
256bgp_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. */
265int
266bgp_confederation_id_set (struct bgp *bgp, as_t as)
267{
268 struct peer *peer;
1eb8ef25 269 struct listnode *node, *nnode;
718e3744 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. */
1eb8ef25 283 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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)
e0701b79 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
718e3744 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)
e0701b79 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 }
718e3744 318 else
319 BGP_EVENT_ADD (peer, BGP_Stop);
320 }
321 }
322 }
323 return 0;
324}
325
326int
327bgp_confederation_id_unset (struct bgp *bgp)
328{
329 struct peer *peer;
1eb8ef25 330 struct listnode *node, *nnode;
718e3744 331
332 bgp->confed_id = 0;
333 bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
334
1eb8ef25 335 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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)
e0701b79 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
718e3744 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? */
356int
357bgp_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. */
372int
373bgp_confederation_peers_add (struct bgp *bgp, as_t as)
374{
375 struct peer *peer;
1eb8ef25 376 struct listnode *node, *nnode;
718e3744 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 {
1eb8ef25 400 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 401 {
402 if (peer->as == as)
403 {
404 peer->local_as = bgp->as;
405 if (peer->status == Established)
e0701b79 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 }
718e3744 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. */
420int
421bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
422{
423 int i;
424 int j;
425 struct peer *peer;
1eb8ef25 426 struct listnode *node, *nnode;
718e3744 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 {
1eb8ef25 456 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 457 {
458 if (peer->as == as)
459 {
460 peer->local_as = bgp->confed_id;
461 if (peer->status == Established)
e0701b79 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 }
718e3744 467 else
468 BGP_EVENT_ADD (peer, BGP_Stop);
469 }
470 }
471 }
472
473 return 0;
474}
475\f
476/* Local preference configuration. */
477int
478bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
479{
480 if (! bgp)
481 return -1;
482
718e3744 483 bgp->default_local_pref = local_pref;
484
485 return 0;
486}
487
488int
489bgp_default_local_preference_unset (struct bgp *bgp)
490{
491 if (! bgp)
492 return -1;
493
718e3744 494 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
495
496 return 0;
497}
498\f
fee0f4c6 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. */
502int
503peer_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
eb821189 516/* Peer comparison function for sorting. */
718e3744 517static int
518peer_cmp (struct peer *p1, struct peer *p2)
519{
eb821189 520 return sockunion_cmp (&p1->su, &p2->su);
718e3744 521}
522
523int
524peer_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. */
530static void
531peer_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 }
fee0f4c6 557 }
558 for (i = RMAP_IN; i < RMAP_MAX; i++)
559 {
718e3744 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;
e0701b79 602 peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
718e3744 603}
604
605/* peer global config reset */
94f2b392 606static void
718e3744 607peer_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 */
637int
638peer_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
200df115 687static inline void
688peer_free (struct peer *peer)
689{
ca058a30
PJ
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);
9fde6624 698 BGP_EVENT_FLUSH (peer);
ca058a30 699
200df115 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);
a625ca3c
PJ
713
714 if (peer->clear_node_queue)
715 work_queue_free (peer->clear_node_queue);
716
ca058a30 717 bgp_sync_delete (peer);
200df115 718 memset (peer, 0, sizeof (struct peer));
719
720 XFREE (MTYPE_BGP_PEER, peer);
721}
722
723/* increase reference count on a struct peer */
724struct peer *
725peer_lock (struct peer *peer)
726{
727 assert (peer && (peer->lock >= 0));
ca058a30
PJ
728 assert (peer->status != Deleted);
729
200df115 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 */
738struct peer *
739peer_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. */
718e3744 767static struct peer *
6f58544d 768peer_new (struct bgp *bgp)
718e3744 769{
770 afi_t afi;
771 safi_t safi;
772 struct peer *peer;
773 struct servent *sp;
6f58544d
PJ
774
775 /* bgp argument is absolutely required */
776 assert (bgp);
777 if (!bgp)
778 return NULL;
779
718e3744 780 /* Allocate new peer. */
ca058a30 781 peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
718e3744 782
783 /* Set default value. */
eb821189 784 peer->fd = -1;
718e3744 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;
718e3744 790 peer->weight = 0;
0df7c91f 791 peer->password = NULL;
6f58544d 792 peer->bgp = bgp;
ca058a30 793 peer = peer_lock (peer); /* initial reference */
718e3744 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. */
94f2b392 823static struct peer *
718e3744 824peer_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
6f58544d 831 peer = peer_new (bgp);
718e3744 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;
200df115 842
843 peer = peer_lock (peer); /* bgp peer list reference */
718e3744 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
848973c7 854 /* Last reset time set */
855 peer->resettime = time (NULL);
856
718e3744 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);
e83e2080 862 peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
718e3744 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
eb821189 871/* Make accept BGP peer. Called from bgp_accept (). */
872struct peer *
873peer_create_accept (struct bgp *bgp)
874{
875 struct peer *peer;
876
6f58544d 877 peer = peer_new (bgp);
200df115 878
879 peer = peer_lock (peer); /* bgp peer list reference */
eb821189 880 listnode_add_sort (bgp->peer, peer);
881
882 return peer;
883}
884
718e3744 885/* Change peer's AS number. */
94f2b392 886static void
718e3744 887peer_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)
e0701b79 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 }
718e3744 900 else
901 BGP_EVENT_ADD (peer, BGP_Stop);
902 }
903 type = peer_sort (peer);
904 peer->as = as;
905
848973c7 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
718e3744 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. */
950int
951peer_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. */
1018int
1019peer_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
e0701b79 1054 {
1055 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
1056 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1057 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1058 }
718e3744 1059 }
1060 }
1061 }
1062 return 0;
1063}
1064
1065int
1066peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
1067{
1068 struct peer_group *group;
1069 struct peer *peer1;
1eb8ef25 1070 struct listnode *node, *nnode;
718e3744 1071
1072 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1073 {
1074 group = peer->group;
1075
1eb8ef25 1076 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
718e3744 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
e0701b79 1113 {
1114 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1115 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1116 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1117 }
718e3744 1118 }
1119 else
e0701b79 1120 {
1121 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1122 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1123 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1124 }
718e3744 1125 }
1126 }
1127 return 0;
1128}
1129
93406d87 1130void
1131peer_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
ca058a30
PJ
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 */
718e3744 1169int
1170peer_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
ca058a30
PJ
1178 assert (peer->status != Deleted);
1179
718e3744 1180 bgp = peer->bgp;
1181
93406d87 1182 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
1183 peer_nsf_stop (peer);
1184
718e3744 1185 /* If this peer belongs to peer group. Clearn up the
1186 relationship. */
1187 if (peer->group)
1188 {
ca058a30
PJ
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 }
718e3744 1196 peer->group = NULL;
1197 }
200df115 1198
718e3744 1199 /* Withdraw all information from routing table. We can not use
200df115 1200 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
1201 * executed after peer structure is deleted.
1202 */
e0701b79 1203 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
718e3744 1204 bgp_stop (peer);
ca058a30 1205 bgp_fsm_change_status (peer, Deleted);
0df7c91f
PJ
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
ca058a30 1217 bgp_timer_set (peer); /* stops all timers for Deleted */
200df115 1218
718e3744 1219 /* Delete from all peer list. */
1220 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
fee0f4c6 1221 {
ca058a30
PJ
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 }
200df115 1229
ca058a30
PJ
1230 if (peer_rsclient_active (peer)
1231 && (pn = listnode_lookup (bgp->rsclient, peer)))
200df115 1232 {
1233 peer_unlock (peer); /* rsclient list reference */
ca058a30 1234 list_delete_node (bgp->rsclient, pn);
200df115 1235 }
fee0f4c6 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])
b608d5b5 1243 bgp_table_finish (&peer->rib[afi][safi]);
718e3744 1244
200df115 1245 /* Buffers. */
718e3744 1246 if (peer->ibuf)
1247 stream_free (peer->ibuf);
718e3744 1248 if (peer->obuf)
1249 stream_fifo_free (peer->obuf);
718e3744 1250 if (peer->work)
1251 stream_free (peer->work);
18937400
PJ
1252 peer->obuf = NULL;
1253 peer->work = peer->ibuf = NULL;
1254
718e3744 1255 /* Local and remote addresses. */
1256 if (peer->su_local)
22db9dec 1257 sockunion_free (peer->su_local);
718e3744 1258 if (peer->su_remote)
22db9dec 1259 sockunion_free (peer->su_remote);
18937400 1260 peer->su_local = peer->su_remote = NULL;
200df115 1261
718e3744 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);
200df115 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 {
718e3744 1283 if (filter->map[i].name)
1284 free (filter->map[i].name);
200df115 1285 filter->map[i].name = NULL;
718e3744 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);
200df115 1293
1294 filter->usmap.name = NULL;
1295 peer->default_rmap[afi][safi].name = NULL;
718e3744 1296 }
200df115 1297
1298 peer_unlock (peer); /* initial reference */
718e3744 1299
1300 return 0;
1301}
1302\f
94f2b392 1303static int
718e3744 1304peer_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. */
94f2b392 1310static int
718e3744 1311peer_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. */
1323static struct peer_group *
66e5cd87 1324peer_group_new (void)
718e3744 1325{
1326 return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
1327 sizeof (struct peer_group));
1328}
1329
94f2b392 1330static void
718e3744 1331peer_group_free (struct peer_group *group)
1332{
1333 XFREE (MTYPE_PEER_GROUP, group);
1334}
1335
1336struct peer_group *
fd79ac91 1337peer_group_lookup (struct bgp *bgp, const char *name)
718e3744 1338{
1339 struct peer_group *group;
1eb8ef25 1340 struct listnode *node, *nnode;
718e3744 1341
1eb8ef25 1342 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 1343 {
1344 if (strcmp (group->name, name) == 0)
1345 return group;
1346 }
1347 return NULL;
1348}
1349
1350struct peer_group *
fd79ac91 1351peer_group_get (struct bgp *bgp, const char *name)
718e3744 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 ();
6f58544d 1363 group->conf = peer_new (bgp);
718e3744 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);
718e3744 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
94f2b392 1382static void
718e3744 1383peer_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
0df7c91f
PJ
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
718e3744 1443 /* maximum-prefix */
1444 peer->pmax[afi][safi] = conf->pmax[afi][safi];
e0701b79 1445 peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
0a486e5f 1446 peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
718e3744 1447
1448 /* allowas-in */
1449 peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
1450
fee0f4c6 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
718e3744 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 }
fee0f4c6 1534 if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
718e3744 1535 {
fee0f4c6 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;
718e3744 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 }
fee0f4c6 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)
718e3744 1602 {
fee0f4c6 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;
718e3744 1607 }
1608 else
1609 {
fee0f4c6 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;
718e3744 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. */
1640int
fd79ac91 1641peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
718e3744 1642{
1643 struct peer_group *group;
1644 struct peer *peer;
1eb8ef25 1645 struct listnode *node, *nnode;
718e3744 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
1eb8ef25 1658 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 1659 {
1660 if (peer->as != *as)
1661 peer_as_change (peer, *as);
1662 }
1663
1664 return 0;
1665}
1666
1667int
1668peer_group_delete (struct peer_group *group)
1669{
1670 struct bgp *bgp;
1671 struct peer *peer;
1eb8ef25 1672 struct listnode *node, *nnode;
718e3744 1673
1674 bgp = group->bgp;
1675
1eb8ef25 1676 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
1697int
1698peer_group_remote_as_delete (struct peer_group *group)
1699{
1700 struct peer *peer;
1eb8ef25 1701 struct listnode *node, *nnode;
718e3744 1702
1703 if (! group->conf->as)
1704 return 0;
1705
1eb8ef25 1706 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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. */
1719int
1720peer_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;
200df115 1742
ca058a30 1743 peer = peer_lock (peer); /* group->peer list reference */
718e3744 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;
200df115 1783
ca058a30 1784 peer = peer_lock (peer); /* group->peer list reference */
718e3744 1785 listnode_add (group->peer, peer);
1786 }
ca058a30
PJ
1787 else
1788 assert (group && peer->group == group);
718e3744 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 }
fee0f4c6 1809
1810 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1811 {
ca058a30
PJ
1812 struct listnode *pn;
1813
fee0f4c6 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.*/
ca058a30
PJ
1817 if (! peer_rsclient_active (peer)
1818 && (pn = listnode_lookup (bgp->rsclient, peer)))
200df115 1819 {
1820 peer_unlock (peer); /* peer rsclient reference */
ca058a30 1821 list_delete_node (bgp->rsclient, pn);
200df115 1822 }
fee0f4c6 1823
b608d5b5 1824 bgp_table_finish (&peer->rib[afi][safi]);
fee0f4c6 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
718e3744 1844 peer_group2peer_config_copy (group, peer, afi, safi);
1845
1846 if (peer->status == Established)
e0701b79 1847 {
1848 peer->last_reset = PEER_DOWN_RMAP_BIND;
1849 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1850 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1851 }
718e3744 1852 else
1853 BGP_EVENT_ADD (peer, BGP_Stop);
1854
1855 return 0;
1856}
1857
1858int
1859peer_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
fee0f4c6 1872 if (peer->rib[afi][safi])
1873 peer->rib[afi][safi] = NULL;
1874
718e3744 1875 if (! peer_group_active (peer))
1876 {
ca058a30 1877 assert (listnode_lookup (group->peer, peer));
200df115 1878 peer_unlock (peer); /* peer group list reference */
718e3744 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)
e0701b79 1890 {
1891 peer->last_reset = PEER_DOWN_RMAP_UNBIND;
1892 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1893 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1894 }
718e3744 1895 else
1896 BGP_EVENT_ADD (peer, BGP_Stop);
1897
1898 return 0;
1899}
1900\f
1901/* BGP instance creation by `router bgp' commands. */
94f2b392 1902static struct bgp *
fd79ac91 1903bgp_create (as_t *as, const char *name)
718e3744 1904{
1905 struct bgp *bgp;
1906 afi_t afi;
1907 safi_t safi;
1908
200df115 1909 if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
1910 return NULL;
1911
6f58544d 1912 bgp->peer_self = peer_new (bgp);
fd79ac91 1913 bgp->peer_self->host = strdup ("Static announcement");
718e3744 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
fee0f4c6 1921 bgp->rsclient = list_new ();
1922 bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
1923
718e3744 1924 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1925 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1926 {
64e580a7
PJ
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);
718e3744 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;
538621f2 1935 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
1936 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
718e3744 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. */
1947struct bgp *
94f2b392 1948bgp_get_default (void)
718e3744 1949{
1950 if (bm->bgp->head)
1eb8ef25 1951 return (listgetdata (listhead (bm->bgp)));
718e3744 1952 return NULL;
1953}
1954
1955/* Lookup BGP entry. */
1956struct bgp *
fd79ac91 1957bgp_lookup (as_t as, const char *name)
718e3744 1958{
1959 struct bgp *bgp;
1eb8ef25 1960 struct listnode *node, *nnode;
718e3744 1961
1eb8ef25 1962 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
718e3744 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. */
1971struct bgp *
fd79ac91 1972bgp_lookup_by_name (const char *name)
718e3744 1973{
1974 struct bgp *bgp;
1eb8ef25 1975 struct listnode *node, *nnode;
718e3744 1976
1eb8ef25 1977 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
718e3744 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. */
1985int
fd79ac91 1986bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
718e3744 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);
18a6dce6 2033 bgp_router_id_set(bgp, &router_id_zebra);
718e3744 2034 *bgp_val = bgp;
2035
2036 return 0;
2037}
2038
2039/* Delete BGP instance. */
2040int
2041bgp_delete (struct bgp *bgp)
2042{
2043 struct peer *peer;
b6b7cff2 2044 struct peer_group *group;
1eb8ef25 2045 struct listnode *node;
718e3744 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
b6b7cff2 2060 for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
2061 peer_group_delete (group);
54a6ed38 2062 list_delete (bgp->group);
718e3744 2063
1eb8ef25 2064 for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
2065 peer_delete (peer);
54a6ed38 2066 list_delete (bgp->peer);
718e3744 2067
54a6ed38 2068 for (ALL_LIST_ELEMENTS (bgp->rsclient, node, next, peer))
2069 peer_delete (peer);
fee0f4c6 2070 list_delete (bgp->rsclient);
2071
718e3744 2072 listnode_delete (bm->bgp, bgp);
200df115 2073
718e3744 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
2092struct peer *
2093peer_lookup (struct bgp *bgp, union sockunion *su)
2094{
2095 struct peer *peer;
1eb8ef25 2096 struct listnode *node, *nnode;
718e3744 2097
2098 if (! bgp)
2099 bgp = bgp_get_default ();
2100
2101 if (! bgp)
2102 return NULL;
2103
1eb8ef25 2104 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 2105 {
eb821189 2106 if (sockunion_same (&peer->su, su)
2107 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2108 return peer;
718e3744 2109 }
2110 return NULL;
2111}
2112
2113struct peer *
2114peer_lookup_with_open (union sockunion *su, as_t remote_as,
2115 struct in_addr *remote_id, int *as)
2116{
2117 struct peer *peer;
1eb8ef25 2118 struct listnode *node, *nnode;
718e3744 2119 struct bgp *bgp;
2120
2121 bgp = bgp_get_default ();
2122 if (! bgp)
2123 return NULL;
2124
1eb8ef25 2125 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 2126 {
eb821189 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 }
718e3744 2136 }
1eb8ef25 2137 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 2138 {
eb821189 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 }
718e3744 2148 }
2149 return NULL;
2150}
2151\f
2152/* If peer is configured at least one address family return 1. */
2153int
2154peer_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. */
2166int
2167peer_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. */
2179enum peer_change_type
2180{
2181 peer_change_none,
2182 peer_change_reset,
2183 peer_change_reset_in,
2184 peer_change_reset_out,
2185};
2186
94f2b392 2187static void
718e3744 2188peer_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
2210struct 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;
e0701b79 2220
2221 /* Peer down cause */
2222 u_char peer_down;
718e3744 2223};
2224
2225struct 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 },
718e3744 2232 { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
6ffd2079 2233 { PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
718e3744 2234 { 0, 0, 0 }
2235 };
2236
2237struct 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 },
fee0f4c6 2252 { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
718e3744 2253 { 0, 0, 0 }
2254 };
2255
2256/* Proper action set. */
94f2b392 2257static int
718e3744 2258peer_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
94f2b392 2306static void
718e3744 2307peer_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 {
93406d87 2313 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2314 peer_nsf_stop (peer);
2315
0a486e5f 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
93406d87 2325 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2326 peer_nsf_stop (peer);
2327
718e3744 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 {
c9502438 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;
6ffd2079 2346 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
c9502438 2347 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
e0701b79 2348
c9502438 2349 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2350 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
718e3744 2351 }
2352 else
2353 BGP_EVENT_ADD (peer, BGP_Stop);
2354}
2355
2356/* Change specified peer flag. */
94f2b392 2357static int
718e3744 2358peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
2359{
2360 int found;
2361 int size;
2362 struct peer_group *group;
1eb8ef25 2363 struct listnode *node, *nnode;
718e3744 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
1eb8ef25 2420 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
2439int
2440peer_flag_set (struct peer *peer, u_int32_t flag)
2441{
2442 return peer_flag_modify (peer, flag, 1);
2443}
2444
2445int
2446peer_flag_unset (struct peer *peer, u_int32_t flag)
2447{
2448 return peer_flag_modify (peer, flag, 0);
2449}
2450
94f2b392 2451static int
718e3744 2452peer_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
94f2b392 2459static int
718e3744 2460peer_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;
1eb8ef25 2465 struct listnode *node, *nnode;
718e3744 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
e0701b79 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
718e3744 2536 }
2537
2538 /* Peer group member updates. */
2539 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2540 {
2541 group = peer->group;
2542
1eb8ef25 2543 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
e0701b79 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 }
718e3744 2576 }
2577 }
2578 }
2579 return 0;
2580}
2581
2582int
2583peer_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
2588int
2589peer_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. */
2595int
2596peer_ebgp_multihop_set (struct peer *peer, int ttl)
2597{
2598 struct peer_group *group;
1eb8ef25 2599 struct listnode *node, *nnode;
718e3744 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 {
eb821189 2608 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2609 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
718e3744 2610 }
2611 else
2612 {
2613 group = peer->group;
1eb8ef25 2614 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
eb821189 2615 {
2616 if (peer_sort (peer) == BGP_PEER_IBGP)
2617 continue;
718e3744 2618
eb821189 2619 peer->ttl = group->conf->ttl;
718e3744 2620
eb821189 2621 if (peer->fd >= 0)
2622 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2623 }
718e3744 2624 }
2625 return 0;
2626}
2627
2628int
2629peer_ebgp_multihop_unset (struct peer *peer)
2630{
2631 struct peer_group *group;
1eb8ef25 2632 struct listnode *node, *nnode;
718e3744 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 {
eb821189 2644 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2645 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
718e3744 2646 }
2647 else
2648 {
2649 group = peer->group;
1eb8ef25 2650 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
eb821189 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 }
718e3744 2660 }
2661 return 0;
2662}
2663\f
2664/* Neighbor description. */
2665int
2666peer_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
2676int
2677peer_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. */
2688int
fd79ac91 2689peer_update_source_if_set (struct peer *peer, const char *ifname)
718e3744 2690{
2691 struct peer_group *group;
1eb8ef25 2692 struct listnode *node, *nnode;
718e3744 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)
e0701b79 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 }
718e3744 2720 else
2721 BGP_EVENT_ADD (peer, BGP_Stop);
2722 return 0;
2723 }
2724
2725 /* peer-group member updates. */
2726 group = peer->group;
1eb8ef25 2727 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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)
e0701b79 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 }
718e3744 2752 else
2753 BGP_EVENT_ADD (peer, BGP_Stop);
2754 }
2755 return 0;
2756}
2757
2758int
2759peer_update_source_addr_set (struct peer *peer, union sockunion *su)
2760{
2761 struct peer_group *group;
1eb8ef25 2762 struct listnode *node, *nnode;
718e3744 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)
e0701b79 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 }
718e3744 2789 else
2790 BGP_EVENT_ADD (peer, BGP_Stop);
2791 return 0;
2792 }
2793
2794 /* peer-group member updates. */
2795 group = peer->group;
1eb8ef25 2796 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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)
e0701b79 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 }
718e3744 2820 else
2821 BGP_EVENT_ADD (peer, BGP_Stop);
2822 }
2823 return 0;
2824}
2825
2826int
2827peer_update_source_unset (struct peer *peer)
2828{
2829 union sockunion *su;
2830 struct peer_group *group;
1eb8ef25 2831 struct listnode *node, *nnode;
718e3744 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)
e0701b79 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 }
718e3744 2871 else
2872 BGP_EVENT_ADD (peer, BGP_Stop);
2873 return 0;
2874 }
2875
2876 /* peer-group member updates. */
2877 group = peer->group;
1eb8ef25 2878 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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)
e0701b79 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 }
718e3744 2901 else
2902 BGP_EVENT_ADD (peer, BGP_Stop);
2903 }
2904 return 0;
2905}
2906\f
2907int
2908peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
fd79ac91 2909 const char *rmap)
718e3744 2910{
2911 struct peer_group *group;
1eb8ef25 2912 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 2946 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
2964int
2965peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
2966{
2967 struct peer_group *group;
1eb8ef25 2968 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 2997 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3012int
3013peer_port_set (struct peer *peer, u_int16_t port)
3014{
3015 peer->port = port;
3016 return 0;
3017}
3018
3019int
3020peer_port_unset (struct peer *peer)
3021{
3022 peer->port = BGP_PORT_DEFAULT;
3023 return 0;
3024}
3025\f
3026/* neighbor weight. */
3027int
3028peer_weight_set (struct peer *peer, u_int16_t weight)
3029{
3030 struct peer_group *group;
1eb8ef25 3031 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3041 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 3042 {
3043 peer->weight = group->conf->weight;
3044 }
3045 return 0;
3046}
3047
3048int
3049peer_weight_unset (struct peer *peer)
3050{
3051 struct peer_group *group;
1eb8ef25 3052 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3067 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 3068 {
3069 peer->weight = 0;
3070 }
3071 return 0;
3072}
3073\f
3074int
3075peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
3076{
3077 struct peer_group *group;
1eb8ef25 3078 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3106 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3115int
3116peer_timers_unset (struct peer *peer)
3117{
3118 struct peer_group *group;
1eb8ef25 3119 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3134 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3144int
3145peer_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
3163int
3164peer_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
3179int
3180peer_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
3195int
3196peer_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
718e3744 3212/* neighbor interface */
3213int
fd79ac91 3214peer_interface_set (struct peer *peer, const char *str)
718e3744 3215{
3216 if (peer->ifname)
3217 free (peer->ifname);
3218 peer->ifname = strdup (str);
3219
3220 return 0;
3221}
3222
3223int
3224peer_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. */
3234int
3235peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
3236{
3237 struct peer_group *group;
1eb8ef25 3238 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3254 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3267int
3268peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
3269{
3270 struct peer_group *group;
1eb8ef25 3271 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3283 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3294int
3295peer_local_as_set (struct peer *peer, as_t as, int no_prepend)
3296{
3297 struct bgp *bgp = peer->bgp;
3298 struct peer_group *group;
1eb8ef25 3299 struct listnode *node, *nnode;
718e3744 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)
e0701b79 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 }
718e3744 3330 else
3331 BGP_EVENT_ADD (peer, BGP_Stop);
3332
3333 return 0;
3334 }
3335
3336 group = peer->group;
1eb8ef25 3337 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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)
e0701b79 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 }
718e3744 3351 else
3352 BGP_EVENT_ADD (peer, BGP_Stop);
3353 }
3354
3355 return 0;
3356}
3357
3358int
3359peer_local_as_unset (struct peer *peer)
3360{
3361 struct peer_group *group;
1eb8ef25 3362 struct listnode *node, *nnode;
718e3744 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)
e0701b79 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 }
718e3744 3381 else
3382 BGP_EVENT_ADD (peer, BGP_Stop);
3383
3384 return 0;
3385 }
3386
3387 group = peer->group;
1eb8ef25 3388 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 3389 {
3390 peer->change_local_as = 0;
3391 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3392
3393 if (peer->status == Established)
e0701b79 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 }
718e3744 3399 else
3400 BGP_EVENT_ADD (peer, BGP_Stop);
3401 }
3402 return 0;
3403}
3404\f
0df7c91f
PJ
3405/* Set password for authenticating with the peer. */
3406int
3407peer_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
3457int
3458peer_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
718e3744 3510/* Set distribute list to the peer. */
3511int
3512peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
fd79ac91 3513 const char *name)
718e3744 3514{
3515 struct bgp_filter *filter;
3516 struct peer_group *group;
1eb8ef25 3517 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3542 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3558int
3559peer_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;
1eb8ef25 3564 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3601 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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. */
94f2b392 3618static void
718e3744 3619peer_distribute_update (struct access_list *access)
3620{
3621 afi_t afi;
3622 safi_t safi;
3623 int direct;
1eb8ef25 3624 struct listnode *mnode, *mnnode;
3625 struct listnode *node, *nnode;
718e3744 3626 struct bgp *bgp;
3627 struct peer *peer;
3628 struct peer_group *group;
3629 struct bgp_filter *filter;
3630
1eb8ef25 3631 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 3632 {
1eb8ef25 3633 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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 }
1eb8ef25 3650 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 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. */
3671int
3672peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
fd79ac91 3673 const char *name)
718e3744 3674{
3675 struct bgp_filter *filter;
3676 struct peer_group *group;
1eb8ef25 3677 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3702 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3717int
3718peer_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;
1eb8ef25 3723 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3760 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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. */
94f2b392 3777static void
718e3744 3778peer_prefix_list_update (struct prefix_list *plist)
3779{
1eb8ef25 3780 struct listnode *mnode, *mnnode;
3781 struct listnode *node, *nnode;
718e3744 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
1eb8ef25 3790 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 3791 {
1eb8ef25 3792 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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 }
1eb8ef25 3809 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 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
3829int
3830peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
fd79ac91 3831 const char *name)
718e3744 3832{
3833 struct bgp_filter *filter;
3834 struct peer_group *group;
1eb8ef25 3835 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 3857 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
3872int
3873peer_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;
1eb8ef25 3878 struct listnode *node, *nnode;
718e3744 3879
3880 if (! peer->afc[afi][safi])
3881 return BGP_ERR_PEER_INACTIVE;
3882
b5f29603 3883 if (direct != FILTER_IN && direct != FILTER_OUT)
718e3744 3884 return BGP_ERR_INVALID_VALUE;
3885
b5f29603 3886 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
718e3744 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;
1eb8ef25 3915 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
94f2b392 3931static void
66e5cd87 3932peer_aslist_update (void)
718e3744 3933{
3934 afi_t afi;
3935 safi_t safi;
3936 int direct;
1eb8ef25 3937 struct listnode *mnode, *mnnode;
3938 struct listnode *node, *nnode;
718e3744 3939 struct bgp *bgp;
3940 struct peer *peer;
3941 struct peer_group *group;
3942 struct bgp_filter *filter;
3943
1eb8ef25 3944 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 3945 {
1eb8ef25 3946 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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 }
1eb8ef25 3963 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 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. */
3984int
3985peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
fd79ac91 3986 const char *name)
718e3744 3987{
3988 struct bgp_filter *filter;
3989 struct peer_group *group;
1eb8ef25 3990 struct listnode *node, *nnode;
718e3744 3991
3992 if (! peer->afc[afi][safi])
3993 return BGP_ERR_PEER_INACTIVE;
3994
fee0f4c6 3995 if (direct != RMAP_IN && direct != RMAP_OUT &&
3996 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
718e3744 3997 return BGP_ERR_INVALID_VALUE;
3998
fee0f4c6 3999 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4000 && peer_is_group_member (peer, afi, safi))
718e3744 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;
1eb8ef25 4015 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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. */
4031int
4032peer_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;
1eb8ef25 4037 struct listnode *node, *nnode;
718e3744 4038
4039 if (! peer->afc[afi][safi])
4040 return BGP_ERR_PEER_INACTIVE;
4041
b5f29603 4042 if (direct != RMAP_IN && direct != RMAP_OUT &&
4043 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
718e3744 4044 return BGP_ERR_INVALID_VALUE;
4045
b5f29603 4046 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4047 && peer_is_group_member (peer, afi, safi))
718e3744 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;
1eb8ef25 4076 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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. */
4092int
fd79ac91 4093peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
4094 const char *name)
718e3744 4095{
4096 struct bgp_filter *filter;
4097 struct peer_group *group;
1eb8ef25 4098 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 4118 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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. */
4134int
4135peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
4136{
4137 struct bgp_filter *filter;
4138 struct peer_group *group;
1eb8ef25 4139 struct listnode *node, *nnode;
718e3744 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;
1eb8ef25 4158 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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
4173int
4174peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
0a486e5f 4175 u_int32_t max, u_char threshold,
4176 int warning, u_int16_t restart)
718e3744 4177{
4178 struct peer_group *group;
1eb8ef25 4179 struct listnode *node, *nnode;
718e3744 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;
e0701b79 4186 peer->pmax_threshold[afi][safi] = threshold;
0a486e5f 4187 peer->pmax_restart[afi][safi] = restart;
718e3744 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;
1eb8ef25 4197 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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;
e0701b79 4204 peer->pmax_threshold[afi][safi] = threshold;
0a486e5f 4205 peer->pmax_restart[afi][safi] = restart;
718e3744 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
4214int
4215peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
4216{
4217 struct peer_group *group;
1eb8ef25 4218 struct listnode *node, *nnode;
718e3744 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];
e0701b79 4239 peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
0a486e5f 4240 peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
718e3744 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;
0a486e5f 4247 peer->pmax_threshold[afi][safi] = 0;
4248 peer->pmax_restart[afi][safi] = 0;
718e3744 4249
4250 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4251 return 0;
4252
4253 group = peer->group;
1eb8ef25 4254 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
718e3744 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;
0a486e5f 4262 peer->pmax_threshold[afi][safi] = 0;
4263 peer->pmax_restart[afi][safi] = 0;
718e3744 4264 }
4265 return 0;
4266}
4267\f
4268int
4269peer_clear (struct peer *peer)
4270{
4271 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4272 {
0a486e5f 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
718e3744 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
4297int
4298peer_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
fee0f4c6 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
718e3744 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
fd79ac91 4373/* Display peer uptime.*/
4374/* XXX: why does this function return char * when it takes buffer? */
718e3744 4375char *
4376peer_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 {
0cd1c32d 4384 zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
fd79ac91 4385 /* XXX: should return status instead of buf... */
4386 snprintf (buf, len, "<error> ");
4387 return buf;
718e3744 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
94f2b392 4418static void
718e3744 4419bgp_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. */
fee0f4c6 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)
718e3744 4457 vty_out (vty, " neighbor %s route-map %s in%s", addr,
fee0f4c6 4458 filter->map[RMAP_IN].name, VTY_NEWLINE);
4459 if (filter->map[RMAP_OUT].name && ! gfilter)
718e3744 4460 vty_out (vty, " neighbor %s route-map %s out%s", addr,
fee0f4c6 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);
718e3744 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. */
94f2b392 4489static void
718e3744 4490bgp_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)
aea339f7 4515 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
718e3744 4516 VTY_NEWLINE);
4517 }
4518 else
4519 {
4520 if (! g_peer->as)
aea339f7 4521 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
718e3744 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))
aea339f7 4531 vty_out (vty, " neighbor %s local-as %u%s%s", addr,
718e3744 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
0df7c91f
PJ
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
718e3744 4555 /* BGP port. */
4556 if (peer->port != BGP_PORT_DEFAULT)
0df7c91f 4557 vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
718e3744 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
6ffd2079 4578 /* disable-connected-check. */
4579 if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
718e3744 4580 if (! peer_group_active (peer) ||
6ffd2079 4581 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4582 vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
718e3744 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
718e3744 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
718e3744 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]
e0701b79 4761 || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
718e3744 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))
e0701b79 4764 {
0a486e5f 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);
e0701b79 4773 }
718e3744 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. */
4818void
4819bgp_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)
37a217a5
PJ
4838 {
4839 vty_out (vty, "ipv6");
4840
4841 if (safi == SAFI_MULTICAST)
4842 vty_out (vty, " multicast");
4843 }
718e3744 4844
4845 vty_out (vty, "%s", VTY_NEWLINE);
4846
4847 *write = 1;
4848}
4849
4850/* Address family based peer configuration display. */
94f2b392 4851static int
718e3744 4852bgp_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;
1eb8ef25 4858 struct listnode *node, *nnode;
718e3744 4859
4860 bgp_config_write_network (vty, bgp, afi, safi, &write);
4861
4862 bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
4863
1eb8ef25 4864 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 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 }
1eb8ef25 4872 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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
4889int
4890bgp_config_write (struct vty *vty)
4891{
4892 int write = 0;
4893 struct bgp *bgp;
4894 struct peer_group *group;
4895 struct peer *peer;
1eb8ef25 4896 struct listnode *node, *nnode;
4897 struct listnode *mnode, *mnnode;
718e3744 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. */
1eb8ef25 4914 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
718e3744 4915 {
4916 if (write)
4917 vty_out (vty, "!%s", VTY_NEWLINE);
4918
4919 /* Router bgp ASN */
aea339f7 4920 vty_out (vty, "router bgp %u", bgp->as);
718e3744 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
848973c7 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
718e3744 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
e0701b79 4968 /* Confederation identifier*/
718e3744 4969 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
e0701b79 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)
718e3744 4975 {
e0701b79 4976 int i;
718e3744 4977
e0701b79 4978 vty_out (vty, " bgp confederation peers");
718e3744 4979
e0701b79 4980 for (i = 0; i < bgp->confed_peers_cnt; i++)
aea339f7 4981 vty_out(vty, " %u", bgp->confed_peers[i]);
718e3744 4982
e0701b79 4983 vty_out (vty, "%s", VTY_NEWLINE);
718e3744 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);
538621f2 4993
4994 /* BGP graceful-restart. */
93406d87 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);
538621f2 4998 if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
4999 vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
5000
718e3744 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);
6811845b 5004 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
5005 vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
718e3744 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 */
1eb8ef25 5044 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
718e3744 5045 {
5046 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
5047 }
5048
5049 /* Normal neighbor configuration. */
1eb8ef25 5050 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
718e3744 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
37a217a5
PJ
5072 /* IPv6 multicast configuration. */
5073 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
5074
718e3744 5075 write++;
5076 }
5077 return write;
5078}
5079
5080void
94f2b392 5081bgp_master_init (void)
718e3744 5082{
5083 memset (&bgp_master, 0, sizeof (struct bgp_master));
5084
5085 bm = &bgp_master;
5086 bm->bgp = list_new ();
0df7c91f 5087 bm->listen_sockets = list_new ();
718e3744 5088 bm->port = BGP_PORT_DEFAULT;
5089 bm->master = thread_master_create ();
5090 bm->start_time = time (NULL);
5091}
200df115 5092
718e3744 5093\f
5094void
94f2b392 5095bgp_init (void)
718e3744 5096{
718e3744 5097 /* BGP VTY commands installation. */
5098 bgp_vty_init ();
5099
5100 /* Create BGP server socket. */
3a02d1f7 5101 bgp_socket (NULL, bm->port, bm->address);
718e3744 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}
545acafb 5137
5138void
66e5cd87 5139bgp_terminate (void)
545acafb 5140{
545acafb 5141 struct bgp *bgp;
5142 struct peer *peer;
1eb8ef25 5143 struct listnode *node, *nnode;
5144 struct listnode *mnode, *mnnode;
545acafb 5145
1eb8ef25 5146 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5147 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
545acafb 5148 if (peer->status == Established)
5149 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
5150 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
1eb8ef25 5151
545acafb 5152 bgp_cleanup_routes ();
acde4b86 5153
e210cf9f 5154 if (bm->process_main_queue)
acde4b86
SH
5155 {
5156 work_queue_free (bm->process_main_queue);
5157 bm->process_main_queue = NULL;
5158 }
e210cf9f 5159 if (bm->process_rsclient_queue)
acde4b86
SH
5160 {
5161 work_queue_free (bm->process_rsclient_queue);
5162 bm->process_rsclient_queue = NULL;
5163 }
545acafb 5164}