[lib] Put symbolic backtrace on system log
[jleu-quagga.git] / bgpd / bgpd.c
blob3adede820e28778faf931c534094d6bb6ec93099
1 /* BGP-4, BGP-4+ daemon program
2 Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
6 GNU Zebra is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 GNU Zebra is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Zebra; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include <zebra.h>
23 #include "prefix.h"
24 #include "thread.h"
25 #include "buffer.h"
26 #include "stream.h"
27 #include "command.h"
28 #include "sockunion.h"
29 #include "network.h"
30 #include "memory.h"
31 #include "filter.h"
32 #include "routemap.h"
33 #include "str.h"
34 #include "log.h"
35 #include "plist.h"
36 #include "linklist.h"
37 #include "workqueue.h"
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 */
64 /* BGP process wide configuration. */
65 static struct bgp_master bgp_master;
67 extern struct in_addr router_id_zebra;
69 /* BGP process wide configuration pointer to export. */
70 struct bgp_master *bm;
72 /* BGP community-list. */
73 struct community_list_handler *bgp_clist;
75 /* BGP global flag manipulation. */
76 int
77 bgp_option_set (int flag)
79 switch (flag)
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;
89 return 0;
92 int
93 bgp_option_unset (int flag)
95 switch (flag)
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;
108 return 0;
112 bgp_option_check (int flag)
114 return CHECK_FLAG (bm->options, flag);
117 /* BGP flag manipulation. */
119 bgp_flag_set (struct bgp *bgp, int flag)
121 SET_FLAG (bgp->flags, flag);
122 return 0;
126 bgp_flag_unset (struct bgp *bgp, int flag)
128 UNSET_FLAG (bgp->flags, flag);
129 return 0;
133 bgp_flag_check (struct bgp *bgp, int flag)
135 return CHECK_FLAG (bgp->flags, flag);
138 /* Internal function to set BGP structure configureation flag. */
139 static void
140 bgp_config_set (struct bgp *bgp, int config)
142 SET_FLAG (bgp->config, config);
145 static void
146 bgp_config_unset (struct bgp *bgp, int config)
148 UNSET_FLAG (bgp->config, config);
151 static int
152 bgp_config_check (struct bgp *bgp, int config)
154 return CHECK_FLAG (bgp->config, config);
157 /* Set BGP router identifier. */
159 bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
161 struct peer *peer;
162 struct listnode *node, *nnode;
164 if (bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID)
165 && IPV4_ADDR_SAME (&bgp->router_id, id))
166 return 0;
168 IPV4_ADDR_COPY (&bgp->router_id, id);
169 bgp_config_set (bgp, BGP_CONFIG_ROUTER_ID);
171 /* Set all peer's local identifier with this value. */
172 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
174 IPV4_ADDR_COPY (&peer->local_id, id);
176 if (peer->status == Established)
178 peer->last_reset = PEER_DOWN_RID_CHANGE;
179 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
180 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
183 return 0;
186 /* BGP's cluster-id control. */
188 bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
190 struct peer *peer;
191 struct listnode *node, *nnode;
193 if (bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID)
194 && IPV4_ADDR_SAME (&bgp->cluster_id, cluster_id))
195 return 0;
197 IPV4_ADDR_COPY (&bgp->cluster_id, cluster_id);
198 bgp_config_set (bgp, BGP_CONFIG_CLUSTER_ID);
200 /* Clear all IBGP peer. */
201 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
203 if (peer_sort (peer) != BGP_PEER_IBGP)
204 continue;
206 if (peer->status == Established)
208 peer->last_reset = PEER_DOWN_CLID_CHANGE;
209 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
210 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
213 return 0;
217 bgp_cluster_id_unset (struct bgp *bgp)
219 struct peer *peer;
220 struct listnode *node, *nnode;
222 if (! bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID))
223 return 0;
225 bgp->cluster_id.s_addr = 0;
226 bgp_config_unset (bgp, BGP_CONFIG_CLUSTER_ID);
228 /* Clear all IBGP peer. */
229 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
231 if (peer_sort (peer) != BGP_PEER_IBGP)
232 continue;
234 if (peer->status == Established)
236 peer->last_reset = PEER_DOWN_CLID_CHANGE;
237 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
238 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
241 return 0;
244 /* BGP timer configuration. */
246 bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime)
248 bgp->default_keepalive = (keepalive < holdtime / 3
249 ? keepalive : holdtime / 3);
250 bgp->default_holdtime = holdtime;
252 return 0;
256 bgp_timers_unset (struct bgp *bgp)
258 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
259 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
261 return 0;
264 /* BGP confederation configuration. */
266 bgp_confederation_id_set (struct bgp *bgp, as_t as)
268 struct peer *peer;
269 struct listnode *node, *nnode;
270 int already_confed;
272 if (as == 0)
273 return BGP_ERR_INVALID_AS;
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);
280 /* If we were doing confederation already, this is just an external
281 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
282 were not doing confederation before, reset all EBGP sessions. */
283 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
285 /* We're looking for peers who's AS is not local or part of our
286 confederation. */
287 if (already_confed)
289 if (peer_sort (peer) == BGP_PEER_EBGP)
291 peer->local_as = as;
292 if (peer->status == Established)
294 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
295 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
296 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
299 else
300 BGP_EVENT_ADD (peer, BGP_Stop);
303 else
305 /* Not doign confederation before, so reset every non-local
306 session */
307 if (peer_sort (peer) != BGP_PEER_IBGP)
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)
314 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
315 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
316 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
318 else
319 BGP_EVENT_ADD (peer, BGP_Stop);
323 return 0;
327 bgp_confederation_id_unset (struct bgp *bgp)
329 struct peer *peer;
330 struct listnode *node, *nnode;
332 bgp->confed_id = 0;
333 bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
335 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
337 /* We're looking for peers who's AS is not local */
338 if (peer_sort (peer) != BGP_PEER_IBGP)
340 peer->local_as = bgp->as;
341 if (peer->status == Established)
343 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
344 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
345 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
348 else
349 BGP_EVENT_ADD (peer, BGP_Stop);
352 return 0;
355 /* Is an AS part of the confed or not? */
357 bgp_confederation_peers_check (struct bgp *bgp, as_t as)
359 int i;
361 if (! bgp)
362 return 0;
364 for (i = 0; i < bgp->confed_peers_cnt; i++)
365 if (bgp->confed_peers[i] == as)
366 return 1;
368 return 0;
371 /* Add an AS to the confederation set. */
373 bgp_confederation_peers_add (struct bgp *bgp, as_t as)
375 struct peer *peer;
376 struct listnode *node, *nnode;
378 if (! bgp)
379 return BGP_ERR_INVALID_BGP;
381 if (bgp->as == as)
382 return BGP_ERR_INVALID_AS;
384 if (bgp_confederation_peers_check (bgp, as))
385 return -1;
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));
395 bgp->confed_peers[bgp->confed_peers_cnt] = as;
396 bgp->confed_peers_cnt++;
398 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
400 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
402 if (peer->as == as)
404 peer->local_as = bgp->as;
405 if (peer->status == Established)
407 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
408 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
409 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
411 else
412 BGP_EVENT_ADD (peer, BGP_Stop);
416 return 0;
419 /* Delete an AS from the confederation set. */
421 bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
423 int i;
424 int j;
425 struct peer *peer;
426 struct listnode *node, *nnode;
428 if (! bgp)
429 return -1;
431 if (! bgp_confederation_peers_check (bgp, as))
432 return -1;
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];
439 bgp->confed_peers_cnt--;
441 if (bgp->confed_peers_cnt == 0)
443 if (bgp->confed_peers)
444 XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
445 bgp->confed_peers = NULL;
447 else
448 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
449 bgp->confed_peers,
450 bgp->confed_peers_cnt * sizeof (as_t));
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))
456 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
458 if (peer->as == as)
460 peer->local_as = bgp->confed_id;
461 if (peer->status == Established)
463 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
464 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
465 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
467 else
468 BGP_EVENT_ADD (peer, BGP_Stop);
473 return 0;
476 /* Local preference configuration. */
478 bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
480 if (! bgp)
481 return -1;
483 bgp->default_local_pref = local_pref;
485 return 0;
489 bgp_default_local_preference_unset (struct bgp *bgp)
491 if (! bgp)
492 return -1;
494 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
496 return 0;
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. */
503 peer_rsclient_active (struct peer *peer)
505 int i;
506 int j;
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;
516 /* Peer comparison function for sorting. */
517 static int
518 peer_cmp (struct peer *p1, struct peer *p2)
520 return sockunion_cmp (&p1->su, &p2->su);
524 peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
526 return CHECK_FLAG (peer->af_flags[afi][safi], flag);
529 /* Reset all address family specific configuration. */
530 static void
531 peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
533 int i;
534 struct bgp_filter *filter;
535 char orf_name[BUFSIZ];
537 filter = &peer->filter[afi][safi];
539 /* Clear neighbor filter and route-map */
540 for (i = FILTER_IN; i < FILTER_MAX; i++)
542 if (filter->dlist[i].name)
544 free (filter->dlist[i].name);
545 filter->dlist[i].name = NULL;
547 if (filter->plist[i].name)
549 free (filter->plist[i].name);
550 filter->plist[i].name = NULL;
552 if (filter->aslist[i].name)
554 free (filter->aslist[i].name);
555 filter->aslist[i].name = NULL;
558 for (i = RMAP_IN; i < RMAP_MAX; i++)
560 if (filter->map[i].name)
562 free (filter->map[i].name);
563 filter->map[i].name = NULL;
567 /* Clear unsuppress map. */
568 if (filter->usmap.name)
569 free (filter->usmap.name);
570 filter->usmap.name = NULL;
571 filter->usmap.map = NULL;
573 /* Clear neighbor's all address family flags. */
574 peer->af_flags[afi][safi] = 0;
576 /* Clear neighbor's all address family sflags. */
577 peer->af_sflags[afi][safi] = 0;
579 /* Clear neighbor's all address family capabilities. */
580 peer->af_cap[afi][safi] = 0;
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);
587 /* Set default neighbor send-community. */
588 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
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);
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;
600 /* Clear neighbor maximum-prefix */
601 peer->pmax[afi][safi] = 0;
602 peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
605 /* peer global config reset */
606 static void
607 peer_global_config_reset (struct peer *peer)
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)
614 sockunion_free (peer->update_source);
615 peer->update_source = NULL;
617 if (peer->update_if)
619 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
620 peer->update_if = NULL;
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;
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;
636 /* Check peer's AS number and determin is this peer IBGP or EBGP */
638 peer_sort (struct peer *peer)
640 struct bgp *bgp;
642 bgp = peer->bgp;
644 /* Peer-group */
645 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
647 if (peer->as)
648 return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP);
649 else
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);
657 return BGP_PEER_INTERNAL;
660 /* Normal peer */
661 if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
663 if (peer->local_as == 0)
664 return BGP_PEER_INTERNAL;
666 if (peer->local_as == peer->as)
668 if (peer->local_as == bgp->confed_id)
669 return BGP_PEER_EBGP;
670 else
671 return BGP_PEER_IBGP;
674 if (bgp_confederation_peers_check (bgp, peer->as))
675 return BGP_PEER_CONFED;
677 return BGP_PEER_EBGP;
679 else
681 return (peer->local_as == 0
682 ? BGP_PEER_INTERNAL : peer->local_as == peer->as
683 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
687 static inline void
688 peer_free (struct peer *peer)
690 assert (peer->status == Deleted);
692 /* this /ought/ to have been done already through bgp_stop earlier,
693 * but just to be sure..
695 bgp_timer_set (peer);
696 BGP_READ_OFF (peer->t_read);
697 BGP_WRITE_OFF (peer->t_write);
698 BGP_EVENT_FLUSH (peer);
700 if (peer->desc)
701 XFREE (MTYPE_PEER_DESC, peer->desc);
703 /* Free allocated host character. */
704 if (peer->host)
705 XFREE (MTYPE_BGP_PEER_HOST, peer->host);
707 /* Update source configuration. */
708 if (peer->update_source)
709 sockunion_free (peer->update_source);
711 if (peer->update_if)
712 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
714 if (peer->clear_node_queue)
715 work_queue_free (peer->clear_node_queue);
717 bgp_sync_delete (peer);
718 memset (peer, 0, sizeof (struct peer));
720 XFREE (MTYPE_BGP_PEER, peer);
723 /* increase reference count on a struct peer */
724 struct peer *
725 peer_lock (struct peer *peer)
727 assert (peer && (peer->lock >= 0));
728 assert (peer->status != Deleted);
730 peer->lock++;
732 return peer;
735 /* decrease reference count on a struct peer
736 * struct peer is freed and NULL returned if last reference
738 struct peer *
739 peer_unlock (struct peer *peer)
741 assert (peer && (peer->lock > 0));
743 peer->lock--;
745 if (peer->lock == 0)
747 #if 0
748 zlog_debug ("unlocked and freeing");
749 zlog_backtrace (LOG_DEBUG);
750 #endif
751 peer_free (peer);
752 return NULL;
755 #if 0
756 if (peer->lock == 1)
758 zlog_debug ("unlocked to 1");
759 zlog_backtrace (LOG_DEBUG);
761 #endif
763 return peer;
766 /* Allocate new peer object, implicitely locked. */
767 static struct peer *
768 peer_new (struct bgp *bgp)
770 afi_t afi;
771 safi_t safi;
772 struct peer *peer;
773 struct servent *sp;
775 /* bgp argument is absolutely required */
776 assert (bgp);
777 if (!bgp)
778 return NULL;
780 /* Allocate new peer. */
781 peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
783 /* Set default value. */
784 peer->fd = -1;
785 peer->v_start = BGP_INIT_START_TIMER;
786 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
787 peer->v_asorig = BGP_DEFAULT_ASORIGINATE;
788 peer->status = Idle;
789 peer->ostatus = Idle;
790 peer->weight = 0;
791 peer->password = NULL;
792 peer->bgp = bgp;
793 peer = peer_lock (peer); /* initial reference */
795 /* Set default flags. */
796 for (afi = AFI_IP; afi < AFI_MAX; afi++)
797 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
799 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
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);
804 peer->orf_plist[afi][safi] = NULL;
806 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
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);
813 bgp_sync_init (peer);
815 /* Get service port number. */
816 sp = getservbyname ("bgp", "tcp");
817 peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
819 return peer;
822 /* Create new BGP peer. */
823 static struct peer *
824 peer_create (union sockunion *su, struct bgp *bgp, as_t local_as,
825 as_t remote_as, afi_t afi, safi_t safi)
827 int active;
828 struct peer *peer;
829 char buf[SU_ADDRSTRLEN];
831 peer = peer_new (bgp);
832 peer->su = *su;
833 peer->local_as = local_as;
834 peer->as = remote_as;
835 peer->local_id = bgp->router_id;
836 peer->v_holdtime = bgp->default_holdtime;
837 peer->v_keepalive = bgp->default_keepalive;
838 if (peer_sort (peer) == BGP_PEER_IBGP)
839 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
840 else
841 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
843 peer = peer_lock (peer); /* bgp peer list reference */
844 listnode_add_sort (bgp->peer, peer);
846 active = peer_active (peer);
848 if (afi && safi)
849 peer->afc[afi][safi] = 1;
851 /* Last read time set */
852 peer->readtime = time (NULL);
854 /* Last reset time set */
855 peer->resettime = time (NULL);
857 /* Default TTL set. */
858 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
860 /* Make peer's address string. */
861 sockunion2str (su, buf, SU_ADDRSTRLEN);
862 peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
864 /* Set up peer's events and timers. */
865 if (! active && peer_active (peer))
866 bgp_timer_set (peer);
868 return peer;
871 /* Make accept BGP peer. Called from bgp_accept (). */
872 struct peer *
873 peer_create_accept (struct bgp *bgp)
875 struct peer *peer;
877 peer = peer_new (bgp);
879 peer = peer_lock (peer); /* bgp peer list reference */
880 listnode_add_sort (bgp->peer, peer);
882 return peer;
885 /* Change peer's AS number. */
886 static void
887 peer_as_change (struct peer *peer, as_t as)
889 int type;
891 /* Stop peer. */
892 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
894 if (peer->status == Established)
896 peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
897 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
898 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
900 else
901 BGP_EVENT_ADD (peer, BGP_Stop);
903 type = peer_sort (peer);
904 peer->as = as;
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;
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;
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;
925 /* reflector-client reset */
926 if (peer_sort (peer) != BGP_PEER_IBGP)
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);
940 /* local-as reset */
941 if (peer_sort (peer) != BGP_PEER_EBGP)
943 peer->change_local_as = 0;
944 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
948 /* If peer does not exist, create new one. If peer already exists,
949 set AS number to the peer. */
951 peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as,
952 afi_t afi, safi_t safi)
954 struct peer *peer;
955 as_t local_as;
957 peer = peer_lookup (bgp, su);
959 if (peer)
961 /* When this peer is a member of peer-group. */
962 if (peer->group)
964 if (peer->group->conf->as)
966 /* Return peer group's AS number. */
967 *as = peer->group->conf->as;
968 return BGP_ERR_PEER_GROUP_MEMBER;
970 if (peer_sort (peer->group->conf) == BGP_PEER_IBGP)
972 if (bgp->as != *as)
974 *as = peer->as;
975 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
978 else
980 if (bgp->as == *as)
982 *as = peer->as;
983 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
988 /* Existing peer's AS number change. */
989 if (peer->as != *as)
990 peer_as_change (peer, *as);
992 else
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;
1004 /* If this is IPv4 unicast configuration and "no bgp default
1005 ipv4-unicast" is specified. */
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);
1014 return 0;
1017 /* Activate the peer or peer group for specified AFI and SAFI. */
1019 peer_activate (struct peer *peer, afi_t afi, safi_t safi)
1021 int active;
1023 if (peer->afc[afi][safi])
1024 return 0;
1026 /* Activate the address family configuration. */
1027 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1028 peer->afc[afi][safi] = 1;
1029 else
1031 active = peer_active (peer);
1033 peer->afc[afi][safi] = 1;
1035 if (! active && peer_active (peer))
1036 bgp_timer_set (peer);
1037 else
1039 if (peer->status == Established)
1041 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
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])
1049 peer->afc_nego[afi][safi] = 1;
1050 bgp_announce_route (peer, afi, safi);
1053 else
1055 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
1056 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1057 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1062 return 0;
1066 peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
1068 struct peer_group *group;
1069 struct peer *peer1;
1070 struct listnode *node, *nnode;
1072 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1074 group = peer->group;
1076 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
1078 if (peer1->af_group[afi][safi])
1079 return BGP_ERR_PEER_GROUP_MEMBER_EXISTS;
1082 else
1084 if (peer->af_group[afi][safi])
1085 return BGP_ERR_PEER_BELONGS_TO_GROUP;
1088 if (! peer->afc[afi][safi])
1089 return 0;
1091 /* De-activate the address family configuration. */
1092 peer->afc[afi][safi] = 0;
1093 peer_af_flag_reset (peer, afi, safi);
1095 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1097 if (peer->status == Established)
1099 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1101 peer->afc_adv[afi][safi] = 0;
1102 peer->afc_nego[afi][safi] = 0;
1104 if (peer_active_nego (peer))
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;
1112 else
1114 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1115 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1116 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1119 else
1121 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1122 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1123 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1127 return 0;
1130 void
1131 peer_nsf_stop (struct peer *peer)
1133 afi_t afi;
1134 safi_t safi;
1136 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1137 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
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;
1143 if (peer->t_gr_restart)
1145 BGP_TIMER_OFF (peer->t_gr_restart);
1146 if (BGP_DEBUG (events, EVENTS))
1147 zlog_debug ("%s graceful restart timer stopped", peer->host);
1149 if (peer->t_gr_stale)
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);
1155 bgp_clear_route_all (peer);
1158 /* Delete peer from confguration.
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.
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.
1170 peer_delete (struct peer *peer)
1172 int i;
1173 afi_t afi;
1174 safi_t safi;
1175 struct bgp *bgp;
1176 struct bgp_filter *filter;
1178 assert (peer->status != Deleted);
1180 bgp = peer->bgp;
1182 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
1183 peer_nsf_stop (peer);
1185 /* If this peer belongs to peer group. Clearn up the
1186 relationship. */
1187 if (peer->group)
1189 struct listnode *pn;
1191 if ((pn = listnode_lookup (peer->group->peer, peer)))
1193 peer = peer_unlock (peer); /* group->peer list reference */
1194 list_delete_node (peer->group->peer, pn);
1196 peer->group = NULL;
1199 /* Withdraw all information from routing table. We can not use
1200 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
1201 * executed after peer structure is deleted.
1203 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1204 bgp_stop (peer);
1205 bgp_fsm_change_status (peer, Deleted);
1207 /* Password configuration */
1208 if (peer->password)
1210 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1211 peer->password = NULL;
1213 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1214 bgp_md5_set (peer);
1217 bgp_timer_set (peer); /* stops all timers for Deleted */
1219 /* Delete from all peer list. */
1220 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1222 struct listnode *pn;
1224 if ((pn = listnode_lookup (bgp->peer, peer)))
1226 peer_unlock (peer); /* bgp peer list reference */
1227 list_delete_node (bgp->peer, pn);
1230 if (peer_rsclient_active (peer)
1231 && (pn = listnode_lookup (bgp->rsclient, peer)))
1233 peer_unlock (peer); /* rsclient list reference */
1234 list_delete_node (bgp->rsclient, pn);
1238 /* Free RIB for any family in which peer is RSERVER_CLIENT, and is not
1239 member of a peer_group. */
1240 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1241 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1242 if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
1243 bgp_table_finish (&peer->rib[afi][safi]);
1245 /* Buffers. */
1246 if (peer->ibuf)
1247 stream_free (peer->ibuf);
1248 if (peer->obuf)
1249 stream_fifo_free (peer->obuf);
1250 if (peer->work)
1251 stream_free (peer->work);
1252 peer->obuf = NULL;
1253 peer->work = peer->ibuf = NULL;
1255 /* Local and remote addresses. */
1256 if (peer->su_local)
1257 sockunion_free (peer->su_local);
1258 if (peer->su_remote)
1259 sockunion_free (peer->su_remote);
1260 peer->su_local = peer->su_remote = NULL;
1262 /* Free filter related memory. */
1263 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1264 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1266 filter = &peer->filter[afi][safi];
1268 for (i = FILTER_IN; i < FILTER_MAX; i++)
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);
1277 filter->dlist[i].name = NULL;
1278 filter->plist[i].name = NULL;
1279 filter->aslist[i].name = NULL;
1281 for (i = RMAP_IN; i < RMAP_MAX; i++)
1283 if (filter->map[i].name)
1284 free (filter->map[i].name);
1285 filter->map[i].name = NULL;
1288 if (filter->usmap.name)
1289 free (filter->usmap.name);
1291 if (peer->default_rmap[afi][safi].name)
1292 free (peer->default_rmap[afi][safi].name);
1294 filter->usmap.name = NULL;
1295 peer->default_rmap[afi][safi].name = NULL;
1298 peer_unlock (peer); /* initial reference */
1300 return 0;
1303 static int
1304 peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
1306 return strcmp (g1->name, g2->name);
1309 /* If peer is configured at least one address family return 1. */
1310 static int
1311 peer_group_active (struct peer *peer)
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;
1322 /* Peer group cofiguration. */
1323 static struct peer_group *
1324 peer_group_new (void)
1326 return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
1327 sizeof (struct peer_group));
1330 static void
1331 peer_group_free (struct peer_group *group)
1333 XFREE (MTYPE_PEER_GROUP, group);
1336 struct peer_group *
1337 peer_group_lookup (struct bgp *bgp, const char *name)
1339 struct peer_group *group;
1340 struct listnode *node, *nnode;
1342 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
1344 if (strcmp (group->name, name) == 0)
1345 return group;
1347 return NULL;
1350 struct peer_group *
1351 peer_group_get (struct bgp *bgp, const char *name)
1353 struct peer_group *group;
1355 group = peer_group_lookup (bgp, name);
1356 if (group)
1357 return group;
1359 group = peer_group_new ();
1360 group->bgp = bgp;
1361 group->name = strdup (name);
1362 group->peer = list_new ();
1363 group->conf = peer_new (bgp);
1364 if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
1365 group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
1366 group->conf->host = strdup (name);
1367 group->conf->group = group;
1368 group->conf->as = 0;
1369 group->conf->ttl = 1;
1370 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1371 UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
1372 UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
1373 group->conf->keepalive = 0;
1374 group->conf->holdtime = 0;
1375 group->conf->connect = 0;
1376 SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP);
1377 listnode_add_sort (bgp->group, group);
1379 return 0;
1382 static void
1383 peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
1384 afi_t afi, safi_t safi)
1386 int in = FILTER_IN;
1387 int out = FILTER_OUT;
1388 struct peer *conf;
1389 struct bgp_filter *pfilter;
1390 struct bgp_filter *gfilter;
1392 conf = group->conf;
1393 pfilter = &peer->filter[afi][safi];
1394 gfilter = &conf->filter[afi][safi];
1396 /* remote-as */
1397 if (conf->as)
1398 peer->as = conf->as;
1400 /* remote-as */
1401 if (conf->change_local_as)
1402 peer->change_local_as = conf->change_local_as;
1404 /* TTL */
1405 peer->ttl = conf->ttl;
1407 /* Weight */
1408 peer->weight = conf->weight;
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;
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;
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;
1432 /* password apply */
1433 if (peer->password)
1434 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1436 if (conf->password)
1437 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
1438 else
1439 peer->password = NULL;
1441 bgp_md5_set (peer);
1443 /* maximum-prefix */
1444 peer->pmax[afi][safi] = conf->pmax[afi][safi];
1445 peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
1446 peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
1448 /* allowas-in */
1449 peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
1451 /* route-server-client */
1452 if (CHECK_FLAG(conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1454 /* Make peer's RIB point to group's RIB. */
1455 peer->rib[afi][safi] = group->conf->rib[afi][safi];
1457 /* Import policy. */
1458 if (pfilter->map[RMAP_IMPORT].name)
1459 free (pfilter->map[RMAP_IMPORT].name);
1460 if (gfilter->map[RMAP_IMPORT].name)
1462 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1463 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1465 else
1467 pfilter->map[RMAP_IMPORT].name = NULL;
1468 pfilter->map[RMAP_IMPORT].map = NULL;
1471 /* Export policy. */
1472 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1474 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1475 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1479 /* default-originate route-map */
1480 if (conf->default_rmap[afi][safi].name)
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;
1488 /* update-source apply */
1489 if (conf->update_source)
1491 if (peer->update_source)
1492 sockunion_free (peer->update_source);
1493 if (peer->update_if)
1495 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1496 peer->update_if = NULL;
1498 peer->update_source = sockunion_dup (conf->update_source);
1500 else if (conf->update_if)
1502 if (peer->update_if)
1503 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1504 if (peer->update_source)
1506 sockunion_free (peer->update_source);
1507 peer->update_source = NULL;
1509 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, conf->update_if);
1512 /* inbound filter apply */
1513 if (gfilter->dlist[in].name && ! pfilter->dlist[in].name)
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;
1520 if (gfilter->plist[in].name && ! pfilter->plist[in].name)
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;
1527 if (gfilter->aslist[in].name && ! pfilter->aslist[in].name)
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;
1534 if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
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;
1542 /* outbound filter apply */
1543 if (gfilter->dlist[out].name)
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;
1550 else
1552 if (pfilter->dlist[out].name)
1553 free (pfilter->dlist[out].name);
1554 pfilter->dlist[out].name = NULL;
1555 pfilter->dlist[out].alist = NULL;
1557 if (gfilter->plist[out].name)
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;
1564 else
1566 if (pfilter->plist[out].name)
1567 free (pfilter->plist[out].name);
1568 pfilter->plist[out].name = NULL;
1569 pfilter->plist[out].plist = NULL;
1571 if (gfilter->aslist[out].name)
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;
1578 else
1580 if (pfilter->aslist[out].name)
1581 free (pfilter->aslist[out].name);
1582 pfilter->aslist[out].name = NULL;
1583 pfilter->aslist[out].aslist = NULL;
1585 if (gfilter->map[RMAP_OUT].name)
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;
1592 else
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;
1600 /* RS-client's import/export route-maps. */
1601 if (gfilter->map[RMAP_IMPORT].name)
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;
1608 else
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;
1615 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
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;
1623 if (gfilter->usmap.name)
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;
1630 else
1632 if (pfilter->usmap.name)
1633 free (pfilter->usmap.name);
1634 pfilter->usmap.name = NULL;
1635 pfilter->usmap.map = NULL;
1639 /* Peer group's remote AS configuration. */
1641 peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
1643 struct peer_group *group;
1644 struct peer *peer;
1645 struct listnode *node, *nnode;
1647 group = peer_group_lookup (bgp, group_name);
1648 if (! group)
1649 return -1;
1651 if (group->conf->as == *as)
1652 return 0;
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);
1658 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1660 if (peer->as != *as)
1661 peer_as_change (peer, *as);
1664 return 0;
1668 peer_group_delete (struct peer_group *group)
1670 struct bgp *bgp;
1671 struct peer *peer;
1672 struct listnode *node, *nnode;
1674 bgp = group->bgp;
1676 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1678 peer->group = NULL;
1679 peer_delete (peer);
1681 list_delete (group->peer);
1683 free (group->name);
1684 group->name = NULL;
1686 group->conf->group = NULL;
1687 peer_delete (group->conf);
1689 /* Delete from all peer_group list. */
1690 listnode_delete (bgp->group, group);
1692 peer_group_free (group);
1694 return 0;
1698 peer_group_remote_as_delete (struct peer_group *group)
1700 struct peer *peer;
1701 struct listnode *node, *nnode;
1703 if (! group->conf->as)
1704 return 0;
1706 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1708 peer->group = NULL;
1709 peer_delete (peer);
1711 list_delete_all_node (group->peer);
1713 group->conf->as = 0;
1715 return 0;
1718 /* Bind specified peer to peer group. */
1720 peer_group_bind (struct bgp *bgp, union sockunion *su,
1721 struct peer_group *group, afi_t afi, safi_t safi, as_t *as)
1723 struct peer *peer;
1724 int first_member = 0;
1726 /* Check peer group's address family. */
1727 if (! group->conf->afc[afi][safi])
1728 return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED;
1730 /* Lookup the peer. */
1731 peer = peer_lookup (bgp, su);
1733 /* Create a new peer. */
1734 if (! peer)
1736 if (! group->conf->as)
1737 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
1739 peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi);
1740 peer->group = group;
1741 peer->af_group[afi][safi] = 1;
1743 peer = peer_lock (peer); /* group->peer list reference */
1744 listnode_add (group->peer, peer);
1745 peer_group2peer_config_copy (group, peer, afi, safi);
1747 return 0;
1750 /* When the peer already belongs to peer group, check the consistency. */
1751 if (peer->af_group[afi][safi])
1753 if (strcmp (peer->group->name, group->name) != 0)
1754 return BGP_ERR_PEER_GROUP_CANT_CHANGE;
1756 return 0;
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;
1764 if (! group->conf->as)
1766 if (peer_sort (group->conf) != BGP_PEER_INTERNAL
1767 && peer_sort (group->conf) != peer_sort (peer))
1769 if (as)
1770 *as = peer->as;
1771 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
1774 if (peer_sort (group->conf) == BGP_PEER_INTERNAL)
1775 first_member = 1;
1778 peer->af_group[afi][safi] = 1;
1779 peer->afc[afi][safi] = 1;
1780 if (! peer->group)
1782 peer->group = group;
1784 peer = peer_lock (peer); /* group->peer list reference */
1785 listnode_add (group->peer, peer);
1787 else
1788 assert (group && peer->group == group);
1790 if (first_member)
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;
1798 /* ebgp-multihop reset */
1799 if (peer_sort (group->conf) == BGP_PEER_IBGP)
1800 group->conf->ttl = 255;
1802 /* local-as reset */
1803 if (peer_sort (group->conf) != BGP_PEER_EBGP)
1805 group->conf->change_local_as = 0;
1806 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
1810 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1812 struct listnode *pn;
1814 /* If it's not configured as RSERVER_CLIENT in any other address
1815 family, without being member of a peer_group, remove it from
1816 list bgp->rsclient.*/
1817 if (! peer_rsclient_active (peer)
1818 && (pn = listnode_lookup (bgp->rsclient, peer)))
1820 peer_unlock (peer); /* peer rsclient reference */
1821 list_delete_node (bgp->rsclient, pn);
1824 bgp_table_finish (&peer->rib[afi][safi]);
1826 /* Import policy. */
1827 if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
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;
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)
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;
1844 peer_group2peer_config_copy (group, peer, afi, safi);
1846 if (peer->status == Established)
1848 peer->last_reset = PEER_DOWN_RMAP_BIND;
1849 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1850 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1852 else
1853 BGP_EVENT_ADD (peer, BGP_Stop);
1855 return 0;
1859 peer_group_unbind (struct bgp *bgp, struct peer *peer,
1860 struct peer_group *group, afi_t afi, safi_t safi)
1862 if (! peer->af_group[afi][safi])
1863 return 0;
1865 if (group != peer->group)
1866 return BGP_ERR_PEER_GROUP_MISMATCH;
1868 peer->af_group[afi][safi] = 0;
1869 peer->afc[afi][safi] = 0;
1870 peer_af_flag_reset (peer, afi, safi);
1872 if (peer->rib[afi][safi])
1873 peer->rib[afi][safi] = NULL;
1875 if (! peer_group_active (peer))
1877 assert (listnode_lookup (group->peer, peer));
1878 peer_unlock (peer); /* peer group list reference */
1879 listnode_delete (group->peer, peer);
1880 peer->group = NULL;
1881 if (group->conf->as)
1883 peer_delete (peer);
1884 return 0;
1886 peer_global_config_reset (peer);
1889 if (peer->status == Established)
1891 peer->last_reset = PEER_DOWN_RMAP_UNBIND;
1892 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1893 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1895 else
1896 BGP_EVENT_ADD (peer, BGP_Stop);
1898 return 0;
1901 /* BGP instance creation by `router bgp' commands. */
1902 static struct bgp *
1903 bgp_create (as_t *as, const char *name)
1905 struct bgp *bgp;
1906 afi_t afi;
1907 safi_t safi;
1909 if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
1910 return NULL;
1912 bgp->peer_self = peer_new (bgp);
1913 bgp->peer_self->host = strdup ("Static announcement");
1915 bgp->peer = list_new ();
1916 bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
1918 bgp->group = list_new ();
1919 bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
1921 bgp->rsclient = list_new ();
1922 bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
1924 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1925 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
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);
1932 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
1933 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
1934 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
1935 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
1936 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
1938 bgp->as = *as;
1940 if (name)
1941 bgp->name = strdup (name);
1943 return bgp;
1946 /* Return first entry of BGP. */
1947 struct bgp *
1948 bgp_get_default (void)
1950 if (bm->bgp->head)
1951 return (listgetdata (listhead (bm->bgp)));
1952 return NULL;
1955 /* Lookup BGP entry. */
1956 struct bgp *
1957 bgp_lookup (as_t as, const char *name)
1959 struct bgp *bgp;
1960 struct listnode *node, *nnode;
1962 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
1963 if (bgp->as == as
1964 && ((bgp->name == NULL && name == NULL)
1965 || (bgp->name && name && strcmp (bgp->name, name) == 0)))
1966 return bgp;
1967 return NULL;
1970 /* Lookup BGP structure by view name. */
1971 struct bgp *
1972 bgp_lookup_by_name (const char *name)
1974 struct bgp *bgp;
1975 struct listnode *node, *nnode;
1977 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
1978 if ((bgp->name == NULL && name == NULL)
1979 || (bgp->name && name && strcmp (bgp->name, name) == 0))
1980 return bgp;
1981 return NULL;
1984 /* Called from VTY commands. */
1986 bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
1988 struct bgp *bgp;
1990 /* Multiple instance check. */
1991 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
1993 if (name)
1994 bgp = bgp_lookup_by_name (name);
1995 else
1996 bgp = bgp_get_default ();
1998 /* Already exists. */
1999 if (bgp)
2001 if (bgp->as != *as)
2003 *as = bgp->as;
2004 return BGP_ERR_INSTANCE_MISMATCH;
2006 *bgp_val = bgp;
2007 return 0;
2010 else
2012 /* BGP instance name can not be specified for single instance. */
2013 if (name)
2014 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
2016 /* Get default BGP structure if exists. */
2017 bgp = bgp_get_default ();
2019 if (bgp)
2021 if (bgp->as != *as)
2023 *as = bgp->as;
2024 return BGP_ERR_AS_MISMATCH;
2026 *bgp_val = bgp;
2027 return 0;
2031 bgp = bgp_create (as, name);
2032 listnode_add (bm->bgp, bgp);
2033 bgp_router_id_set(bgp, &router_id_zebra);
2034 *bgp_val = bgp;
2036 return 0;
2039 /* Delete BGP instance. */
2041 bgp_delete (struct bgp *bgp)
2043 struct peer *peer;
2044 struct peer_group *group;
2045 struct listnode *node;
2046 struct listnode *next;
2047 afi_t afi;
2048 safi_t safi;
2049 int i;
2051 /* Delete static route. */
2052 bgp_static_delete (bgp);
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);
2060 for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
2061 peer_group_delete (group);
2062 list_delete (bgp->group);
2064 for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
2065 peer_delete (peer);
2066 list_delete (bgp->peer);
2068 for (ALL_LIST_ELEMENTS (bgp->rsclient, node, next, peer))
2069 peer_delete (peer);
2070 list_delete (bgp->rsclient);
2072 listnode_delete (bm->bgp, bgp);
2074 if (bgp->name)
2075 free (bgp->name);
2077 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2078 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
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]);
2087 XFREE (MTYPE_BGP, bgp);
2089 return 0;
2092 struct peer *
2093 peer_lookup (struct bgp *bgp, union sockunion *su)
2095 struct peer *peer;
2096 struct listnode *node, *nnode;
2098 if (! bgp)
2099 bgp = bgp_get_default ();
2101 if (! bgp)
2102 return NULL;
2104 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2106 if (sockunion_same (&peer->su, su)
2107 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2108 return peer;
2110 return NULL;
2113 struct peer *
2114 peer_lookup_with_open (union sockunion *su, as_t remote_as,
2115 struct in_addr *remote_id, int *as)
2117 struct peer *peer;
2118 struct listnode *node, *nnode;
2119 struct bgp *bgp;
2121 bgp = bgp_get_default ();
2122 if (! bgp)
2123 return NULL;
2125 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2127 if (sockunion_same (&peer->su, su)
2128 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
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;
2137 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2139 if (sockunion_same (&peer->su, su)
2140 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
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;
2149 return NULL;
2152 /* If peer is configured at least one address family return 1. */
2154 peer_active (struct peer *peer)
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;
2165 /* If peer is negotiated at least one address family return 1. */
2167 peer_active_nego (struct peer *peer)
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;
2178 /* peer_flag_change_type. */
2179 enum peer_change_type
2181 peer_change_none,
2182 peer_change_reset,
2183 peer_change_reset_in,
2184 peer_change_reset_out,
2187 static void
2188 peer_change_action (struct peer *peer, afi_t afi, safi_t safi,
2189 enum peer_change_type type)
2191 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2192 return;
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)
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);
2206 else if (type == peer_change_reset_out)
2207 bgp_announce_route (peer, afi, safi);
2210 struct peer_flag_action
2212 /* Peer's flag. */
2213 u_int32_t flag;
2215 /* This flag can be set for peer-group member. */
2216 u_char not_for_member;
2218 /* Action when the flag is changed. */
2219 enum peer_change_type type;
2221 /* Peer down cause */
2222 u_char peer_down;
2225 struct peer_flag_action peer_flag_action_list[] =
2227 { PEER_FLAG_PASSIVE, 0, peer_change_reset },
2228 { PEER_FLAG_SHUTDOWN, 0, peer_change_reset },
2229 { PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none },
2230 { PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none },
2231 { PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none },
2232 { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
2233 { PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
2234 { 0, 0, 0 }
2237 struct peer_flag_action peer_af_flag_action_list[] =
2239 { PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out },
2240 { PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out },
2241 { PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out },
2242 { PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in },
2243 { PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset },
2244 { PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset },
2245 { PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out },
2246 { PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out },
2247 { PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out },
2248 { PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out },
2249 { PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in },
2250 { PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset },
2251 { PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
2252 { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
2253 { 0, 0, 0 }
2256 /* Proper action set. */
2257 static int
2258 peer_flag_action_set (struct peer_flag_action *action_list, int size,
2259 struct peer_flag_action *action, u_int32_t flag)
2261 int i;
2262 int found = 0;
2263 int reset_in = 0;
2264 int reset_out = 0;
2265 struct peer_flag_action *match = NULL;
2267 /* Check peer's frag action. */
2268 for (i = 0; i < size; i++)
2270 match = &action_list[i];
2272 if (match->flag == 0)
2273 break;
2275 if (match->flag & flag)
2277 found = 1;
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)
2285 reset_in = 1;
2286 reset_out = 1;
2288 if (match->not_for_member)
2289 action->not_for_member = 1;
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;
2303 return found;
2306 static void
2307 peer_flag_modify_action (struct peer *peer, u_int32_t flag)
2309 if (flag == PEER_FLAG_SHUTDOWN)
2311 if (CHECK_FLAG (peer->flags, flag))
2313 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2314 peer_nsf_stop (peer);
2316 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2317 if (peer->t_pmax_restart)
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);
2325 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2326 peer_nsf_stop (peer);
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);
2334 else
2336 peer->v_start = BGP_INIT_START_TIMER;
2337 BGP_EVENT_ADD (peer, BGP_Stop);
2340 else if (peer->status == Established)
2342 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
2343 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2344 else if (flag == PEER_FLAG_PASSIVE)
2345 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
2346 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
2347 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
2349 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2350 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2352 else
2353 BGP_EVENT_ADD (peer, BGP_Stop);
2356 /* Change specified peer flag. */
2357 static int
2358 peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
2360 int found;
2361 int size;
2362 struct peer_group *group;
2363 struct listnode *node, *nnode;
2364 struct peer_flag_action action;
2366 memset (&action, 0, sizeof (struct peer_flag_action));
2367 size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
2369 found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
2371 /* No flag action is found. */
2372 if (! found)
2373 return BGP_ERR_INVALID_FLAG;
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;
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))
2384 if (flag == PEER_FLAG_SHUTDOWN)
2385 return BGP_ERR_PEER_GROUP_SHUTDOWN;
2386 else
2387 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
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;
2396 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2398 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2399 return 0;
2400 if (! set && ! CHECK_FLAG (peer->flags, flag))
2401 return 0;
2404 if (set)
2405 SET_FLAG (peer->flags, flag);
2406 else
2407 UNSET_FLAG (peer->flags, flag);
2409 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2411 if (action.type == peer_change_reset)
2412 peer_flag_modify_action (peer, flag);
2414 return 0;
2417 /* peer-group member updates. */
2418 group = peer->group;
2420 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2422 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2423 continue;
2425 if (! set && ! CHECK_FLAG (peer->flags, flag))
2426 continue;
2428 if (set)
2429 SET_FLAG (peer->flags, flag);
2430 else
2431 UNSET_FLAG (peer->flags, flag);
2433 if (action.type == peer_change_reset)
2434 peer_flag_modify_action (peer, flag);
2436 return 0;
2440 peer_flag_set (struct peer *peer, u_int32_t flag)
2442 return peer_flag_modify (peer, flag, 1);
2446 peer_flag_unset (struct peer *peer, u_int32_t flag)
2448 return peer_flag_modify (peer, flag, 0);
2451 static int
2452 peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
2454 if (peer->af_group[afi][safi])
2455 return 1;
2456 return 0;
2459 static int
2460 peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
2461 int set)
2463 int found;
2464 int size;
2465 struct listnode *node, *nnode;
2466 struct peer_group *group;
2467 struct peer_flag_action action;
2469 memset (&action, 0, sizeof (struct peer_flag_action));
2470 size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action);
2472 found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag);
2474 /* No flag action is found. */
2475 if (! found)
2476 return BGP_ERR_INVALID_FLAG;
2478 /* Adress family must be activated. */
2479 if (! peer->afc[afi][safi])
2480 return BGP_ERR_PEER_INACTIVE;
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;
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;
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;
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;
2502 /* When current flag configuration is same as requested one. */
2503 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
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;
2511 if (set)
2512 SET_FLAG (peer->af_flags[afi][safi], flag);
2513 else
2514 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2516 /* Execute action when peer is established. */
2517 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2518 && peer->status == Established)
2520 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2521 bgp_clear_adj_in (peer, afi, safi);
2522 else
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;
2533 peer_change_action (peer, afi, safi, action.type);
2538 /* Peer group member updates. */
2539 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2541 group = peer->group;
2543 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2545 if (! peer->af_group[afi][safi])
2546 continue;
2548 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2549 continue;
2551 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2552 continue;
2554 if (set)
2555 SET_FLAG (peer->af_flags[afi][safi], flag);
2556 else
2557 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2559 if (peer->status == Established)
2561 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2562 bgp_clear_adj_in (peer, afi, safi);
2563 else
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;
2574 peer_change_action (peer, afi, safi, action.type);
2579 return 0;
2583 peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2585 return peer_af_flag_modify (peer, afi, safi, flag, 1);
2589 peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2591 return peer_af_flag_modify (peer, afi, safi, flag, 0);
2594 /* EBGP multihop configuration. */
2596 peer_ebgp_multihop_set (struct peer *peer, int ttl)
2598 struct peer_group *group;
2599 struct listnode *node, *nnode;
2601 if (peer_sort (peer) == BGP_PEER_IBGP)
2602 return 0;
2604 peer->ttl = ttl;
2606 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2608 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2609 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2611 else
2613 group = peer->group;
2614 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2616 if (peer_sort (peer) == BGP_PEER_IBGP)
2617 continue;
2619 peer->ttl = group->conf->ttl;
2621 if (peer->fd >= 0)
2622 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2625 return 0;
2629 peer_ebgp_multihop_unset (struct peer *peer)
2631 struct peer_group *group;
2632 struct listnode *node, *nnode;
2634 if (peer_sort (peer) == BGP_PEER_IBGP)
2635 return 0;
2637 if (peer_group_active (peer))
2638 peer->ttl = peer->group->conf->ttl;
2639 else
2640 peer->ttl = 1;
2642 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2644 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2645 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2647 else
2649 group = peer->group;
2650 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2652 if (peer_sort (peer) == BGP_PEER_IBGP)
2653 continue;
2655 peer->ttl = 1;
2657 if (peer->fd >= 0)
2658 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2661 return 0;
2664 /* Neighbor description. */
2666 peer_description_set (struct peer *peer, char *desc)
2668 if (peer->desc)
2669 XFREE (MTYPE_PEER_DESC, peer->desc);
2671 peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
2673 return 0;
2677 peer_description_unset (struct peer *peer)
2679 if (peer->desc)
2680 XFREE (MTYPE_PEER_DESC, peer->desc);
2682 peer->desc = NULL;
2684 return 0;
2687 /* Neighbor update-source. */
2689 peer_update_source_if_set (struct peer *peer, const char *ifname)
2691 struct peer_group *group;
2692 struct listnode *node, *nnode;
2694 if (peer->update_if)
2696 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2697 && strcmp (peer->update_if, ifname) == 0)
2698 return 0;
2700 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2701 peer->update_if = NULL;
2704 if (peer->update_source)
2706 sockunion_free (peer->update_source);
2707 peer->update_source = NULL;
2710 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2712 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2714 if (peer->status == Established)
2716 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2717 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2718 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2720 else
2721 BGP_EVENT_ADD (peer, BGP_Stop);
2722 return 0;
2725 /* peer-group member updates. */
2726 group = peer->group;
2727 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2729 if (peer->update_if)
2731 if (strcmp (peer->update_if, ifname) == 0)
2732 continue;
2734 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2735 peer->update_if = NULL;
2738 if (peer->update_source)
2740 sockunion_free (peer->update_source);
2741 peer->update_source = NULL;
2744 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2746 if (peer->status == Established)
2748 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2749 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2750 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2752 else
2753 BGP_EVENT_ADD (peer, BGP_Stop);
2755 return 0;
2759 peer_update_source_addr_set (struct peer *peer, union sockunion *su)
2761 struct peer_group *group;
2762 struct listnode *node, *nnode;
2764 if (peer->update_source)
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;
2773 if (peer->update_if)
2775 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2776 peer->update_if = NULL;
2779 peer->update_source = sockunion_dup (su);
2781 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2783 if (peer->status == Established)
2785 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2786 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2787 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2789 else
2790 BGP_EVENT_ADD (peer, BGP_Stop);
2791 return 0;
2794 /* peer-group member updates. */
2795 group = peer->group;
2796 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2798 if (peer->update_source)
2800 if (sockunion_cmp (peer->update_source, su) == 0)
2801 continue;
2802 sockunion_free (peer->update_source);
2803 peer->update_source = NULL;
2806 if (peer->update_if)
2808 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2809 peer->update_if = NULL;
2812 peer->update_source = sockunion_dup (su);
2814 if (peer->status == Established)
2816 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2817 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2818 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2820 else
2821 BGP_EVENT_ADD (peer, BGP_Stop);
2823 return 0;
2827 peer_update_source_unset (struct peer *peer)
2829 union sockunion *su;
2830 struct peer_group *group;
2831 struct listnode *node, *nnode;
2833 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2834 && ! peer->update_source
2835 && ! peer->update_if)
2836 return 0;
2838 if (peer->update_source)
2840 sockunion_free (peer->update_source);
2841 peer->update_source = NULL;
2843 if (peer->update_if)
2845 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2846 peer->update_if = NULL;
2849 if (peer_group_active (peer))
2851 group = peer->group;
2853 if (group->conf->update_source)
2855 su = sockunion_dup (group->conf->update_source);
2856 peer->update_source = su;
2858 else if (group->conf->update_if)
2859 peer->update_if =
2860 XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
2863 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2865 if (peer->status == Established)
2867 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2868 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2869 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2871 else
2872 BGP_EVENT_ADD (peer, BGP_Stop);
2873 return 0;
2876 /* peer-group member updates. */
2877 group = peer->group;
2878 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2880 if (! peer->update_source && ! peer->update_if)
2881 continue;
2883 if (peer->update_source)
2885 sockunion_free (peer->update_source);
2886 peer->update_source = NULL;
2889 if (peer->update_if)
2891 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2892 peer->update_if = NULL;
2895 if (peer->status == Established)
2897 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2898 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2899 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2901 else
2902 BGP_EVENT_ADD (peer, BGP_Stop);
2904 return 0;
2908 peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
2909 const char *rmap)
2911 struct peer_group *group;
2912 struct listnode *node, *nnode;
2914 /* Adress family must be activated. */
2915 if (! peer->afc[afi][safi])
2916 return BGP_ERR_PEER_INACTIVE;
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;
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))
2926 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
2928 if (rmap)
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);
2937 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2939 if (peer->status == Established && peer->afc_nego[afi][safi])
2940 bgp_default_originate (peer, afi, safi, 0);
2941 return 0;
2944 /* peer-group member updates. */
2945 group = peer->group;
2946 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2948 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
2950 if (rmap)
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);
2958 if (peer->status == Established && peer->afc_nego[afi][safi])
2959 bgp_default_originate (peer, afi, safi, 0);
2961 return 0;
2965 peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
2967 struct peer_group *group;
2968 struct listnode *node, *nnode;
2970 /* Adress family must be activated. */
2971 if (! peer->afc[afi][safi])
2972 return BGP_ERR_PEER_INACTIVE;
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;
2978 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
2980 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
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;
2988 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2990 if (peer->status == Established && peer->afc_nego[afi][safi])
2991 bgp_default_originate (peer, afi, safi, 1);
2992 return 0;
2995 /* peer-group member updates. */
2996 group = peer->group;
2997 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2999 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
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;
3006 if (peer->status == Established && peer->afc_nego[afi][safi])
3007 bgp_default_originate (peer, afi, safi, 1);
3009 return 0;
3013 peer_port_set (struct peer *peer, u_int16_t port)
3015 peer->port = port;
3016 return 0;
3020 peer_port_unset (struct peer *peer)
3022 peer->port = BGP_PORT_DEFAULT;
3023 return 0;
3026 /* neighbor weight. */
3028 peer_weight_set (struct peer *peer, u_int16_t weight)
3030 struct peer_group *group;
3031 struct listnode *node, *nnode;
3033 SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3034 peer->weight = weight;
3036 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3037 return 0;
3039 /* peer-group member updates. */
3040 group = peer->group;
3041 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3043 peer->weight = group->conf->weight;
3045 return 0;
3049 peer_weight_unset (struct peer *peer)
3051 struct peer_group *group;
3052 struct listnode *node, *nnode;
3054 /* Set default weight. */
3055 if (peer_group_active (peer))
3056 peer->weight = peer->group->conf->weight;
3057 else
3058 peer->weight = 0;
3060 UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3062 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3063 return 0;
3065 /* peer-group member updates. */
3066 group = peer->group;
3067 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3069 peer->weight = 0;
3071 return 0;
3075 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
3077 struct peer_group *group;
3078 struct listnode *node, *nnode;
3080 /* Not for peer group memeber. */
3081 if (peer_group_active (peer))
3082 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3084 /* keepalive value check. */
3085 if (keepalive > 65535)
3086 return BGP_ERR_INVALID_VALUE;
3088 /* Holdtime value check. */
3089 if (holdtime > 65535)
3090 return BGP_ERR_INVALID_VALUE;
3092 /* Holdtime value must be either 0 or greater than 3. */
3093 if (holdtime < 3 && holdtime != 0)
3094 return BGP_ERR_INVALID_VALUE;
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);
3101 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3102 return 0;
3104 /* peer-group member updates. */
3105 group = peer->group;
3106 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3108 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3109 peer->holdtime = group->conf->holdtime;
3110 peer->keepalive = group->conf->keepalive;
3112 return 0;
3116 peer_timers_unset (struct peer *peer)
3118 struct peer_group *group;
3119 struct listnode *node, *nnode;
3121 if (peer_group_active (peer))
3122 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3124 /* Clear configuration. */
3125 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3126 peer->keepalive = 0;
3127 peer->holdtime = 0;
3129 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3130 return 0;
3132 /* peer-group member updates. */
3133 group = peer->group;
3134 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3136 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3137 peer->holdtime = 0;
3138 peer->keepalive = 0;
3141 return 0;
3145 peer_timers_connect_set (struct peer *peer, u_int32_t connect)
3147 if (peer_group_active (peer))
3148 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3150 if (connect > 65535)
3151 return BGP_ERR_INVALID_VALUE;
3153 /* Set value to the configuration. */
3154 SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3155 peer->connect = connect;
3157 /* Set value to timer setting. */
3158 peer->v_connect = connect;
3160 return 0;
3164 peer_timers_connect_unset (struct peer *peer)
3166 if (peer_group_active (peer))
3167 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3169 /* Clear configuration. */
3170 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3171 peer->connect = 0;
3173 /* Set timer setting to default value. */
3174 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
3176 return 0;
3180 peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
3182 if (peer_group_active (peer))
3183 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3185 if (routeadv > 600)
3186 return BGP_ERR_INVALID_VALUE;
3188 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3189 peer->routeadv = routeadv;
3190 peer->v_routeadv = routeadv;
3192 return 0;
3196 peer_advertise_interval_unset (struct peer *peer)
3198 if (peer_group_active (peer))
3199 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3201 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3202 peer->routeadv = 0;
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;
3209 return 0;
3212 /* neighbor interface */
3214 peer_interface_set (struct peer *peer, const char *str)
3216 if (peer->ifname)
3217 free (peer->ifname);
3218 peer->ifname = strdup (str);
3220 return 0;
3224 peer_interface_unset (struct peer *peer)
3226 if (peer->ifname)
3227 free (peer->ifname);
3228 peer->ifname = NULL;
3230 return 0;
3233 /* Allow-as in. */
3235 peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
3237 struct peer_group *group;
3238 struct listnode *node, *nnode;
3240 if (allow_num < 1 || allow_num > 10)
3241 return BGP_ERR_INVALID_VALUE;
3243 if (peer->allowas_in[afi][safi] != allow_num)
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);
3250 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3251 return 0;
3253 group = peer->group;
3254 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3256 if (peer->allowas_in[afi][safi] != allow_num)
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);
3264 return 0;
3268 peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
3270 struct peer_group *group;
3271 struct listnode *node, *nnode;
3273 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3275 peer->allowas_in[afi][safi] = 0;
3276 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3279 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3280 return 0;
3282 group = peer->group;
3283 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3285 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3287 peer->allowas_in[afi][safi] = 0;
3288 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3291 return 0;
3295 peer_local_as_set (struct peer *peer, as_t as, int no_prepend)
3297 struct bgp *bgp = peer->bgp;
3298 struct peer_group *group;
3299 struct listnode *node, *nnode;
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;
3305 if (bgp->as == as)
3306 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
3308 if (peer_group_active (peer))
3309 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
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;
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);
3322 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3324 if (peer->status == Established)
3326 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3327 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3328 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3330 else
3331 BGP_EVENT_ADD (peer, BGP_Stop);
3333 return 0;
3336 group = peer->group;
3337 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
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);
3345 if (peer->status == Established)
3347 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3348 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3349 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3351 else
3352 BGP_EVENT_ADD (peer, BGP_Stop);
3355 return 0;
3359 peer_local_as_unset (struct peer *peer)
3361 struct peer_group *group;
3362 struct listnode *node, *nnode;
3364 if (peer_group_active (peer))
3365 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3367 if (! peer->change_local_as)
3368 return 0;
3370 peer->change_local_as = 0;
3371 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3373 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3375 if (peer->status == Established)
3377 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3378 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3379 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3381 else
3382 BGP_EVENT_ADD (peer, BGP_Stop);
3384 return 0;
3387 group = peer->group;
3388 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3390 peer->change_local_as = 0;
3391 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3393 if (peer->status == Established)
3395 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3396 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3397 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3399 else
3400 BGP_EVENT_ADD (peer, BGP_Stop);
3402 return 0;
3405 /* Set password for authenticating with the peer. */
3407 peer_password_set (struct peer *peer, const char *password)
3409 struct listnode *nn, *nnode;
3410 int len = password ? strlen(password) : 0;
3411 int ret = BGP_SUCCESS;
3413 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
3414 return BGP_ERR_INVALID_VALUE;
3416 if (peer->password && strcmp (peer->password, password) == 0
3417 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3418 return 0;
3420 if (peer->password)
3421 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3423 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
3425 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
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);
3432 return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
3435 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3437 if (peer->password && strcmp (peer->password, password) == 0)
3438 continue;
3440 if (peer->password)
3441 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3443 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
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);
3450 if (bgp_md5_set (peer) < 0)
3451 ret = BGP_ERR_TCPSIG_FAILED;
3454 return ret;
3458 peer_password_unset (struct peer *peer)
3460 struct listnode *nn, *nnode;
3462 if (!peer->password
3463 && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3464 return 0;
3466 if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
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;
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);
3478 if (peer->password)
3479 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3481 peer->password = NULL;
3483 bgp_md5_set (peer);
3485 return 0;
3488 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3489 peer->password = NULL;
3491 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3493 if (!peer->password)
3494 continue;
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);
3501 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3502 peer->password = NULL;
3504 bgp_md5_set (peer);
3507 return 0;
3510 /* Set distribute list to the peer. */
3512 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3513 const char *name)
3515 struct bgp_filter *filter;
3516 struct peer_group *group;
3517 struct listnode *node, *nnode;
3519 if (! peer->afc[afi][safi])
3520 return BGP_ERR_PEER_INACTIVE;
3522 if (direct != FILTER_IN && direct != FILTER_OUT)
3523 return BGP_ERR_INVALID_VALUE;
3525 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3526 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3528 filter = &peer->filter[afi][safi];
3530 if (filter->plist[direct].name)
3531 return BGP_ERR_PEER_FILTER_CONFLICT;
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);
3538 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3539 return 0;
3541 group = peer->group;
3542 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3544 filter = &peer->filter[afi][safi];
3546 if (! peer->af_group[afi][safi])
3547 continue;
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);
3555 return 0;
3559 peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3561 struct bgp_filter *filter;
3562 struct bgp_filter *gfilter;
3563 struct peer_group *group;
3564 struct listnode *node, *nnode;
3566 if (! peer->afc[afi][safi])
3567 return BGP_ERR_PEER_INACTIVE;
3569 if (direct != FILTER_IN && direct != FILTER_OUT)
3570 return BGP_ERR_INVALID_VALUE;
3572 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3573 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3575 filter = &peer->filter[afi][safi];
3577 /* apply peer-group filter */
3578 if (peer->af_group[afi][safi])
3580 gfilter = &peer->group->conf->filter[afi][safi];
3582 if (gfilter->dlist[direct].name)
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;
3592 if (filter->dlist[direct].name)
3593 free (filter->dlist[direct].name);
3594 filter->dlist[direct].name = NULL;
3595 filter->dlist[direct].alist = NULL;
3597 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3598 return 0;
3600 group = peer->group;
3601 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3603 filter = &peer->filter[afi][safi];
3605 if (! peer->af_group[afi][safi])
3606 continue;
3608 if (filter->dlist[direct].name)
3609 free (filter->dlist[direct].name);
3610 filter->dlist[direct].name = NULL;
3611 filter->dlist[direct].alist = NULL;
3614 return 0;
3617 /* Update distribute list. */
3618 static void
3619 peer_distribute_update (struct access_list *access)
3621 afi_t afi;
3622 safi_t safi;
3623 int direct;
3624 struct listnode *mnode, *mnnode;
3625 struct listnode *node, *nnode;
3626 struct bgp *bgp;
3627 struct peer *peer;
3628 struct peer_group *group;
3629 struct bgp_filter *filter;
3631 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3633 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3635 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3636 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3638 filter = &peer->filter[afi][safi];
3640 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
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;
3650 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3652 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3653 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3655 filter = &group->conf->filter[afi][safi];
3657 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
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;
3670 /* Set prefix list to the peer. */
3672 peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3673 const char *name)
3675 struct bgp_filter *filter;
3676 struct peer_group *group;
3677 struct listnode *node, *nnode;
3679 if (! peer->afc[afi][safi])
3680 return BGP_ERR_PEER_INACTIVE;
3682 if (direct != FILTER_IN && direct != FILTER_OUT)
3683 return BGP_ERR_INVALID_VALUE;
3685 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3686 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3688 filter = &peer->filter[afi][safi];
3690 if (filter->dlist[direct].name)
3691 return BGP_ERR_PEER_FILTER_CONFLICT;
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);
3698 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3699 return 0;
3701 group = peer->group;
3702 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3704 filter = &peer->filter[afi][safi];
3706 if (! peer->af_group[afi][safi])
3707 continue;
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);
3714 return 0;
3718 peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3720 struct bgp_filter *filter;
3721 struct bgp_filter *gfilter;
3722 struct peer_group *group;
3723 struct listnode *node, *nnode;
3725 if (! peer->afc[afi][safi])
3726 return BGP_ERR_PEER_INACTIVE;
3728 if (direct != FILTER_IN && direct != FILTER_OUT)
3729 return BGP_ERR_INVALID_VALUE;
3731 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3732 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3734 filter = &peer->filter[afi][safi];
3736 /* apply peer-group filter */
3737 if (peer->af_group[afi][safi])
3739 gfilter = &peer->group->conf->filter[afi][safi];
3741 if (gfilter->plist[direct].name)
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;
3751 if (filter->plist[direct].name)
3752 free (filter->plist[direct].name);
3753 filter->plist[direct].name = NULL;
3754 filter->plist[direct].plist = NULL;
3756 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3757 return 0;
3759 group = peer->group;
3760 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3762 filter = &peer->filter[afi][safi];
3764 if (! peer->af_group[afi][safi])
3765 continue;
3767 if (filter->plist[direct].name)
3768 free (filter->plist[direct].name);
3769 filter->plist[direct].name = NULL;
3770 filter->plist[direct].plist = NULL;
3773 return 0;
3776 /* Update prefix-list list. */
3777 static void
3778 peer_prefix_list_update (struct prefix_list *plist)
3780 struct listnode *mnode, *mnnode;
3781 struct listnode *node, *nnode;
3782 struct bgp *bgp;
3783 struct peer *peer;
3784 struct peer_group *group;
3785 struct bgp_filter *filter;
3786 afi_t afi;
3787 safi_t safi;
3788 int direct;
3790 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3792 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3794 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3795 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3797 filter = &peer->filter[afi][safi];
3799 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
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;
3809 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3811 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3812 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3814 filter = &group->conf->filter[afi][safi];
3816 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
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;
3830 peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3831 const char *name)
3833 struct bgp_filter *filter;
3834 struct peer_group *group;
3835 struct listnode *node, *nnode;
3837 if (! peer->afc[afi][safi])
3838 return BGP_ERR_PEER_INACTIVE;
3840 if (direct != FILTER_IN && direct != FILTER_OUT)
3841 return BGP_ERR_INVALID_VALUE;
3843 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3844 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3846 filter = &peer->filter[afi][safi];
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);
3853 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3854 return 0;
3856 group = peer->group;
3857 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3859 filter = &peer->filter[afi][safi];
3861 if (! peer->af_group[afi][safi])
3862 continue;
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);
3869 return 0;
3873 peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
3875 struct bgp_filter *filter;
3876 struct bgp_filter *gfilter;
3877 struct peer_group *group;
3878 struct listnode *node, *nnode;
3880 if (! peer->afc[afi][safi])
3881 return BGP_ERR_PEER_INACTIVE;
3883 if (direct != FILTER_IN && direct != FILTER_OUT)
3884 return BGP_ERR_INVALID_VALUE;
3886 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3887 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3889 filter = &peer->filter[afi][safi];
3891 /* apply peer-group filter */
3892 if (peer->af_group[afi][safi])
3894 gfilter = &peer->group->conf->filter[afi][safi];
3896 if (gfilter->aslist[direct].name)
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;
3906 if (filter->aslist[direct].name)
3907 free (filter->aslist[direct].name);
3908 filter->aslist[direct].name = NULL;
3909 filter->aslist[direct].aslist = NULL;
3911 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3912 return 0;
3914 group = peer->group;
3915 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3917 filter = &peer->filter[afi][safi];
3919 if (! peer->af_group[afi][safi])
3920 continue;
3922 if (filter->aslist[direct].name)
3923 free (filter->aslist[direct].name);
3924 filter->aslist[direct].name = NULL;
3925 filter->aslist[direct].aslist = NULL;
3928 return 0;
3931 static void
3932 peer_aslist_update (void)
3934 afi_t afi;
3935 safi_t safi;
3936 int direct;
3937 struct listnode *mnode, *mnnode;
3938 struct listnode *node, *nnode;
3939 struct bgp *bgp;
3940 struct peer *peer;
3941 struct peer_group *group;
3942 struct bgp_filter *filter;
3944 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3946 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3948 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3949 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3951 filter = &peer->filter[afi][safi];
3953 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
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;
3963 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3965 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3966 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3968 filter = &group->conf->filter[afi][safi];
3970 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
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;
3983 /* Set route-map to the peer. */
3985 peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3986 const char *name)
3988 struct bgp_filter *filter;
3989 struct peer_group *group;
3990 struct listnode *node, *nnode;
3992 if (! peer->afc[afi][safi])
3993 return BGP_ERR_PEER_INACTIVE;
3995 if (direct != RMAP_IN && direct != RMAP_OUT &&
3996 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
3997 return BGP_ERR_INVALID_VALUE;
3999 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4000 && peer_is_group_member (peer, afi, safi))
4001 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4003 filter = &peer->filter[afi][safi];
4005 if (filter->map[direct].name)
4006 free (filter->map[direct].name);
4008 filter->map[direct].name = strdup (name);
4009 filter->map[direct].map = route_map_lookup_by_name (name);
4011 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4012 return 0;
4014 group = peer->group;
4015 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4017 filter = &peer->filter[afi][safi];
4019 if (! peer->af_group[afi][safi])
4020 continue;
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);
4027 return 0;
4030 /* Unset route-map from the peer. */
4032 peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
4034 struct bgp_filter *filter;
4035 struct bgp_filter *gfilter;
4036 struct peer_group *group;
4037 struct listnode *node, *nnode;
4039 if (! peer->afc[afi][safi])
4040 return BGP_ERR_PEER_INACTIVE;
4042 if (direct != RMAP_IN && direct != RMAP_OUT &&
4043 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4044 return BGP_ERR_INVALID_VALUE;
4046 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4047 && peer_is_group_member (peer, afi, safi))
4048 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4050 filter = &peer->filter[afi][safi];
4052 /* apply peer-group filter */
4053 if (peer->af_group[afi][safi])
4055 gfilter = &peer->group->conf->filter[afi][safi];
4057 if (gfilter->map[direct].name)
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;
4067 if (filter->map[direct].name)
4068 free (filter->map[direct].name);
4069 filter->map[direct].name = NULL;
4070 filter->map[direct].map = NULL;
4072 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4073 return 0;
4075 group = peer->group;
4076 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4078 filter = &peer->filter[afi][safi];
4080 if (! peer->af_group[afi][safi])
4081 continue;
4083 if (filter->map[direct].name)
4084 free (filter->map[direct].name);
4085 filter->map[direct].name = NULL;
4086 filter->map[direct].map = NULL;
4088 return 0;
4091 /* Set unsuppress-map to the peer. */
4093 peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
4094 const char *name)
4096 struct bgp_filter *filter;
4097 struct peer_group *group;
4098 struct listnode *node, *nnode;
4100 if (! peer->afc[afi][safi])
4101 return BGP_ERR_PEER_INACTIVE;
4103 if (peer_is_group_member (peer, afi, safi))
4104 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4106 filter = &peer->filter[afi][safi];
4108 if (filter->usmap.name)
4109 free (filter->usmap.name);
4111 filter->usmap.name = strdup (name);
4112 filter->usmap.map = route_map_lookup_by_name (name);
4114 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4115 return 0;
4117 group = peer->group;
4118 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4120 filter = &peer->filter[afi][safi];
4122 if (! peer->af_group[afi][safi])
4123 continue;
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);
4130 return 0;
4133 /* Unset route-map from the peer. */
4135 peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
4137 struct bgp_filter *filter;
4138 struct peer_group *group;
4139 struct listnode *node, *nnode;
4141 if (! peer->afc[afi][safi])
4142 return BGP_ERR_PEER_INACTIVE;
4144 if (peer_is_group_member (peer, afi, safi))
4145 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4147 filter = &peer->filter[afi][safi];
4149 if (filter->usmap.name)
4150 free (filter->usmap.name);
4151 filter->usmap.name = NULL;
4152 filter->usmap.map = NULL;
4154 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4155 return 0;
4157 group = peer->group;
4158 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4160 filter = &peer->filter[afi][safi];
4162 if (! peer->af_group[afi][safi])
4163 continue;
4165 if (filter->usmap.name)
4166 free (filter->usmap.name);
4167 filter->usmap.name = NULL;
4168 filter->usmap.map = NULL;
4170 return 0;
4174 peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
4175 u_int32_t max, u_char threshold,
4176 int warning, u_int16_t restart)
4178 struct peer_group *group;
4179 struct listnode *node, *nnode;
4181 if (! peer->afc[afi][safi])
4182 return BGP_ERR_PEER_INACTIVE;
4184 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4185 peer->pmax[afi][safi] = max;
4186 peer->pmax_threshold[afi][safi] = threshold;
4187 peer->pmax_restart[afi][safi] = restart;
4188 if (warning)
4189 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4190 else
4191 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4193 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4194 return 0;
4196 group = peer->group;
4197 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4199 if (! peer->af_group[afi][safi])
4200 continue;
4202 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4203 peer->pmax[afi][safi] = max;
4204 peer->pmax_threshold[afi][safi] = threshold;
4205 peer->pmax_restart[afi][safi] = restart;
4206 if (warning)
4207 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4208 else
4209 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4211 return 0;
4215 peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
4217 struct peer_group *group;
4218 struct listnode *node, *nnode;
4220 if (! peer->afc[afi][safi])
4221 return BGP_ERR_PEER_INACTIVE;
4223 /* apply peer-group config */
4224 if (peer->af_group[afi][safi])
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);
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);
4238 peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
4239 peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
4240 peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
4241 return 0;
4244 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4245 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4246 peer->pmax[afi][safi] = 0;
4247 peer->pmax_threshold[afi][safi] = 0;
4248 peer->pmax_restart[afi][safi] = 0;
4250 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4251 return 0;
4253 group = peer->group;
4254 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4256 if (! peer->af_group[afi][safi])
4257 continue;
4259 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4260 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4261 peer->pmax[afi][safi] = 0;
4262 peer->pmax_threshold[afi][safi] = 0;
4263 peer->pmax_restart[afi][safi] = 0;
4265 return 0;
4269 peer_clear (struct peer *peer)
4271 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4273 if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4275 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4276 if (peer->t_pmax_restart)
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);
4283 BGP_EVENT_ADD (peer, BGP_Start);
4284 return 0;
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);
4294 return 0;
4298 peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
4299 enum bgp_clear_type stype)
4301 if (peer->status != Established)
4302 return 0;
4304 if (! peer->afc[afi][safi])
4305 return BGP_ERR_AF_UNCONFIGURED;
4307 if (stype == BGP_CLEAR_SOFT_RSCLIENT)
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);
4315 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
4316 bgp_announce_route (peer, afi, safi);
4318 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
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)))
4324 struct bgp_filter *filter = &peer->filter[afi][safi];
4325 u_char prefix_type;
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;
4332 if (filter->plist[FILTER_IN].plist)
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);
4340 else
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);
4348 return 0;
4352 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
4353 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
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
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;
4370 return 0;
4373 /* Display peer uptime.*/
4374 /* XXX: why does this function return char * when it takes buffer? */
4375 char *
4376 peer_uptime (time_t uptime2, char *buf, size_t len)
4378 time_t uptime1;
4379 struct tm *tm;
4381 /* Check buffer length. */
4382 if (len < BGP_UPTIME_LEN)
4384 zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
4385 /* XXX: should return status instead of buf... */
4386 snprintf (buf, len, "<error> ");
4387 return buf;
4390 /* If there is no connection has been done before print `never'. */
4391 if (uptime2 == 0)
4393 snprintf (buf, len, "never ");
4394 return buf;
4397 /* Get current time. */
4398 uptime1 = time (NULL);
4399 uptime1 -= uptime2;
4400 tm = gmtime (&uptime1);
4402 /* Making formatted timer strings. */
4403 #define ONE_DAY_SECOND 60*60*24
4404 #define ONE_WEEK_SECOND 60*60*24*7
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;
4418 static void
4419 bgp_config_write_filter (struct vty *vty, struct peer *peer,
4420 afi_t afi, safi_t safi)
4422 struct bgp_filter *filter;
4423 struct bgp_filter *gfilter = NULL;
4424 char *addr;
4425 int in = FILTER_IN;
4426 int out = FILTER_OUT;
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];
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);
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);
4453 /* route-map. */
4454 if (filter->map[RMAP_IN].name)
4455 if (! gfilter || ! gfilter->map[RMAP_IN].name
4456 || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
4457 vty_out (vty, " neighbor %s route-map %s in%s", addr,
4458 filter->map[RMAP_IN].name, VTY_NEWLINE);
4459 if (filter->map[RMAP_OUT].name && ! gfilter)
4460 vty_out (vty, " neighbor %s route-map %s out%s", addr,
4461 filter->map[RMAP_OUT].name, VTY_NEWLINE);
4462 if (filter->map[RMAP_IMPORT].name && ! gfilter)
4463 vty_out (vty, " neighbor %s route-map %s import%s", addr,
4464 filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
4465 if (filter->map[RMAP_EXPORT].name)
4466 if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
4467 || strcmp (filter->map[RMAP_EXPORT].name,
4468 gfilter->map[RMAP_EXPORT].name) != 0)
4469 vty_out (vty, " neighbor %s route-map %s export%s", addr,
4470 filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
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);
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);
4488 /* BGP peer configuration display function. */
4489 static void
4490 bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
4491 struct peer *peer, afi_t afi, safi_t safi)
4493 struct bgp_filter *filter;
4494 struct peer *g_peer = NULL;
4495 char buf[SU_ADDRSTRLEN];
4496 char *addr;
4498 filter = &peer->filter[afi][safi];
4499 addr = peer->host;
4500 if (peer_group_active (peer))
4501 g_peer = peer->group->conf;
4503 /************************************
4504 ****** Global to the neighbor ******
4505 ************************************/
4506 if (afi == AFI_IP && safi == SAFI_UNICAST)
4508 /* remote-as. */
4509 if (! peer_group_active (peer))
4511 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4512 vty_out (vty, " neighbor %s peer-group%s", addr,
4513 VTY_NEWLINE);
4514 if (peer->as)
4515 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4516 VTY_NEWLINE);
4518 else
4520 if (! g_peer->as)
4521 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4522 VTY_NEWLINE);
4523 if (peer->af_group[AFI_IP][SAFI_UNICAST])
4524 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4525 peer->group->name, VTY_NEWLINE);
4528 /* local-as. */
4529 if (peer->change_local_as)
4530 if (! peer_group_active (peer))
4531 vty_out (vty, " neighbor %s local-as %u%s%s", addr,
4532 peer->change_local_as,
4533 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
4534 " no-prepend" : "", VTY_NEWLINE);
4536 /* Description. */
4537 if (peer->desc)
4538 vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
4539 VTY_NEWLINE);
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);
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);
4555 /* BGP port. */
4556 if (peer->port != BGP_PORT_DEFAULT)
4557 vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
4558 VTY_NEWLINE);
4560 /* Local interface name. */
4561 if (peer->ifname)
4562 vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
4563 VTY_NEWLINE);
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);
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);
4578 /* disable-connected-check. */
4579 if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4580 if (! peer_group_active (peer) ||
4581 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4582 vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
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);
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);
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);
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);
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);
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);
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);
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);
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);
4648 if (! peer_group_active (peer))
4650 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
4652 if (peer->afc[AFI_IP][SAFI_UNICAST])
4653 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4655 else
4657 if (! peer->afc[AFI_IP][SAFI_UNICAST])
4658 vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
4664 /************************************
4665 ****** Per AF to the neighbor ******
4666 ************************************/
4668 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
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);
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])
4682 vty_out (vty, " neighbor %s capability orf prefix-list", addr);
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);
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);
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);
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);
4711 /* send-community print. */
4712 if (! peer->af_group[afi][safi])
4714 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
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);
4725 else
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);
4740 /* Default information */
4741 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
4742 && ! peer->af_group[afi][safi])
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);
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);
4757 /* maximum-prefix. */
4758 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
4759 if (! peer->af_group[afi][safi]
4760 || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
4761 || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
4762 || CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
4763 != CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
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);
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);
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])
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);
4793 /* Filter. */
4794 bgp_config_write_filter (vty, peer, afi, safi);
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])
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);
4817 /* Display "address-family" configuration header. */
4818 void
4819 bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
4820 int *write)
4822 if (*write)
4823 return;
4825 if (afi == AFI_IP && safi == SAFI_UNICAST)
4826 return;
4828 vty_out (vty, "!%s address-family ", VTY_NEWLINE);
4830 if (afi == AFI_IP)
4832 if (safi == SAFI_MULTICAST)
4833 vty_out (vty, "ipv4 multicast");
4834 else if (safi == SAFI_MPLS_VPN)
4835 vty_out (vty, "vpnv4 unicast");
4837 else if (afi == AFI_IP6)
4839 vty_out (vty, "ipv6");
4841 if (safi == SAFI_MULTICAST)
4842 vty_out (vty, " multicast");
4845 vty_out (vty, "%s", VTY_NEWLINE);
4847 *write = 1;
4850 /* Address family based peer configuration display. */
4851 static int
4852 bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
4853 safi_t safi)
4855 int write = 0;
4856 struct peer *peer;
4857 struct peer_group *group;
4858 struct listnode *node, *nnode;
4860 bgp_config_write_network (vty, bgp, afi, safi, &write);
4862 bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
4864 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4866 if (group->conf->afc[afi][safi])
4868 bgp_config_write_family_header (vty, afi, safi, &write);
4869 bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
4872 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4874 if (peer->afc[afi][safi])
4876 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
4878 bgp_config_write_family_header (vty, afi, safi, &write);
4879 bgp_config_write_peer (vty, bgp, peer, afi, safi);
4883 if (write)
4884 vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
4886 return write;
4890 bgp_config_write (struct vty *vty)
4892 int write = 0;
4893 struct bgp *bgp;
4894 struct peer_group *group;
4895 struct peer *peer;
4896 struct listnode *node, *nnode;
4897 struct listnode *mnode, *mnnode;
4899 /* BGP Multiple instance. */
4900 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
4902 vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE);
4903 write++;
4906 /* BGP Config type. */
4907 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4909 vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE);
4910 write++;
4913 /* BGP configuration. */
4914 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4916 if (write)
4917 vty_out (vty, "!%s", VTY_NEWLINE);
4919 /* Router bgp ASN */
4920 vty_out (vty, "router bgp %u", bgp->as);
4922 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
4924 if (bgp->name)
4925 vty_out (vty, " view %s", bgp->name);
4927 vty_out (vty, "%s", VTY_NEWLINE);
4929 /* No Synchronization */
4930 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4931 vty_out (vty, " no synchronization%s", VTY_NEWLINE);
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);
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);
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);
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);
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);
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);
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);
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);
4968 /* Confederation identifier*/
4969 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
4970 vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
4971 VTY_NEWLINE);
4973 /* Confederation peer */
4974 if (bgp->confed_peers_cnt > 0)
4976 int i;
4978 vty_out (vty, " bgp confederation peers");
4980 for (i = 0; i < bgp->confed_peers_cnt; i++)
4981 vty_out(vty, " %u", bgp->confed_peers[i]);
4983 vty_out (vty, "%s", VTY_NEWLINE);
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);
4990 /* BGP deterministic-med. */
4991 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
4992 vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
4994 /* BGP graceful-restart. */
4995 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
4996 vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
4997 bgp->stalepath_time, VTY_NEWLINE);
4998 if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
4999 vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
5001 /* BGP bestpath method. */
5002 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
5003 vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
5004 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
5005 vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
5006 if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
5007 vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
5008 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
5009 || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
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);
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);
5023 /* BGP scan interval. */
5024 bgp_config_write_scan_time (vty);
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);
5031 /* BGP static route configuration. */
5032 bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5034 /* BGP redistribute configuration. */
5035 bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
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);
5043 /* peer-group */
5044 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5046 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
5049 /* Normal neighbor configuration. */
5050 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5052 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5053 bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
5056 /* Distance configuration. */
5057 bgp_config_write_distance (vty, bgp);
5059 /* No auto-summary */
5060 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5061 vty_out (vty, " no auto-summary%s", VTY_NEWLINE);
5063 /* IPv4 multicast configuration. */
5064 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
5066 /* IPv4 VPN configuration. */
5067 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
5069 /* IPv6 unicast configuration. */
5070 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
5072 /* IPv6 multicast configuration. */
5073 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
5075 write++;
5077 return write;
5080 void
5081 bgp_master_init (void)
5083 memset (&bgp_master, 0, sizeof (struct bgp_master));
5085 bm = &bgp_master;
5086 bm->bgp = list_new ();
5087 bm->listen_sockets = list_new ();
5088 bm->port = BGP_PORT_DEFAULT;
5089 bm->master = thread_master_create ();
5090 bm->start_time = time (NULL);
5094 void
5095 bgp_init (void)
5097 /* BGP VTY commands installation. */
5098 bgp_vty_init ();
5100 /* Create BGP server socket. */
5101 bgp_socket (NULL, bm->port, bm->address);
5103 /* Init zebra. */
5104 bgp_zebra_init ();
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 ();
5115 /* Access list initialize. */
5116 access_list_init ();
5117 access_list_add_hook (peer_distribute_update);
5118 access_list_delete_hook (peer_distribute_update);
5120 /* Filter list initialize. */
5121 bgp_filter_init ();
5122 as_list_add_hook (peer_aslist_update);
5123 as_list_delete_hook (peer_aslist_update);
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);
5130 /* Community list initialize. */
5131 bgp_clist = community_list_init ();
5133 #ifdef HAVE_SNMP
5134 bgp_snmp_init ();
5135 #endif /* HAVE_SNMP */
5138 void
5139 bgp_terminate (void)
5141 struct bgp *bgp;
5142 struct peer *peer;
5143 struct listnode *node, *nnode;
5144 struct listnode *mnode, *mnnode;
5146 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5147 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5148 if (peer->status == Established)
5149 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
5150 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
5152 bgp_cleanup_routes ();
5154 if (bm->process_main_queue)
5156 work_queue_free (bm->process_main_queue);
5157 bm->process_main_queue = NULL;
5159 if (bm->process_rsclient_queue)
5161 work_queue_free (bm->process_rsclient_queue);
5162 bm->process_rsclient_queue = NULL;