build: Add QuaggaId to README.NetBSD
[jleu-quagga.git] / bgpd / bgpd.c
blob882fe37cad66b858e1155cbf1ebbf0b48bb435a5
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 /* time_t value that is monotonicly increasing
245 * and uneffected by adjustments to system clock
247 time_t bgp_clock (void)
249 struct timeval tv;
251 quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv);
252 return tv.tv_sec;
255 /* BGP timer configuration. */
257 bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime)
259 bgp->default_keepalive = (keepalive < holdtime / 3
260 ? keepalive : holdtime / 3);
261 bgp->default_holdtime = holdtime;
263 return 0;
267 bgp_timers_unset (struct bgp *bgp)
269 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
270 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
272 return 0;
275 /* BGP confederation configuration. */
277 bgp_confederation_id_set (struct bgp *bgp, as_t as)
279 struct peer *peer;
280 struct listnode *node, *nnode;
281 int already_confed;
283 if (as == 0)
284 return BGP_ERR_INVALID_AS;
286 /* Remember - were we doing confederation before? */
287 already_confed = bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION);
288 bgp->confed_id = as;
289 bgp_config_set (bgp, BGP_CONFIG_CONFEDERATION);
291 /* If we were doing confederation already, this is just an external
292 AS change. Just Reset EBGP sessions, not CONFED sessions. If we
293 were not doing confederation before, reset all EBGP sessions. */
294 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
296 /* We're looking for peers who's AS is not local or part of our
297 confederation. */
298 if (already_confed)
300 if (peer_sort (peer) == BGP_PEER_EBGP)
302 peer->local_as = as;
303 if (peer->status == Established)
305 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
306 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
307 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
310 else
311 BGP_EVENT_ADD (peer, BGP_Stop);
314 else
316 /* Not doign confederation before, so reset every non-local
317 session */
318 if (peer_sort (peer) != BGP_PEER_IBGP)
320 /* Reset the local_as to be our EBGP one */
321 if (peer_sort (peer) == BGP_PEER_EBGP)
322 peer->local_as = as;
323 if (peer->status == Established)
325 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
326 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
327 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
329 else
330 BGP_EVENT_ADD (peer, BGP_Stop);
334 return 0;
338 bgp_confederation_id_unset (struct bgp *bgp)
340 struct peer *peer;
341 struct listnode *node, *nnode;
343 bgp->confed_id = 0;
344 bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
346 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
348 /* We're looking for peers who's AS is not local */
349 if (peer_sort (peer) != BGP_PEER_IBGP)
351 peer->local_as = bgp->as;
352 if (peer->status == Established)
354 peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
355 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
356 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
359 else
360 BGP_EVENT_ADD (peer, BGP_Stop);
363 return 0;
366 /* Is an AS part of the confed or not? */
368 bgp_confederation_peers_check (struct bgp *bgp, as_t as)
370 int i;
372 if (! bgp)
373 return 0;
375 for (i = 0; i < bgp->confed_peers_cnt; i++)
376 if (bgp->confed_peers[i] == as)
377 return 1;
379 return 0;
382 /* Add an AS to the confederation set. */
384 bgp_confederation_peers_add (struct bgp *bgp, as_t as)
386 struct peer *peer;
387 struct listnode *node, *nnode;
389 if (! bgp)
390 return BGP_ERR_INVALID_BGP;
392 if (bgp->as == as)
393 return BGP_ERR_INVALID_AS;
395 if (bgp_confederation_peers_check (bgp, as))
396 return -1;
398 if (bgp->confed_peers)
399 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
400 bgp->confed_peers,
401 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
402 else
403 bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST,
404 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
406 bgp->confed_peers[bgp->confed_peers_cnt] = as;
407 bgp->confed_peers_cnt++;
409 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
411 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
413 if (peer->as == as)
415 peer->local_as = bgp->as;
416 if (peer->status == Established)
418 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
419 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
420 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
422 else
423 BGP_EVENT_ADD (peer, BGP_Stop);
427 return 0;
430 /* Delete an AS from the confederation set. */
432 bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
434 int i;
435 int j;
436 struct peer *peer;
437 struct listnode *node, *nnode;
439 if (! bgp)
440 return -1;
442 if (! bgp_confederation_peers_check (bgp, as))
443 return -1;
445 for (i = 0; i < bgp->confed_peers_cnt; i++)
446 if (bgp->confed_peers[i] == as)
447 for(j = i + 1; j < bgp->confed_peers_cnt; j++)
448 bgp->confed_peers[j - 1] = bgp->confed_peers[j];
450 bgp->confed_peers_cnt--;
452 if (bgp->confed_peers_cnt == 0)
454 if (bgp->confed_peers)
455 XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
456 bgp->confed_peers = NULL;
458 else
459 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
460 bgp->confed_peers,
461 bgp->confed_peers_cnt * sizeof (as_t));
463 /* Now reset any peer who's remote AS has just been removed from the
464 CONFED */
465 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
467 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
469 if (peer->as == as)
471 peer->local_as = bgp->confed_id;
472 if (peer->status == Established)
474 peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
475 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
476 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
478 else
479 BGP_EVENT_ADD (peer, BGP_Stop);
484 return 0;
487 /* Local preference configuration. */
489 bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
491 if (! bgp)
492 return -1;
494 bgp->default_local_pref = local_pref;
496 return 0;
500 bgp_default_local_preference_unset (struct bgp *bgp)
502 if (! bgp)
503 return -1;
505 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
507 return 0;
510 /* If peer is RSERVER_CLIENT in at least one address family and is not member
511 of a peer_group for that family, return 1.
512 Used to check wether the peer is included in list bgp->rsclient. */
514 peer_rsclient_active (struct peer *peer)
516 int i;
517 int j;
519 for (i=AFI_IP; i < AFI_MAX; i++)
520 for (j=SAFI_UNICAST; j < SAFI_MAX; j++)
521 if (CHECK_FLAG(peer->af_flags[i][j], PEER_FLAG_RSERVER_CLIENT)
522 && ! peer->af_group[i][j])
523 return 1;
524 return 0;
527 /* Peer comparison function for sorting. */
528 static int
529 peer_cmp (struct peer *p1, struct peer *p2)
531 return sockunion_cmp (&p1->su, &p2->su);
535 peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
537 return CHECK_FLAG (peer->af_flags[afi][safi], flag);
540 /* Reset all address family specific configuration. */
541 static void
542 peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
544 int i;
545 struct bgp_filter *filter;
546 char orf_name[BUFSIZ];
548 filter = &peer->filter[afi][safi];
550 /* Clear neighbor filter and route-map */
551 for (i = FILTER_IN; i < FILTER_MAX; i++)
553 if (filter->dlist[i].name)
555 free (filter->dlist[i].name);
556 filter->dlist[i].name = NULL;
558 if (filter->plist[i].name)
560 free (filter->plist[i].name);
561 filter->plist[i].name = NULL;
563 if (filter->aslist[i].name)
565 free (filter->aslist[i].name);
566 filter->aslist[i].name = NULL;
569 for (i = RMAP_IN; i < RMAP_MAX; i++)
571 if (filter->map[i].name)
573 free (filter->map[i].name);
574 filter->map[i].name = NULL;
578 /* Clear unsuppress map. */
579 if (filter->usmap.name)
580 free (filter->usmap.name);
581 filter->usmap.name = NULL;
582 filter->usmap.map = NULL;
584 /* Clear neighbor's all address family flags. */
585 peer->af_flags[afi][safi] = 0;
587 /* Clear neighbor's all address family sflags. */
588 peer->af_sflags[afi][safi] = 0;
590 /* Clear neighbor's all address family capabilities. */
591 peer->af_cap[afi][safi] = 0;
593 /* Clear ORF info */
594 peer->orf_plist[afi][safi] = NULL;
595 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
596 prefix_bgp_orf_remove_all (orf_name);
598 /* Set default neighbor send-community. */
599 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
601 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
602 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
605 /* Clear neighbor default_originate_rmap */
606 if (peer->default_rmap[afi][safi].name)
607 free (peer->default_rmap[afi][safi].name);
608 peer->default_rmap[afi][safi].name = NULL;
609 peer->default_rmap[afi][safi].map = NULL;
611 /* Clear neighbor maximum-prefix */
612 peer->pmax[afi][safi] = 0;
613 peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
616 /* peer global config reset */
617 static void
618 peer_global_config_reset (struct peer *peer)
620 peer->weight = 0;
621 peer->change_local_as = 0;
622 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
623 if (peer->update_source)
625 sockunion_free (peer->update_source);
626 peer->update_source = NULL;
628 if (peer->update_if)
630 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
631 peer->update_if = NULL;
634 if (peer_sort (peer) == BGP_PEER_IBGP)
635 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
636 else
637 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
639 peer->flags = 0;
640 peer->config = 0;
641 peer->holdtime = 0;
642 peer->keepalive = 0;
643 peer->connect = 0;
644 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
647 /* Check peer's AS number and determin is this peer IBGP or EBGP */
649 peer_sort (struct peer *peer)
651 struct bgp *bgp;
653 bgp = peer->bgp;
655 /* Peer-group */
656 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
658 if (peer->as)
659 return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP);
660 else
662 struct peer *peer1;
663 peer1 = listnode_head (peer->group->peer);
664 if (peer1)
665 return (peer1->local_as == peer1->as
666 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
668 return BGP_PEER_INTERNAL;
671 /* Normal peer */
672 if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
674 if (peer->local_as == 0)
675 return BGP_PEER_INTERNAL;
677 if (peer->local_as == peer->as)
679 if (peer->local_as == bgp->confed_id)
680 return BGP_PEER_EBGP;
681 else
682 return BGP_PEER_IBGP;
685 if (bgp_confederation_peers_check (bgp, peer->as))
686 return BGP_PEER_CONFED;
688 return BGP_PEER_EBGP;
690 else
692 return (peer->local_as == 0
693 ? BGP_PEER_INTERNAL : peer->local_as == peer->as
694 ? BGP_PEER_IBGP : BGP_PEER_EBGP);
698 static inline void
699 peer_free (struct peer *peer)
701 assert (peer->status == Deleted);
703 bgp_unlock(peer->bgp);
705 /* this /ought/ to have been done already through bgp_stop earlier,
706 * but just to be sure..
708 bgp_timer_set (peer);
709 BGP_READ_OFF (peer->t_read);
710 BGP_WRITE_OFF (peer->t_write);
711 BGP_EVENT_FLUSH (peer);
713 if (peer->desc)
714 XFREE (MTYPE_PEER_DESC, peer->desc);
716 /* Free allocated host character. */
717 if (peer->host)
718 XFREE (MTYPE_BGP_PEER_HOST, peer->host);
720 /* Update source configuration. */
721 if (peer->update_source)
722 sockunion_free (peer->update_source);
724 if (peer->update_if)
725 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
727 if (peer->clear_node_queue)
728 work_queue_free (peer->clear_node_queue);
730 bgp_sync_delete (peer);
731 memset (peer, 0, sizeof (struct peer));
733 XFREE (MTYPE_BGP_PEER, peer);
736 /* increase reference count on a struct peer */
737 struct peer *
738 peer_lock (struct peer *peer)
740 assert (peer && (peer->lock >= 0));
742 peer->lock++;
744 return peer;
747 /* decrease reference count on a struct peer
748 * struct peer is freed and NULL returned if last reference
750 struct peer *
751 peer_unlock (struct peer *peer)
753 assert (peer && (peer->lock > 0));
755 peer->lock--;
757 if (peer->lock == 0)
759 #if 0
760 zlog_debug ("unlocked and freeing");
761 zlog_backtrace (LOG_DEBUG);
762 #endif
763 peer_free (peer);
764 return NULL;
767 #if 0
768 if (peer->lock == 1)
770 zlog_debug ("unlocked to 1");
771 zlog_backtrace (LOG_DEBUG);
773 #endif
775 return peer;
778 /* Allocate new peer object, implicitely locked. */
779 static struct peer *
780 peer_new (struct bgp *bgp)
782 afi_t afi;
783 safi_t safi;
784 struct peer *peer;
785 struct servent *sp;
787 /* bgp argument is absolutely required */
788 assert (bgp);
789 if (!bgp)
790 return NULL;
792 /* Allocate new peer. */
793 peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
795 /* Set default value. */
796 peer->fd = -1;
797 peer->v_start = BGP_INIT_START_TIMER;
798 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
799 peer->v_asorig = BGP_DEFAULT_ASORIGINATE;
800 peer->status = Idle;
801 peer->ostatus = Idle;
802 peer->weight = 0;
803 peer->password = NULL;
804 peer->bgp = bgp;
805 peer = peer_lock (peer); /* initial reference */
806 bgp_lock (bgp);
808 /* Set default flags. */
809 for (afi = AFI_IP; afi < AFI_MAX; afi++)
810 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
812 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
814 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
815 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
817 peer->orf_plist[afi][safi] = NULL;
819 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
821 /* Create buffers. */
822 peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);
823 peer->obuf = stream_fifo_new ();
824 peer->work = stream_new (BGP_MAX_PACKET_SIZE);
826 bgp_sync_init (peer);
828 /* Get service port number. */
829 sp = getservbyname ("bgp", "tcp");
830 peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
832 return peer;
835 /* Create new BGP peer. */
836 static struct peer *
837 peer_create (union sockunion *su, struct bgp *bgp, as_t local_as,
838 as_t remote_as, afi_t afi, safi_t safi)
840 int active;
841 struct peer *peer;
842 char buf[SU_ADDRSTRLEN];
844 peer = peer_new (bgp);
845 peer->su = *su;
846 peer->local_as = local_as;
847 peer->as = remote_as;
848 peer->local_id = bgp->router_id;
849 peer->v_holdtime = bgp->default_holdtime;
850 peer->v_keepalive = bgp->default_keepalive;
851 if (peer_sort (peer) == BGP_PEER_IBGP)
852 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
853 else
854 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
856 peer = peer_lock (peer); /* bgp peer list reference */
857 listnode_add_sort (bgp->peer, peer);
859 active = peer_active (peer);
861 if (afi && safi)
862 peer->afc[afi][safi] = 1;
864 /* Last read and reset time set */
865 peer->readtime = peer->resettime = bgp_clock ();
867 /* Default TTL set. */
868 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
870 /* Make peer's address string. */
871 sockunion2str (su, buf, SU_ADDRSTRLEN);
872 peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
874 /* Set up peer's events and timers. */
875 if (! active && peer_active (peer))
876 bgp_timer_set (peer);
878 return peer;
881 /* Make accept BGP peer. Called from bgp_accept (). */
882 struct peer *
883 peer_create_accept (struct bgp *bgp)
885 struct peer *peer;
887 peer = peer_new (bgp);
889 peer = peer_lock (peer); /* bgp peer list reference */
890 listnode_add_sort (bgp->peer, peer);
892 return peer;
895 /* Change peer's AS number. */
896 static void
897 peer_as_change (struct peer *peer, as_t as)
899 int type;
901 /* Stop peer. */
902 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
904 if (peer->status == Established)
906 peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
907 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
908 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
910 else
911 BGP_EVENT_ADD (peer, BGP_Stop);
913 type = peer_sort (peer);
914 peer->as = as;
916 if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION)
917 && ! bgp_confederation_peers_check (peer->bgp, as)
918 && peer->bgp->as != as)
919 peer->local_as = peer->bgp->confed_id;
920 else
921 peer->local_as = peer->bgp->as;
923 /* Advertisement-interval reset */
924 if (peer_sort (peer) == BGP_PEER_IBGP)
925 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
926 else
927 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
929 /* TTL reset */
930 if (peer_sort (peer) == BGP_PEER_IBGP)
931 peer->ttl = 255;
932 else if (type == BGP_PEER_IBGP)
933 peer->ttl = 1;
935 /* reflector-client reset */
936 if (peer_sort (peer) != BGP_PEER_IBGP)
938 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
939 PEER_FLAG_REFLECTOR_CLIENT);
940 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
941 PEER_FLAG_REFLECTOR_CLIENT);
942 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
943 PEER_FLAG_REFLECTOR_CLIENT);
944 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
945 PEER_FLAG_REFLECTOR_CLIENT);
946 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
947 PEER_FLAG_REFLECTOR_CLIENT);
950 /* local-as reset */
951 if (peer_sort (peer) != BGP_PEER_EBGP)
953 peer->change_local_as = 0;
954 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
958 /* If peer does not exist, create new one. If peer already exists,
959 set AS number to the peer. */
961 peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as,
962 afi_t afi, safi_t safi)
964 struct peer *peer;
965 as_t local_as;
967 peer = peer_lookup (bgp, su);
969 if (peer)
971 /* When this peer is a member of peer-group. */
972 if (peer->group)
974 if (peer->group->conf->as)
976 /* Return peer group's AS number. */
977 *as = peer->group->conf->as;
978 return BGP_ERR_PEER_GROUP_MEMBER;
980 if (peer_sort (peer->group->conf) == BGP_PEER_IBGP)
982 if (bgp->as != *as)
984 *as = peer->as;
985 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
988 else
990 if (bgp->as == *as)
992 *as = peer->as;
993 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
998 /* Existing peer's AS number change. */
999 if (peer->as != *as)
1000 peer_as_change (peer, *as);
1002 else
1005 /* If the peer is not part of our confederation, and its not an
1006 iBGP peer then spoof the source AS */
1007 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION)
1008 && ! bgp_confederation_peers_check (bgp, *as)
1009 && bgp->as != *as)
1010 local_as = bgp->confed_id;
1011 else
1012 local_as = bgp->as;
1014 /* If this is IPv4 unicast configuration and "no bgp default
1015 ipv4-unicast" is specified. */
1017 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
1018 && afi == AFI_IP && safi == SAFI_UNICAST)
1019 peer = peer_create (su, bgp, local_as, *as, 0, 0);
1020 else
1021 peer = peer_create (su, bgp, local_as, *as, afi, safi);
1024 return 0;
1027 /* Activate the peer or peer group for specified AFI and SAFI. */
1029 peer_activate (struct peer *peer, afi_t afi, safi_t safi)
1031 int active;
1033 if (peer->afc[afi][safi])
1034 return 0;
1036 /* Activate the address family configuration. */
1037 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1038 peer->afc[afi][safi] = 1;
1039 else
1041 active = peer_active (peer);
1043 peer->afc[afi][safi] = 1;
1045 if (! active && peer_active (peer))
1046 bgp_timer_set (peer);
1047 else
1049 if (peer->status == Established)
1051 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1053 peer->afc_adv[afi][safi] = 1;
1054 bgp_capability_send (peer, afi, safi,
1055 CAPABILITY_CODE_MP,
1056 CAPABILITY_ACTION_SET);
1057 if (peer->afc_recv[afi][safi])
1059 peer->afc_nego[afi][safi] = 1;
1060 bgp_announce_route (peer, afi, safi);
1063 else
1065 peer->last_reset = PEER_DOWN_AF_ACTIVATE;
1066 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1067 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1072 return 0;
1076 peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
1078 struct peer_group *group;
1079 struct peer *peer1;
1080 struct listnode *node, *nnode;
1082 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1084 group = peer->group;
1086 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
1088 if (peer1->af_group[afi][safi])
1089 return BGP_ERR_PEER_GROUP_MEMBER_EXISTS;
1092 else
1094 if (peer->af_group[afi][safi])
1095 return BGP_ERR_PEER_BELONGS_TO_GROUP;
1098 if (! peer->afc[afi][safi])
1099 return 0;
1101 /* De-activate the address family configuration. */
1102 peer->afc[afi][safi] = 0;
1103 peer_af_flag_reset (peer, afi, safi);
1105 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1107 if (peer->status == Established)
1109 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
1111 peer->afc_adv[afi][safi] = 0;
1112 peer->afc_nego[afi][safi] = 0;
1114 if (peer_active_nego (peer))
1116 bgp_capability_send (peer, afi, safi,
1117 CAPABILITY_CODE_MP,
1118 CAPABILITY_ACTION_UNSET);
1119 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
1120 peer->pcount[afi][safi] = 0;
1122 else
1124 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1125 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1126 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1129 else
1131 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1132 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1133 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1137 return 0;
1140 static void
1141 peer_nsf_stop (struct peer *peer)
1143 afi_t afi;
1144 safi_t safi;
1146 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
1147 UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
1149 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1150 for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
1151 peer->nsf[afi][safi] = 0;
1153 if (peer->t_gr_restart)
1155 BGP_TIMER_OFF (peer->t_gr_restart);
1156 if (BGP_DEBUG (events, EVENTS))
1157 zlog_debug ("%s graceful restart timer stopped", peer->host);
1159 if (peer->t_gr_stale)
1161 BGP_TIMER_OFF (peer->t_gr_stale);
1162 if (BGP_DEBUG (events, EVENTS))
1163 zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
1165 bgp_clear_route_all (peer);
1168 /* Delete peer from confguration.
1170 * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
1171 * it to "cool off" and refcounts to hit 0, at which state it is freed.
1173 * This function /should/ take care to be idempotent, to guard against
1174 * it being called multiple times through stray events that come in
1175 * that happen to result in this function being called again. That
1176 * said, getting here for a "Deleted" peer is a bug in the neighbour
1177 * FSM.
1180 peer_delete (struct peer *peer)
1182 int i;
1183 afi_t afi;
1184 safi_t safi;
1185 struct bgp *bgp;
1186 struct bgp_filter *filter;
1187 struct listnode *pn;
1189 assert (peer->status != Deleted);
1191 bgp = peer->bgp;
1193 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
1194 peer_nsf_stop (peer);
1196 /* If this peer belongs to peer group, clear up the
1197 relationship. */
1198 if (peer->group)
1200 if ((pn = listnode_lookup (peer->group->peer, peer)))
1202 peer = peer_unlock (peer); /* group->peer list reference */
1203 list_delete_node (peer->group->peer, pn);
1205 peer->group = NULL;
1208 /* Withdraw all information from routing table. We can not use
1209 * BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
1210 * executed after peer structure is deleted.
1212 peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
1213 bgp_stop (peer);
1214 bgp_fsm_change_status (peer, Deleted);
1216 /* Password configuration */
1217 if (peer->password)
1219 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1220 peer->password = NULL;
1222 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
1223 bgp_md5_set (peer);
1226 bgp_timer_set (peer); /* stops all timers for Deleted */
1228 /* Delete from all peer list. */
1229 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
1230 && (pn = listnode_lookup (bgp->peer, peer)))
1232 peer_unlock (peer); /* bgp peer list reference */
1233 list_delete_node (bgp->peer, pn);
1236 if (peer_rsclient_active (peer)
1237 && (pn = listnode_lookup (bgp->rsclient, peer)))
1239 peer_unlock (peer); /* rsclient list reference */
1240 list_delete_node (bgp->rsclient, pn);
1242 /* Clear our own rsclient ribs. */
1243 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1244 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1245 if (CHECK_FLAG(peer->af_flags[afi][safi],
1246 PEER_FLAG_RSERVER_CLIENT))
1247 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
1250 /* Free RIB for any family in which peer is RSERVER_CLIENT, and is not
1251 member of a peer_group. */
1252 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1253 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1254 if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
1255 bgp_table_finish (&peer->rib[afi][safi]);
1257 /* Buffers. */
1258 if (peer->ibuf)
1259 stream_free (peer->ibuf);
1260 if (peer->obuf)
1261 stream_fifo_free (peer->obuf);
1262 if (peer->work)
1263 stream_free (peer->work);
1264 peer->obuf = NULL;
1265 peer->work = peer->ibuf = NULL;
1267 /* Local and remote addresses. */
1268 if (peer->su_local)
1269 sockunion_free (peer->su_local);
1270 if (peer->su_remote)
1271 sockunion_free (peer->su_remote);
1272 peer->su_local = peer->su_remote = NULL;
1274 /* Free filter related memory. */
1275 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1276 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1278 filter = &peer->filter[afi][safi];
1280 for (i = FILTER_IN; i < FILTER_MAX; i++)
1282 if (filter->dlist[i].name)
1283 free (filter->dlist[i].name);
1284 if (filter->plist[i].name)
1285 free (filter->plist[i].name);
1286 if (filter->aslist[i].name)
1287 free (filter->aslist[i].name);
1289 filter->dlist[i].name = NULL;
1290 filter->plist[i].name = NULL;
1291 filter->aslist[i].name = NULL;
1293 for (i = RMAP_IN; i < RMAP_MAX; i++)
1295 if (filter->map[i].name)
1296 free (filter->map[i].name);
1297 filter->map[i].name = NULL;
1300 if (filter->usmap.name)
1301 free (filter->usmap.name);
1303 if (peer->default_rmap[afi][safi].name)
1304 free (peer->default_rmap[afi][safi].name);
1306 filter->usmap.name = NULL;
1307 peer->default_rmap[afi][safi].name = NULL;
1310 peer_unlock (peer); /* initial reference */
1312 return 0;
1315 static int
1316 peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
1318 return strcmp (g1->name, g2->name);
1321 /* If peer is configured at least one address family return 1. */
1322 static int
1323 peer_group_active (struct peer *peer)
1325 if (peer->af_group[AFI_IP][SAFI_UNICAST]
1326 || peer->af_group[AFI_IP][SAFI_MULTICAST]
1327 || peer->af_group[AFI_IP][SAFI_MPLS_VPN]
1328 || peer->af_group[AFI_IP6][SAFI_UNICAST]
1329 || peer->af_group[AFI_IP6][SAFI_MULTICAST])
1330 return 1;
1331 return 0;
1334 /* Peer group cofiguration. */
1335 static struct peer_group *
1336 peer_group_new (void)
1338 return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
1339 sizeof (struct peer_group));
1342 static void
1343 peer_group_free (struct peer_group *group)
1345 XFREE (MTYPE_PEER_GROUP, group);
1348 struct peer_group *
1349 peer_group_lookup (struct bgp *bgp, const char *name)
1351 struct peer_group *group;
1352 struct listnode *node, *nnode;
1354 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
1356 if (strcmp (group->name, name) == 0)
1357 return group;
1359 return NULL;
1362 struct peer_group *
1363 peer_group_get (struct bgp *bgp, const char *name)
1365 struct peer_group *group;
1367 group = peer_group_lookup (bgp, name);
1368 if (group)
1369 return group;
1371 group = peer_group_new ();
1372 group->bgp = bgp;
1373 group->name = strdup (name);
1374 group->peer = list_new ();
1375 group->conf = peer_new (bgp);
1376 if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
1377 group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
1378 group->conf->host = XSTRDUP (MTYPE_BGP_PEER_HOST, name);
1379 group->conf->group = group;
1380 group->conf->as = 0;
1381 group->conf->ttl = 1;
1382 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1383 UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
1384 UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
1385 group->conf->keepalive = 0;
1386 group->conf->holdtime = 0;
1387 group->conf->connect = 0;
1388 SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP);
1389 listnode_add_sort (bgp->group, group);
1391 return 0;
1394 static void
1395 peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
1396 afi_t afi, safi_t safi)
1398 int in = FILTER_IN;
1399 int out = FILTER_OUT;
1400 struct peer *conf;
1401 struct bgp_filter *pfilter;
1402 struct bgp_filter *gfilter;
1404 conf = group->conf;
1405 pfilter = &peer->filter[afi][safi];
1406 gfilter = &conf->filter[afi][safi];
1408 /* remote-as */
1409 if (conf->as)
1410 peer->as = conf->as;
1412 /* remote-as */
1413 if (conf->change_local_as)
1414 peer->change_local_as = conf->change_local_as;
1416 /* TTL */
1417 peer->ttl = conf->ttl;
1419 /* Weight */
1420 peer->weight = conf->weight;
1422 /* peer flags apply */
1423 peer->flags = conf->flags;
1424 /* peer af_flags apply */
1425 peer->af_flags[afi][safi] = conf->af_flags[afi][safi];
1426 /* peer config apply */
1427 peer->config = conf->config;
1429 /* peer timers apply */
1430 peer->holdtime = conf->holdtime;
1431 peer->keepalive = conf->keepalive;
1432 peer->connect = conf->connect;
1433 if (CHECK_FLAG (conf->config, PEER_CONFIG_CONNECT))
1434 peer->v_connect = conf->connect;
1435 else
1436 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
1438 /* advertisement-interval reset */
1439 if (peer_sort (peer) == BGP_PEER_IBGP)
1440 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
1441 else
1442 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1444 /* password apply */
1445 if (peer->password)
1446 XFREE (MTYPE_PEER_PASSWORD, peer->password);
1448 if (conf->password)
1449 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
1450 else
1451 peer->password = NULL;
1453 bgp_md5_set (peer);
1455 /* maximum-prefix */
1456 peer->pmax[afi][safi] = conf->pmax[afi][safi];
1457 peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
1458 peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
1460 /* allowas-in */
1461 peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
1463 /* route-server-client */
1464 if (CHECK_FLAG(conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1466 /* Make peer's RIB point to group's RIB. */
1467 peer->rib[afi][safi] = group->conf->rib[afi][safi];
1469 /* Import policy. */
1470 if (pfilter->map[RMAP_IMPORT].name)
1471 free (pfilter->map[RMAP_IMPORT].name);
1472 if (gfilter->map[RMAP_IMPORT].name)
1474 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1475 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1477 else
1479 pfilter->map[RMAP_IMPORT].name = NULL;
1480 pfilter->map[RMAP_IMPORT].map = NULL;
1483 /* Export policy. */
1484 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1486 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1487 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1491 /* default-originate route-map */
1492 if (conf->default_rmap[afi][safi].name)
1494 if (peer->default_rmap[afi][safi].name)
1495 free (peer->default_rmap[afi][safi].name);
1496 peer->default_rmap[afi][safi].name = strdup (conf->default_rmap[afi][safi].name);
1497 peer->default_rmap[afi][safi].map = conf->default_rmap[afi][safi].map;
1500 /* update-source apply */
1501 if (conf->update_source)
1503 if (peer->update_source)
1504 sockunion_free (peer->update_source);
1505 if (peer->update_if)
1507 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1508 peer->update_if = NULL;
1510 peer->update_source = sockunion_dup (conf->update_source);
1512 else if (conf->update_if)
1514 if (peer->update_if)
1515 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
1516 if (peer->update_source)
1518 sockunion_free (peer->update_source);
1519 peer->update_source = NULL;
1521 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, conf->update_if);
1524 /* inbound filter apply */
1525 if (gfilter->dlist[in].name && ! pfilter->dlist[in].name)
1527 if (pfilter->dlist[in].name)
1528 free (pfilter->dlist[in].name);
1529 pfilter->dlist[in].name = strdup (gfilter->dlist[in].name);
1530 pfilter->dlist[in].alist = gfilter->dlist[in].alist;
1532 if (gfilter->plist[in].name && ! pfilter->plist[in].name)
1534 if (pfilter->plist[in].name)
1535 free (pfilter->plist[in].name);
1536 pfilter->plist[in].name = strdup (gfilter->plist[in].name);
1537 pfilter->plist[in].plist = gfilter->plist[in].plist;
1539 if (gfilter->aslist[in].name && ! pfilter->aslist[in].name)
1541 if (pfilter->aslist[in].name)
1542 free (pfilter->aslist[in].name);
1543 pfilter->aslist[in].name = strdup (gfilter->aslist[in].name);
1544 pfilter->aslist[in].aslist = gfilter->aslist[in].aslist;
1546 if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
1548 if (pfilter->map[RMAP_IN].name)
1549 free (pfilter->map[RMAP_IN].name);
1550 pfilter->map[RMAP_IN].name = strdup (gfilter->map[RMAP_IN].name);
1551 pfilter->map[RMAP_IN].map = gfilter->map[RMAP_IN].map;
1554 /* outbound filter apply */
1555 if (gfilter->dlist[out].name)
1557 if (pfilter->dlist[out].name)
1558 free (pfilter->dlist[out].name);
1559 pfilter->dlist[out].name = strdup (gfilter->dlist[out].name);
1560 pfilter->dlist[out].alist = gfilter->dlist[out].alist;
1562 else
1564 if (pfilter->dlist[out].name)
1565 free (pfilter->dlist[out].name);
1566 pfilter->dlist[out].name = NULL;
1567 pfilter->dlist[out].alist = NULL;
1569 if (gfilter->plist[out].name)
1571 if (pfilter->plist[out].name)
1572 free (pfilter->plist[out].name);
1573 pfilter->plist[out].name = strdup (gfilter->plist[out].name);
1574 pfilter->plist[out].plist = gfilter->plist[out].plist;
1576 else
1578 if (pfilter->plist[out].name)
1579 free (pfilter->plist[out].name);
1580 pfilter->plist[out].name = NULL;
1581 pfilter->plist[out].plist = NULL;
1583 if (gfilter->aslist[out].name)
1585 if (pfilter->aslist[out].name)
1586 free (pfilter->aslist[out].name);
1587 pfilter->aslist[out].name = strdup (gfilter->aslist[out].name);
1588 pfilter->aslist[out].aslist = gfilter->aslist[out].aslist;
1590 else
1592 if (pfilter->aslist[out].name)
1593 free (pfilter->aslist[out].name);
1594 pfilter->aslist[out].name = NULL;
1595 pfilter->aslist[out].aslist = NULL;
1597 if (gfilter->map[RMAP_OUT].name)
1599 if (pfilter->map[RMAP_OUT].name)
1600 free (pfilter->map[RMAP_OUT].name);
1601 pfilter->map[RMAP_OUT].name = strdup (gfilter->map[RMAP_OUT].name);
1602 pfilter->map[RMAP_OUT].map = gfilter->map[RMAP_OUT].map;
1604 else
1606 if (pfilter->map[RMAP_OUT].name)
1607 free (pfilter->map[RMAP_OUT].name);
1608 pfilter->map[RMAP_OUT].name = NULL;
1609 pfilter->map[RMAP_OUT].map = NULL;
1612 /* RS-client's import/export route-maps. */
1613 if (gfilter->map[RMAP_IMPORT].name)
1615 if (pfilter->map[RMAP_IMPORT].name)
1616 free (pfilter->map[RMAP_IMPORT].name);
1617 pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
1618 pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
1620 else
1622 if (pfilter->map[RMAP_IMPORT].name)
1623 free (pfilter->map[RMAP_IMPORT].name);
1624 pfilter->map[RMAP_IMPORT].name = NULL;
1625 pfilter->map[RMAP_IMPORT].map = NULL;
1627 if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
1629 if (pfilter->map[RMAP_EXPORT].name)
1630 free (pfilter->map[RMAP_EXPORT].name);
1631 pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
1632 pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
1635 if (gfilter->usmap.name)
1637 if (pfilter->usmap.name)
1638 free (pfilter->usmap.name);
1639 pfilter->usmap.name = strdup (gfilter->usmap.name);
1640 pfilter->usmap.map = gfilter->usmap.map;
1642 else
1644 if (pfilter->usmap.name)
1645 free (pfilter->usmap.name);
1646 pfilter->usmap.name = NULL;
1647 pfilter->usmap.map = NULL;
1651 /* Peer group's remote AS configuration. */
1653 peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
1655 struct peer_group *group;
1656 struct peer *peer;
1657 struct listnode *node, *nnode;
1659 group = peer_group_lookup (bgp, group_name);
1660 if (! group)
1661 return -1;
1663 if (group->conf->as == *as)
1664 return 0;
1666 /* When we setup peer-group AS number all peer group member's AS
1667 number must be updated to same number. */
1668 peer_as_change (group->conf, *as);
1670 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1672 if (peer->as != *as)
1673 peer_as_change (peer, *as);
1676 return 0;
1680 peer_group_delete (struct peer_group *group)
1682 struct bgp *bgp;
1683 struct peer *peer;
1684 struct listnode *node, *nnode;
1686 bgp = group->bgp;
1688 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1690 peer->group = NULL;
1691 peer_delete (peer);
1693 list_delete (group->peer);
1695 free (group->name);
1696 group->name = NULL;
1698 group->conf->group = NULL;
1699 peer_delete (group->conf);
1701 /* Delete from all peer_group list. */
1702 listnode_delete (bgp->group, group);
1704 peer_group_free (group);
1706 return 0;
1710 peer_group_remote_as_delete (struct peer_group *group)
1712 struct peer *peer;
1713 struct listnode *node, *nnode;
1715 if (! group->conf->as)
1716 return 0;
1718 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
1720 peer->group = NULL;
1721 peer_delete (peer);
1723 list_delete_all_node (group->peer);
1725 group->conf->as = 0;
1727 return 0;
1730 /* Bind specified peer to peer group. */
1732 peer_group_bind (struct bgp *bgp, union sockunion *su,
1733 struct peer_group *group, afi_t afi, safi_t safi, as_t *as)
1735 struct peer *peer;
1736 int first_member = 0;
1738 /* Check peer group's address family. */
1739 if (! group->conf->afc[afi][safi])
1740 return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED;
1742 /* Lookup the peer. */
1743 peer = peer_lookup (bgp, su);
1745 /* Create a new peer. */
1746 if (! peer)
1748 if (! group->conf->as)
1749 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
1751 peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi);
1752 peer->group = group;
1753 peer->af_group[afi][safi] = 1;
1755 peer = peer_lock (peer); /* group->peer list reference */
1756 listnode_add (group->peer, peer);
1757 peer_group2peer_config_copy (group, peer, afi, safi);
1759 return 0;
1762 /* When the peer already belongs to peer group, check the consistency. */
1763 if (peer->af_group[afi][safi])
1765 if (strcmp (peer->group->name, group->name) != 0)
1766 return BGP_ERR_PEER_GROUP_CANT_CHANGE;
1768 return 0;
1771 /* Check current peer group configuration. */
1772 if (peer_group_active (peer)
1773 && strcmp (peer->group->name, group->name) != 0)
1774 return BGP_ERR_PEER_GROUP_MISMATCH;
1776 if (! group->conf->as)
1778 if (peer_sort (group->conf) != BGP_PEER_INTERNAL
1779 && peer_sort (group->conf) != peer_sort (peer))
1781 if (as)
1782 *as = peer->as;
1783 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
1786 if (peer_sort (group->conf) == BGP_PEER_INTERNAL)
1787 first_member = 1;
1790 peer->af_group[afi][safi] = 1;
1791 peer->afc[afi][safi] = 1;
1792 if (! peer->group)
1794 peer->group = group;
1796 peer = peer_lock (peer); /* group->peer list reference */
1797 listnode_add (group->peer, peer);
1799 else
1800 assert (group && peer->group == group);
1802 if (first_member)
1804 /* Advertisement-interval reset */
1805 if (peer_sort (group->conf) == BGP_PEER_IBGP)
1806 group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
1807 else
1808 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
1810 /* ebgp-multihop reset */
1811 if (peer_sort (group->conf) == BGP_PEER_IBGP)
1812 group->conf->ttl = 255;
1814 /* local-as reset */
1815 if (peer_sort (group->conf) != BGP_PEER_EBGP)
1817 group->conf->change_local_as = 0;
1818 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
1822 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1824 struct listnode *pn;
1826 /* If it's not configured as RSERVER_CLIENT in any other address
1827 family, without being member of a peer_group, remove it from
1828 list bgp->rsclient.*/
1829 if (! peer_rsclient_active (peer)
1830 && (pn = listnode_lookup (bgp->rsclient, peer)))
1832 peer_unlock (peer); /* peer rsclient reference */
1833 list_delete_node (bgp->rsclient, pn);
1835 /* Clear our own rsclient rib for this afi/safi. */
1836 bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
1839 bgp_table_finish (&peer->rib[afi][safi]);
1841 /* Import policy. */
1842 if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
1844 free (peer->filter[afi][safi].map[RMAP_IMPORT].name);
1845 peer->filter[afi][safi].map[RMAP_IMPORT].name = NULL;
1846 peer->filter[afi][safi].map[RMAP_IMPORT].map = NULL;
1849 /* Export policy. */
1850 if (! CHECK_FLAG(group->conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1851 && peer->filter[afi][safi].map[RMAP_EXPORT].name)
1853 free (peer->filter[afi][safi].map[RMAP_EXPORT].name);
1854 peer->filter[afi][safi].map[RMAP_EXPORT].name = NULL;
1855 peer->filter[afi][safi].map[RMAP_EXPORT].map = NULL;
1859 peer_group2peer_config_copy (group, peer, afi, safi);
1861 if (peer->status == Established)
1863 peer->last_reset = PEER_DOWN_RMAP_BIND;
1864 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1865 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1867 else
1868 BGP_EVENT_ADD (peer, BGP_Stop);
1870 return 0;
1874 peer_group_unbind (struct bgp *bgp, struct peer *peer,
1875 struct peer_group *group, afi_t afi, safi_t safi)
1877 if (! peer->af_group[afi][safi])
1878 return 0;
1880 if (group != peer->group)
1881 return BGP_ERR_PEER_GROUP_MISMATCH;
1883 peer->af_group[afi][safi] = 0;
1884 peer->afc[afi][safi] = 0;
1885 peer_af_flag_reset (peer, afi, safi);
1887 if (peer->rib[afi][safi])
1888 peer->rib[afi][safi] = NULL;
1890 if (! peer_group_active (peer))
1892 assert (listnode_lookup (group->peer, peer));
1893 peer_unlock (peer); /* peer group list reference */
1894 listnode_delete (group->peer, peer);
1895 peer->group = NULL;
1896 if (group->conf->as)
1898 peer_delete (peer);
1899 return 0;
1901 peer_global_config_reset (peer);
1904 if (peer->status == Established)
1906 peer->last_reset = PEER_DOWN_RMAP_UNBIND;
1907 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
1908 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
1910 else
1911 BGP_EVENT_ADD (peer, BGP_Stop);
1913 return 0;
1916 /* BGP instance creation by `router bgp' commands. */
1917 static struct bgp *
1918 bgp_create (as_t *as, const char *name)
1920 struct bgp *bgp;
1921 afi_t afi;
1922 safi_t safi;
1924 if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
1925 return NULL;
1927 bgp_lock (bgp);
1928 bgp->peer_self = peer_new (bgp);
1929 bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement");
1931 bgp->peer = list_new ();
1932 bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
1934 bgp->group = list_new ();
1935 bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
1937 bgp->rsclient = list_new ();
1938 bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
1940 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1941 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1943 bgp->route[afi][safi] = bgp_table_init (afi, safi);
1944 bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
1945 bgp->rib[afi][safi] = bgp_table_init (afi, safi);
1948 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
1949 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
1950 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
1951 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
1952 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
1954 bgp->as = *as;
1956 if (name)
1957 bgp->name = strdup (name);
1959 return bgp;
1962 /* Return first entry of BGP. */
1963 struct bgp *
1964 bgp_get_default (void)
1966 if (bm->bgp->head)
1967 return (listgetdata (listhead (bm->bgp)));
1968 return NULL;
1971 /* Lookup BGP entry. */
1972 struct bgp *
1973 bgp_lookup (as_t as, const char *name)
1975 struct bgp *bgp;
1976 struct listnode *node, *nnode;
1978 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
1979 if (bgp->as == as
1980 && ((bgp->name == NULL && name == NULL)
1981 || (bgp->name && name && strcmp (bgp->name, name) == 0)))
1982 return bgp;
1983 return NULL;
1986 /* Lookup BGP structure by view name. */
1987 struct bgp *
1988 bgp_lookup_by_name (const char *name)
1990 struct bgp *bgp;
1991 struct listnode *node, *nnode;
1993 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
1994 if ((bgp->name == NULL && name == NULL)
1995 || (bgp->name && name && strcmp (bgp->name, name) == 0))
1996 return bgp;
1997 return NULL;
2000 /* Called from VTY commands. */
2002 bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
2004 struct bgp *bgp;
2006 /* Multiple instance check. */
2007 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
2009 if (name)
2010 bgp = bgp_lookup_by_name (name);
2011 else
2012 bgp = bgp_get_default ();
2014 /* Already exists. */
2015 if (bgp)
2017 if (bgp->as != *as)
2019 *as = bgp->as;
2020 return BGP_ERR_INSTANCE_MISMATCH;
2022 *bgp_val = bgp;
2023 return 0;
2026 else
2028 /* BGP instance name can not be specified for single instance. */
2029 if (name)
2030 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
2032 /* Get default BGP structure if exists. */
2033 bgp = bgp_get_default ();
2035 if (bgp)
2037 if (bgp->as != *as)
2039 *as = bgp->as;
2040 return BGP_ERR_AS_MISMATCH;
2042 *bgp_val = bgp;
2043 return 0;
2047 /* Create BGP server socket, if first instance. */
2048 if (list_isempty(bm->bgp))
2050 if (bgp_socket (bm->port, bm->address) < 0)
2051 return BGP_ERR_INVALID_VALUE;
2054 bgp = bgp_create (as, name);
2055 listnode_add (bm->bgp, bgp);
2056 bgp_router_id_set(bgp, &router_id_zebra);
2057 *bgp_val = bgp;
2059 return 0;
2062 /* Delete BGP instance. */
2064 bgp_delete (struct bgp *bgp)
2066 struct peer *peer;
2067 struct peer_group *group;
2068 struct listnode *node;
2069 struct listnode *next;
2070 afi_t afi;
2071 int i;
2073 /* Delete static route. */
2074 bgp_static_delete (bgp);
2076 /* Unset redistribution. */
2077 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2078 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2079 if (i != ZEBRA_ROUTE_BGP)
2080 bgp_redistribute_unset (bgp, afi, i);
2082 for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
2083 peer_delete (peer);
2085 for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
2086 peer_group_delete (group);
2088 assert (listcount (bgp->rsclient) == 0);
2090 if (bgp->peer_self) {
2091 peer_delete(bgp->peer_self);
2092 bgp->peer_self = NULL;
2095 /* Remove visibility via the master list - there may however still be
2096 * routes to be processed still referencing the struct bgp.
2098 listnode_delete (bm->bgp, bgp);
2099 if (list_isempty(bm->bgp))
2100 bgp_close ();
2102 bgp_unlock(bgp); /* initial reference */
2104 return 0;
2107 static void bgp_free (struct bgp *);
2109 void
2110 bgp_lock (struct bgp *bgp)
2112 ++bgp->lock;
2115 void
2116 bgp_unlock(struct bgp *bgp)
2118 assert(bgp->lock > 0);
2119 if (--bgp->lock == 0)
2120 bgp_free (bgp);
2123 static void
2124 bgp_free (struct bgp *bgp)
2126 afi_t afi;
2127 safi_t safi;
2129 list_delete (bgp->group);
2130 list_delete (bgp->peer);
2131 list_delete (bgp->rsclient);
2133 if (bgp->name)
2134 free (bgp->name);
2136 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2137 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2139 if (bgp->route[afi][safi])
2140 bgp_table_finish (&bgp->route[afi][safi]);
2141 if (bgp->aggregate[afi][safi])
2142 bgp_table_finish (&bgp->aggregate[afi][safi]) ;
2143 if (bgp->rib[afi][safi])
2144 bgp_table_finish (&bgp->rib[afi][safi]);
2146 XFREE (MTYPE_BGP, bgp);
2149 struct peer *
2150 peer_lookup (struct bgp *bgp, union sockunion *su)
2152 struct peer *peer;
2153 struct listnode *node, *nnode;
2155 if (bgp != NULL)
2157 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2158 if (sockunion_same (&peer->su, su)
2159 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2160 return peer;
2162 else if (bm->bgp != NULL)
2164 struct listnode *bgpnode, *nbgpnode;
2166 for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp))
2167 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2168 if (sockunion_same (&peer->su, su)
2169 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2170 return peer;
2172 return NULL;
2175 struct peer *
2176 peer_lookup_with_open (union sockunion *su, as_t remote_as,
2177 struct in_addr *remote_id, int *as)
2179 struct peer *peer;
2180 struct listnode *node;
2181 struct listnode *bgpnode;
2182 struct bgp *bgp;
2184 if (! bm->bgp)
2185 return NULL;
2187 for (ALL_LIST_ELEMENTS_RO (bm->bgp, bgpnode, bgp))
2189 for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
2191 if (sockunion_same (&peer->su, su)
2192 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2194 if (peer->as == remote_as
2195 && peer->remote_id.s_addr == remote_id->s_addr)
2196 return peer;
2197 if (peer->as == remote_as)
2198 *as = 1;
2202 for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
2204 if (sockunion_same (&peer->su, su)
2205 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
2207 if (peer->as == remote_as
2208 && peer->remote_id.s_addr == 0)
2209 return peer;
2210 if (peer->as == remote_as)
2211 *as = 1;
2215 return NULL;
2218 /* If peer is configured at least one address family return 1. */
2220 peer_active (struct peer *peer)
2222 if (peer->afc[AFI_IP][SAFI_UNICAST]
2223 || peer->afc[AFI_IP][SAFI_MULTICAST]
2224 || peer->afc[AFI_IP][SAFI_MPLS_VPN]
2225 || peer->afc[AFI_IP6][SAFI_UNICAST]
2226 || peer->afc[AFI_IP6][SAFI_MULTICAST])
2227 return 1;
2228 return 0;
2231 /* If peer is negotiated at least one address family return 1. */
2233 peer_active_nego (struct peer *peer)
2235 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
2236 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
2237 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
2238 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
2239 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
2240 return 1;
2241 return 0;
2244 /* peer_flag_change_type. */
2245 enum peer_change_type
2247 peer_change_none,
2248 peer_change_reset,
2249 peer_change_reset_in,
2250 peer_change_reset_out,
2253 static void
2254 peer_change_action (struct peer *peer, afi_t afi, safi_t safi,
2255 enum peer_change_type type)
2257 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2258 return;
2260 if (type == peer_change_reset)
2261 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2262 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2263 else if (type == peer_change_reset_in)
2265 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
2266 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
2267 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
2268 else
2269 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2270 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2272 else if (type == peer_change_reset_out)
2273 bgp_announce_route (peer, afi, safi);
2276 struct peer_flag_action
2278 /* Peer's flag. */
2279 u_int32_t flag;
2281 /* This flag can be set for peer-group member. */
2282 u_char not_for_member;
2284 /* Action when the flag is changed. */
2285 enum peer_change_type type;
2287 /* Peer down cause */
2288 u_char peer_down;
2291 static const struct peer_flag_action peer_flag_action_list[] =
2293 { PEER_FLAG_PASSIVE, 0, peer_change_reset },
2294 { PEER_FLAG_SHUTDOWN, 0, peer_change_reset },
2295 { PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none },
2296 { PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none },
2297 { PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none },
2298 { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
2299 { PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
2300 { 0, 0, 0 }
2303 static const struct peer_flag_action peer_af_flag_action_list[] =
2305 { PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out },
2306 { PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out },
2307 { PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out },
2308 { PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in },
2309 { PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset },
2310 { PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset },
2311 { PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out },
2312 { PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out },
2313 { PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out },
2314 { PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out },
2315 { PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in },
2316 { PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset },
2317 { PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
2318 { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
2319 { 0, 0, 0 }
2322 /* Proper action set. */
2323 static int
2324 peer_flag_action_set (const struct peer_flag_action *action_list, int size,
2325 struct peer_flag_action *action, u_int32_t flag)
2327 int i;
2328 int found = 0;
2329 int reset_in = 0;
2330 int reset_out = 0;
2331 const struct peer_flag_action *match = NULL;
2333 /* Check peer's frag action. */
2334 for (i = 0; i < size; i++)
2336 match = &action_list[i];
2338 if (match->flag == 0)
2339 break;
2341 if (match->flag & flag)
2343 found = 1;
2345 if (match->type == peer_change_reset_in)
2346 reset_in = 1;
2347 if (match->type == peer_change_reset_out)
2348 reset_out = 1;
2349 if (match->type == peer_change_reset)
2351 reset_in = 1;
2352 reset_out = 1;
2354 if (match->not_for_member)
2355 action->not_for_member = 1;
2359 /* Set peer clear type. */
2360 if (reset_in && reset_out)
2361 action->type = peer_change_reset;
2362 else if (reset_in)
2363 action->type = peer_change_reset_in;
2364 else if (reset_out)
2365 action->type = peer_change_reset_out;
2366 else
2367 action->type = peer_change_none;
2369 return found;
2372 static void
2373 peer_flag_modify_action (struct peer *peer, u_int32_t flag)
2375 if (flag == PEER_FLAG_SHUTDOWN)
2377 if (CHECK_FLAG (peer->flags, flag))
2379 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2380 peer_nsf_stop (peer);
2382 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2383 if (peer->t_pmax_restart)
2385 BGP_TIMER_OFF (peer->t_pmax_restart);
2386 if (BGP_DEBUG (events, EVENTS))
2387 zlog_debug ("%s Maximum-prefix restart timer canceled",
2388 peer->host);
2391 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2392 peer_nsf_stop (peer);
2394 if (peer->status == Established)
2395 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2396 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2397 else
2398 BGP_EVENT_ADD (peer, BGP_Stop);
2400 else
2402 peer->v_start = BGP_INIT_START_TIMER;
2403 BGP_EVENT_ADD (peer, BGP_Stop);
2406 else if (peer->status == Established)
2408 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
2409 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2410 else if (flag == PEER_FLAG_PASSIVE)
2411 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
2412 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
2413 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
2415 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2416 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2418 else
2419 BGP_EVENT_ADD (peer, BGP_Stop);
2422 /* Change specified peer flag. */
2423 static int
2424 peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
2426 int found;
2427 int size;
2428 struct peer_group *group;
2429 struct listnode *node, *nnode;
2430 struct peer_flag_action action;
2432 memset (&action, 0, sizeof (struct peer_flag_action));
2433 size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
2435 found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
2437 /* No flag action is found. */
2438 if (! found)
2439 return BGP_ERR_INVALID_FLAG;
2441 /* Not for peer-group member. */
2442 if (action.not_for_member && peer_group_active (peer))
2443 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2445 /* When unset the peer-group member's flag we have to check
2446 peer-group configuration. */
2447 if (! set && peer_group_active (peer))
2448 if (CHECK_FLAG (peer->group->conf->flags, flag))
2450 if (flag == PEER_FLAG_SHUTDOWN)
2451 return BGP_ERR_PEER_GROUP_SHUTDOWN;
2452 else
2453 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2456 /* Flag conflict check. */
2457 if (set
2458 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
2459 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
2460 return BGP_ERR_PEER_FLAG_CONFLICT;
2462 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2464 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2465 return 0;
2466 if (! set && ! CHECK_FLAG (peer->flags, flag))
2467 return 0;
2470 if (set)
2471 SET_FLAG (peer->flags, flag);
2472 else
2473 UNSET_FLAG (peer->flags, flag);
2475 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2477 if (action.type == peer_change_reset)
2478 peer_flag_modify_action (peer, flag);
2480 return 0;
2483 /* peer-group member updates. */
2484 group = peer->group;
2486 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2488 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2489 continue;
2491 if (! set && ! CHECK_FLAG (peer->flags, flag))
2492 continue;
2494 if (set)
2495 SET_FLAG (peer->flags, flag);
2496 else
2497 UNSET_FLAG (peer->flags, flag);
2499 if (action.type == peer_change_reset)
2500 peer_flag_modify_action (peer, flag);
2502 return 0;
2506 peer_flag_set (struct peer *peer, u_int32_t flag)
2508 return peer_flag_modify (peer, flag, 1);
2512 peer_flag_unset (struct peer *peer, u_int32_t flag)
2514 return peer_flag_modify (peer, flag, 0);
2517 static int
2518 peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
2520 if (peer->af_group[afi][safi])
2521 return 1;
2522 return 0;
2525 static int
2526 peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
2527 int set)
2529 int found;
2530 int size;
2531 struct listnode *node, *nnode;
2532 struct peer_group *group;
2533 struct peer_flag_action action;
2535 memset (&action, 0, sizeof (struct peer_flag_action));
2536 size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action);
2538 found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag);
2540 /* No flag action is found. */
2541 if (! found)
2542 return BGP_ERR_INVALID_FLAG;
2544 /* Adress family must be activated. */
2545 if (! peer->afc[afi][safi])
2546 return BGP_ERR_PEER_INACTIVE;
2548 /* Not for peer-group member. */
2549 if (action.not_for_member && peer_is_group_member (peer, afi, safi))
2550 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2552 /* Spcecial check for reflector client. */
2553 if (flag & PEER_FLAG_REFLECTOR_CLIENT
2554 && peer_sort (peer) != BGP_PEER_IBGP)
2555 return BGP_ERR_NOT_INTERNAL_PEER;
2557 /* Spcecial check for remove-private-AS. */
2558 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
2559 && peer_sort (peer) == BGP_PEER_IBGP)
2560 return BGP_ERR_REMOVE_PRIVATE_AS;
2562 /* When unset the peer-group member's flag we have to check
2563 peer-group configuration. */
2564 if (! set && peer->af_group[afi][safi])
2565 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
2566 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2568 /* When current flag configuration is same as requested one. */
2569 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2571 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2572 return 0;
2573 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2574 return 0;
2577 if (set)
2578 SET_FLAG (peer->af_flags[afi][safi], flag);
2579 else
2580 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2582 /* Execute action when peer is established. */
2583 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2584 && peer->status == Established)
2586 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2587 bgp_clear_adj_in (peer, afi, safi);
2588 else
2590 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2591 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2592 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2593 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2594 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2595 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2596 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2597 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2599 peer_change_action (peer, afi, safi, action.type);
2604 /* Peer group member updates. */
2605 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2607 group = peer->group;
2609 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2611 if (! peer->af_group[afi][safi])
2612 continue;
2614 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2615 continue;
2617 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2618 continue;
2620 if (set)
2621 SET_FLAG (peer->af_flags[afi][safi], flag);
2622 else
2623 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2625 if (peer->status == Established)
2627 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2628 bgp_clear_adj_in (peer, afi, safi);
2629 else
2631 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2632 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2633 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2634 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2635 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2636 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2637 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2638 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2640 peer_change_action (peer, afi, safi, action.type);
2645 return 0;
2649 peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2651 return peer_af_flag_modify (peer, afi, safi, flag, 1);
2655 peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2657 return peer_af_flag_modify (peer, afi, safi, flag, 0);
2660 /* EBGP multihop configuration. */
2662 peer_ebgp_multihop_set (struct peer *peer, int ttl)
2664 struct peer_group *group;
2665 struct listnode *node, *nnode;
2667 if (peer_sort (peer) == BGP_PEER_IBGP)
2668 return 0;
2670 peer->ttl = ttl;
2672 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2674 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2675 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2677 else
2679 group = peer->group;
2680 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2682 if (peer_sort (peer) == BGP_PEER_IBGP)
2683 continue;
2685 peer->ttl = group->conf->ttl;
2687 if (peer->fd >= 0)
2688 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2691 return 0;
2695 peer_ebgp_multihop_unset (struct peer *peer)
2697 struct peer_group *group;
2698 struct listnode *node, *nnode;
2700 if (peer_sort (peer) == BGP_PEER_IBGP)
2701 return 0;
2703 if (peer_group_active (peer))
2704 peer->ttl = peer->group->conf->ttl;
2705 else
2706 peer->ttl = 1;
2708 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2710 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
2711 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2713 else
2715 group = peer->group;
2716 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2718 if (peer_sort (peer) == BGP_PEER_IBGP)
2719 continue;
2721 peer->ttl = 1;
2723 if (peer->fd >= 0)
2724 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2727 return 0;
2730 /* Neighbor description. */
2732 peer_description_set (struct peer *peer, char *desc)
2734 if (peer->desc)
2735 XFREE (MTYPE_PEER_DESC, peer->desc);
2737 peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
2739 return 0;
2743 peer_description_unset (struct peer *peer)
2745 if (peer->desc)
2746 XFREE (MTYPE_PEER_DESC, peer->desc);
2748 peer->desc = NULL;
2750 return 0;
2753 /* Neighbor update-source. */
2755 peer_update_source_if_set (struct peer *peer, const char *ifname)
2757 struct peer_group *group;
2758 struct listnode *node, *nnode;
2760 if (peer->update_if)
2762 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2763 && strcmp (peer->update_if, ifname) == 0)
2764 return 0;
2766 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2767 peer->update_if = NULL;
2770 if (peer->update_source)
2772 sockunion_free (peer->update_source);
2773 peer->update_source = NULL;
2776 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2778 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2780 if (peer->status == Established)
2782 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2783 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2784 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2786 else
2787 BGP_EVENT_ADD (peer, BGP_Stop);
2788 return 0;
2791 /* peer-group member updates. */
2792 group = peer->group;
2793 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2795 if (peer->update_if)
2797 if (strcmp (peer->update_if, ifname) == 0)
2798 continue;
2800 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2801 peer->update_if = NULL;
2804 if (peer->update_source)
2806 sockunion_free (peer->update_source);
2807 peer->update_source = NULL;
2810 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2812 if (peer->status == Established)
2814 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2815 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2816 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2818 else
2819 BGP_EVENT_ADD (peer, BGP_Stop);
2821 return 0;
2825 peer_update_source_addr_set (struct peer *peer, union sockunion *su)
2827 struct peer_group *group;
2828 struct listnode *node, *nnode;
2830 if (peer->update_source)
2832 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2833 && sockunion_cmp (peer->update_source, su) == 0)
2834 return 0;
2835 sockunion_free (peer->update_source);
2836 peer->update_source = NULL;
2839 if (peer->update_if)
2841 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2842 peer->update_if = NULL;
2845 peer->update_source = sockunion_dup (su);
2847 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2849 if (peer->status == Established)
2851 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2852 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2853 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2855 else
2856 BGP_EVENT_ADD (peer, BGP_Stop);
2857 return 0;
2860 /* peer-group member updates. */
2861 group = peer->group;
2862 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2864 if (peer->update_source)
2866 if (sockunion_cmp (peer->update_source, su) == 0)
2867 continue;
2868 sockunion_free (peer->update_source);
2869 peer->update_source = NULL;
2872 if (peer->update_if)
2874 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2875 peer->update_if = NULL;
2878 peer->update_source = sockunion_dup (su);
2880 if (peer->status == Established)
2882 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2883 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2884 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2886 else
2887 BGP_EVENT_ADD (peer, BGP_Stop);
2889 return 0;
2893 peer_update_source_unset (struct peer *peer)
2895 union sockunion *su;
2896 struct peer_group *group;
2897 struct listnode *node, *nnode;
2899 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2900 && ! peer->update_source
2901 && ! peer->update_if)
2902 return 0;
2904 if (peer->update_source)
2906 sockunion_free (peer->update_source);
2907 peer->update_source = NULL;
2909 if (peer->update_if)
2911 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2912 peer->update_if = NULL;
2915 if (peer_group_active (peer))
2917 group = peer->group;
2919 if (group->conf->update_source)
2921 su = sockunion_dup (group->conf->update_source);
2922 peer->update_source = su;
2924 else if (group->conf->update_if)
2925 peer->update_if =
2926 XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
2929 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2931 if (peer->status == Established)
2933 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2934 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2935 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2937 else
2938 BGP_EVENT_ADD (peer, BGP_Stop);
2939 return 0;
2942 /* peer-group member updates. */
2943 group = peer->group;
2944 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2946 if (! peer->update_source && ! peer->update_if)
2947 continue;
2949 if (peer->update_source)
2951 sockunion_free (peer->update_source);
2952 peer->update_source = NULL;
2955 if (peer->update_if)
2957 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2958 peer->update_if = NULL;
2961 if (peer->status == Established)
2963 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2964 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2965 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2967 else
2968 BGP_EVENT_ADD (peer, BGP_Stop);
2970 return 0;
2974 peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
2975 const char *rmap)
2977 struct peer_group *group;
2978 struct listnode *node, *nnode;
2980 /* Adress family must be activated. */
2981 if (! peer->afc[afi][safi])
2982 return BGP_ERR_PEER_INACTIVE;
2984 /* Default originate can't be used for peer group memeber. */
2985 if (peer_is_group_member (peer, afi, safi))
2986 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2988 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
2989 || (rmap && ! peer->default_rmap[afi][safi].name)
2990 || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
2992 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
2994 if (rmap)
2996 if (peer->default_rmap[afi][safi].name)
2997 free (peer->default_rmap[afi][safi].name);
2998 peer->default_rmap[afi][safi].name = strdup (rmap);
2999 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
3003 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3005 if (peer->status == Established && peer->afc_nego[afi][safi])
3006 bgp_default_originate (peer, afi, safi, 0);
3007 return 0;
3010 /* peer-group member updates. */
3011 group = peer->group;
3012 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3014 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3016 if (rmap)
3018 if (peer->default_rmap[afi][safi].name)
3019 free (peer->default_rmap[afi][safi].name);
3020 peer->default_rmap[afi][safi].name = strdup (rmap);
3021 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
3024 if (peer->status == Established && peer->afc_nego[afi][safi])
3025 bgp_default_originate (peer, afi, safi, 0);
3027 return 0;
3031 peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
3033 struct peer_group *group;
3034 struct listnode *node, *nnode;
3036 /* Adress family must be activated. */
3037 if (! peer->afc[afi][safi])
3038 return BGP_ERR_PEER_INACTIVE;
3040 /* Default originate can't be used for peer group memeber. */
3041 if (peer_is_group_member (peer, afi, safi))
3042 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3044 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
3046 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3048 if (peer->default_rmap[afi][safi].name)
3049 free (peer->default_rmap[afi][safi].name);
3050 peer->default_rmap[afi][safi].name = NULL;
3051 peer->default_rmap[afi][safi].map = NULL;
3054 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3056 if (peer->status == Established && peer->afc_nego[afi][safi])
3057 bgp_default_originate (peer, afi, safi, 1);
3058 return 0;
3061 /* peer-group member updates. */
3062 group = peer->group;
3063 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3065 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3067 if (peer->default_rmap[afi][safi].name)
3068 free (peer->default_rmap[afi][safi].name);
3069 peer->default_rmap[afi][safi].name = NULL;
3070 peer->default_rmap[afi][safi].map = NULL;
3072 if (peer->status == Established && peer->afc_nego[afi][safi])
3073 bgp_default_originate (peer, afi, safi, 1);
3075 return 0;
3079 peer_port_set (struct peer *peer, u_int16_t port)
3081 peer->port = port;
3082 return 0;
3086 peer_port_unset (struct peer *peer)
3088 peer->port = BGP_PORT_DEFAULT;
3089 return 0;
3092 /* neighbor weight. */
3094 peer_weight_set (struct peer *peer, u_int16_t weight)
3096 struct peer_group *group;
3097 struct listnode *node, *nnode;
3099 SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3100 peer->weight = weight;
3102 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3103 return 0;
3105 /* peer-group member updates. */
3106 group = peer->group;
3107 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3109 peer->weight = group->conf->weight;
3111 return 0;
3115 peer_weight_unset (struct peer *peer)
3117 struct peer_group *group;
3118 struct listnode *node, *nnode;
3120 /* Set default weight. */
3121 if (peer_group_active (peer))
3122 peer->weight = peer->group->conf->weight;
3123 else
3124 peer->weight = 0;
3126 UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3128 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3129 return 0;
3131 /* peer-group member updates. */
3132 group = peer->group;
3133 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3135 peer->weight = 0;
3137 return 0;
3141 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
3143 struct peer_group *group;
3144 struct listnode *node, *nnode;
3146 /* Not for peer group memeber. */
3147 if (peer_group_active (peer))
3148 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3150 /* keepalive value check. */
3151 if (keepalive > 65535)
3152 return BGP_ERR_INVALID_VALUE;
3154 /* Holdtime value check. */
3155 if (holdtime > 65535)
3156 return BGP_ERR_INVALID_VALUE;
3158 /* Holdtime value must be either 0 or greater than 3. */
3159 if (holdtime < 3 && holdtime != 0)
3160 return BGP_ERR_INVALID_VALUE;
3162 /* Set value to the configuration. */
3163 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3164 peer->holdtime = holdtime;
3165 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
3167 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3168 return 0;
3170 /* peer-group member updates. */
3171 group = peer->group;
3172 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3174 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3175 peer->holdtime = group->conf->holdtime;
3176 peer->keepalive = group->conf->keepalive;
3178 return 0;
3182 peer_timers_unset (struct peer *peer)
3184 struct peer_group *group;
3185 struct listnode *node, *nnode;
3187 if (peer_group_active (peer))
3188 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3190 /* Clear configuration. */
3191 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3192 peer->keepalive = 0;
3193 peer->holdtime = 0;
3195 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3196 return 0;
3198 /* peer-group member updates. */
3199 group = peer->group;
3200 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3202 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3203 peer->holdtime = 0;
3204 peer->keepalive = 0;
3207 return 0;
3211 peer_timers_connect_set (struct peer *peer, u_int32_t connect)
3213 if (peer_group_active (peer))
3214 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3216 if (connect > 65535)
3217 return BGP_ERR_INVALID_VALUE;
3219 /* Set value to the configuration. */
3220 SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3221 peer->connect = connect;
3223 /* Set value to timer setting. */
3224 peer->v_connect = connect;
3226 return 0;
3230 peer_timers_connect_unset (struct peer *peer)
3232 if (peer_group_active (peer))
3233 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3235 /* Clear configuration. */
3236 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3237 peer->connect = 0;
3239 /* Set timer setting to default value. */
3240 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
3242 return 0;
3246 peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
3248 if (peer_group_active (peer))
3249 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3251 if (routeadv > 600)
3252 return BGP_ERR_INVALID_VALUE;
3254 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3255 peer->routeadv = routeadv;
3256 peer->v_routeadv = routeadv;
3258 return 0;
3262 peer_advertise_interval_unset (struct peer *peer)
3264 if (peer_group_active (peer))
3265 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3267 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3268 peer->routeadv = 0;
3270 if (peer_sort (peer) == BGP_PEER_IBGP)
3271 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
3272 else
3273 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
3275 return 0;
3278 /* neighbor interface */
3280 peer_interface_set (struct peer *peer, const char *str)
3282 if (peer->ifname)
3283 free (peer->ifname);
3284 peer->ifname = strdup (str);
3286 return 0;
3290 peer_interface_unset (struct peer *peer)
3292 if (peer->ifname)
3293 free (peer->ifname);
3294 peer->ifname = NULL;
3296 return 0;
3299 /* Allow-as in. */
3301 peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
3303 struct peer_group *group;
3304 struct listnode *node, *nnode;
3306 if (allow_num < 1 || allow_num > 10)
3307 return BGP_ERR_INVALID_VALUE;
3309 if (peer->allowas_in[afi][safi] != allow_num)
3311 peer->allowas_in[afi][safi] = allow_num;
3312 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3313 peer_change_action (peer, afi, safi, peer_change_reset_in);
3316 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3317 return 0;
3319 group = peer->group;
3320 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3322 if (peer->allowas_in[afi][safi] != allow_num)
3324 peer->allowas_in[afi][safi] = allow_num;
3325 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3326 peer_change_action (peer, afi, safi, peer_change_reset_in);
3330 return 0;
3334 peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
3336 struct peer_group *group;
3337 struct listnode *node, *nnode;
3339 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3341 peer->allowas_in[afi][safi] = 0;
3342 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3345 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3346 return 0;
3348 group = peer->group;
3349 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3351 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3353 peer->allowas_in[afi][safi] = 0;
3354 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3357 return 0;
3361 peer_local_as_set (struct peer *peer, as_t as, int no_prepend)
3363 struct bgp *bgp = peer->bgp;
3364 struct peer_group *group;
3365 struct listnode *node, *nnode;
3367 if (peer_sort (peer) != BGP_PEER_EBGP
3368 && peer_sort (peer) != BGP_PEER_INTERNAL)
3369 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
3371 if (bgp->as == as)
3372 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
3374 if (peer_group_active (peer))
3375 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3377 if (peer->change_local_as == as &&
3378 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
3379 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)))
3380 return 0;
3382 peer->change_local_as = as;
3383 if (no_prepend)
3384 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3385 else
3386 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3388 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3390 if (peer->status == Established)
3392 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3393 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3394 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3396 else
3397 BGP_EVENT_ADD (peer, BGP_Stop);
3399 return 0;
3402 group = peer->group;
3403 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3405 peer->change_local_as = as;
3406 if (no_prepend)
3407 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3408 else
3409 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3411 if (peer->status == Established)
3413 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3414 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3415 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3417 else
3418 BGP_EVENT_ADD (peer, BGP_Stop);
3421 return 0;
3425 peer_local_as_unset (struct peer *peer)
3427 struct peer_group *group;
3428 struct listnode *node, *nnode;
3430 if (peer_group_active (peer))
3431 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3433 if (! peer->change_local_as)
3434 return 0;
3436 peer->change_local_as = 0;
3437 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3439 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3441 if (peer->status == Established)
3443 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3444 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3445 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3447 else
3448 BGP_EVENT_ADD (peer, BGP_Stop);
3450 return 0;
3453 group = peer->group;
3454 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3456 peer->change_local_as = 0;
3457 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3459 if (peer->status == Established)
3461 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3462 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3463 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3465 else
3466 BGP_EVENT_ADD (peer, BGP_Stop);
3468 return 0;
3471 /* Set password for authenticating with the peer. */
3473 peer_password_set (struct peer *peer, const char *password)
3475 struct listnode *nn, *nnode;
3476 int len = password ? strlen(password) : 0;
3477 int ret = BGP_SUCCESS;
3479 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
3480 return BGP_ERR_INVALID_VALUE;
3482 if (peer->password && strcmp (peer->password, password) == 0
3483 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3484 return 0;
3486 if (peer->password)
3487 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3489 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
3491 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3493 if (peer->status == Established)
3494 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3495 else
3496 BGP_EVENT_ADD (peer, BGP_Stop);
3498 return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
3501 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3503 if (peer->password && strcmp (peer->password, password) == 0)
3504 continue;
3506 if (peer->password)
3507 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3509 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
3511 if (peer->status == Established)
3512 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3513 else
3514 BGP_EVENT_ADD (peer, BGP_Stop);
3516 if (bgp_md5_set (peer) < 0)
3517 ret = BGP_ERR_TCPSIG_FAILED;
3520 return ret;
3524 peer_password_unset (struct peer *peer)
3526 struct listnode *nn, *nnode;
3528 if (!peer->password
3529 && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3530 return 0;
3532 if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3534 if (peer_group_active (peer)
3535 && peer->group->conf->password
3536 && strcmp (peer->group->conf->password, peer->password) == 0)
3537 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
3539 if (peer->status == Established)
3540 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3541 else
3542 BGP_EVENT_ADD (peer, BGP_Stop);
3544 if (peer->password)
3545 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3547 peer->password = NULL;
3549 bgp_md5_set (peer);
3551 return 0;
3554 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3555 peer->password = NULL;
3557 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3559 if (!peer->password)
3560 continue;
3562 if (peer->status == Established)
3563 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3564 else
3565 BGP_EVENT_ADD (peer, BGP_Stop);
3567 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3568 peer->password = NULL;
3570 bgp_md5_set (peer);
3573 return 0;
3576 /* Set distribute list to the peer. */
3578 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3579 const char *name)
3581 struct bgp_filter *filter;
3582 struct peer_group *group;
3583 struct listnode *node, *nnode;
3585 if (! peer->afc[afi][safi])
3586 return BGP_ERR_PEER_INACTIVE;
3588 if (direct != FILTER_IN && direct != FILTER_OUT)
3589 return BGP_ERR_INVALID_VALUE;
3591 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3592 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3594 filter = &peer->filter[afi][safi];
3596 if (filter->plist[direct].name)
3597 return BGP_ERR_PEER_FILTER_CONFLICT;
3599 if (filter->dlist[direct].name)
3600 free (filter->dlist[direct].name);
3601 filter->dlist[direct].name = strdup (name);
3602 filter->dlist[direct].alist = access_list_lookup (afi, name);
3604 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3605 return 0;
3607 group = peer->group;
3608 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3610 filter = &peer->filter[afi][safi];
3612 if (! peer->af_group[afi][safi])
3613 continue;
3615 if (filter->dlist[direct].name)
3616 free (filter->dlist[direct].name);
3617 filter->dlist[direct].name = strdup (name);
3618 filter->dlist[direct].alist = access_list_lookup (afi, name);
3621 return 0;
3625 peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3627 struct bgp_filter *filter;
3628 struct bgp_filter *gfilter;
3629 struct peer_group *group;
3630 struct listnode *node, *nnode;
3632 if (! peer->afc[afi][safi])
3633 return BGP_ERR_PEER_INACTIVE;
3635 if (direct != FILTER_IN && direct != FILTER_OUT)
3636 return BGP_ERR_INVALID_VALUE;
3638 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3639 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3641 filter = &peer->filter[afi][safi];
3643 /* apply peer-group filter */
3644 if (peer->af_group[afi][safi])
3646 gfilter = &peer->group->conf->filter[afi][safi];
3648 if (gfilter->dlist[direct].name)
3650 if (filter->dlist[direct].name)
3651 free (filter->dlist[direct].name);
3652 filter->dlist[direct].name = strdup (gfilter->dlist[direct].name);
3653 filter->dlist[direct].alist = gfilter->dlist[direct].alist;
3654 return 0;
3658 if (filter->dlist[direct].name)
3659 free (filter->dlist[direct].name);
3660 filter->dlist[direct].name = NULL;
3661 filter->dlist[direct].alist = NULL;
3663 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3664 return 0;
3666 group = peer->group;
3667 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3669 filter = &peer->filter[afi][safi];
3671 if (! peer->af_group[afi][safi])
3672 continue;
3674 if (filter->dlist[direct].name)
3675 free (filter->dlist[direct].name);
3676 filter->dlist[direct].name = NULL;
3677 filter->dlist[direct].alist = NULL;
3680 return 0;
3683 /* Update distribute list. */
3684 static void
3685 peer_distribute_update (struct access_list *access)
3687 afi_t afi;
3688 safi_t safi;
3689 int direct;
3690 struct listnode *mnode, *mnnode;
3691 struct listnode *node, *nnode;
3692 struct bgp *bgp;
3693 struct peer *peer;
3694 struct peer_group *group;
3695 struct bgp_filter *filter;
3697 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3699 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3701 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3702 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3704 filter = &peer->filter[afi][safi];
3706 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3708 if (filter->dlist[direct].name)
3709 filter->dlist[direct].alist =
3710 access_list_lookup (afi, filter->dlist[direct].name);
3711 else
3712 filter->dlist[direct].alist = NULL;
3716 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3718 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3719 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3721 filter = &group->conf->filter[afi][safi];
3723 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3725 if (filter->dlist[direct].name)
3726 filter->dlist[direct].alist =
3727 access_list_lookup (afi, filter->dlist[direct].name);
3728 else
3729 filter->dlist[direct].alist = NULL;
3736 /* Set prefix list to the peer. */
3738 peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3739 const char *name)
3741 struct bgp_filter *filter;
3742 struct peer_group *group;
3743 struct listnode *node, *nnode;
3745 if (! peer->afc[afi][safi])
3746 return BGP_ERR_PEER_INACTIVE;
3748 if (direct != FILTER_IN && direct != FILTER_OUT)
3749 return BGP_ERR_INVALID_VALUE;
3751 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3752 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3754 filter = &peer->filter[afi][safi];
3756 if (filter->dlist[direct].name)
3757 return BGP_ERR_PEER_FILTER_CONFLICT;
3759 if (filter->plist[direct].name)
3760 free (filter->plist[direct].name);
3761 filter->plist[direct].name = strdup (name);
3762 filter->plist[direct].plist = prefix_list_lookup (afi, name);
3764 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3765 return 0;
3767 group = peer->group;
3768 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3770 filter = &peer->filter[afi][safi];
3772 if (! peer->af_group[afi][safi])
3773 continue;
3775 if (filter->plist[direct].name)
3776 free (filter->plist[direct].name);
3777 filter->plist[direct].name = strdup (name);
3778 filter->plist[direct].plist = prefix_list_lookup (afi, name);
3780 return 0;
3784 peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3786 struct bgp_filter *filter;
3787 struct bgp_filter *gfilter;
3788 struct peer_group *group;
3789 struct listnode *node, *nnode;
3791 if (! peer->afc[afi][safi])
3792 return BGP_ERR_PEER_INACTIVE;
3794 if (direct != FILTER_IN && direct != FILTER_OUT)
3795 return BGP_ERR_INVALID_VALUE;
3797 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3798 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3800 filter = &peer->filter[afi][safi];
3802 /* apply peer-group filter */
3803 if (peer->af_group[afi][safi])
3805 gfilter = &peer->group->conf->filter[afi][safi];
3807 if (gfilter->plist[direct].name)
3809 if (filter->plist[direct].name)
3810 free (filter->plist[direct].name);
3811 filter->plist[direct].name = strdup (gfilter->plist[direct].name);
3812 filter->plist[direct].plist = gfilter->plist[direct].plist;
3813 return 0;
3817 if (filter->plist[direct].name)
3818 free (filter->plist[direct].name);
3819 filter->plist[direct].name = NULL;
3820 filter->plist[direct].plist = NULL;
3822 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3823 return 0;
3825 group = peer->group;
3826 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3828 filter = &peer->filter[afi][safi];
3830 if (! peer->af_group[afi][safi])
3831 continue;
3833 if (filter->plist[direct].name)
3834 free (filter->plist[direct].name);
3835 filter->plist[direct].name = NULL;
3836 filter->plist[direct].plist = NULL;
3839 return 0;
3842 /* Update prefix-list list. */
3843 static void
3844 peer_prefix_list_update (struct prefix_list *plist)
3846 struct listnode *mnode, *mnnode;
3847 struct listnode *node, *nnode;
3848 struct bgp *bgp;
3849 struct peer *peer;
3850 struct peer_group *group;
3851 struct bgp_filter *filter;
3852 afi_t afi;
3853 safi_t safi;
3854 int direct;
3856 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3858 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3860 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3861 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3863 filter = &peer->filter[afi][safi];
3865 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3867 if (filter->plist[direct].name)
3868 filter->plist[direct].plist =
3869 prefix_list_lookup (afi, filter->plist[direct].name);
3870 else
3871 filter->plist[direct].plist = NULL;
3875 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3877 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3878 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3880 filter = &group->conf->filter[afi][safi];
3882 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3884 if (filter->plist[direct].name)
3885 filter->plist[direct].plist =
3886 prefix_list_lookup (afi, filter->plist[direct].name);
3887 else
3888 filter->plist[direct].plist = NULL;
3896 peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3897 const char *name)
3899 struct bgp_filter *filter;
3900 struct peer_group *group;
3901 struct listnode *node, *nnode;
3903 if (! peer->afc[afi][safi])
3904 return BGP_ERR_PEER_INACTIVE;
3906 if (direct != FILTER_IN && direct != FILTER_OUT)
3907 return BGP_ERR_INVALID_VALUE;
3909 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3910 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3912 filter = &peer->filter[afi][safi];
3914 if (filter->aslist[direct].name)
3915 free (filter->aslist[direct].name);
3916 filter->aslist[direct].name = strdup (name);
3917 filter->aslist[direct].aslist = as_list_lookup (name);
3919 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3920 return 0;
3922 group = peer->group;
3923 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3925 filter = &peer->filter[afi][safi];
3927 if (! peer->af_group[afi][safi])
3928 continue;
3930 if (filter->aslist[direct].name)
3931 free (filter->aslist[direct].name);
3932 filter->aslist[direct].name = strdup (name);
3933 filter->aslist[direct].aslist = as_list_lookup (name);
3935 return 0;
3939 peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
3941 struct bgp_filter *filter;
3942 struct bgp_filter *gfilter;
3943 struct peer_group *group;
3944 struct listnode *node, *nnode;
3946 if (! peer->afc[afi][safi])
3947 return BGP_ERR_PEER_INACTIVE;
3949 if (direct != FILTER_IN && direct != FILTER_OUT)
3950 return BGP_ERR_INVALID_VALUE;
3952 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3953 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3955 filter = &peer->filter[afi][safi];
3957 /* apply peer-group filter */
3958 if (peer->af_group[afi][safi])
3960 gfilter = &peer->group->conf->filter[afi][safi];
3962 if (gfilter->aslist[direct].name)
3964 if (filter->aslist[direct].name)
3965 free (filter->aslist[direct].name);
3966 filter->aslist[direct].name = strdup (gfilter->aslist[direct].name);
3967 filter->aslist[direct].aslist = gfilter->aslist[direct].aslist;
3968 return 0;
3972 if (filter->aslist[direct].name)
3973 free (filter->aslist[direct].name);
3974 filter->aslist[direct].name = NULL;
3975 filter->aslist[direct].aslist = NULL;
3977 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3978 return 0;
3980 group = peer->group;
3981 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3983 filter = &peer->filter[afi][safi];
3985 if (! peer->af_group[afi][safi])
3986 continue;
3988 if (filter->aslist[direct].name)
3989 free (filter->aslist[direct].name);
3990 filter->aslist[direct].name = NULL;
3991 filter->aslist[direct].aslist = NULL;
3994 return 0;
3997 static void
3998 peer_aslist_update (void)
4000 afi_t afi;
4001 safi_t safi;
4002 int direct;
4003 struct listnode *mnode, *mnnode;
4004 struct listnode *node, *nnode;
4005 struct bgp *bgp;
4006 struct peer *peer;
4007 struct peer_group *group;
4008 struct bgp_filter *filter;
4010 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4012 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4014 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4015 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4017 filter = &peer->filter[afi][safi];
4019 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4021 if (filter->aslist[direct].name)
4022 filter->aslist[direct].aslist =
4023 as_list_lookup (filter->aslist[direct].name);
4024 else
4025 filter->aslist[direct].aslist = NULL;
4029 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4031 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4032 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4034 filter = &group->conf->filter[afi][safi];
4036 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4038 if (filter->aslist[direct].name)
4039 filter->aslist[direct].aslist =
4040 as_list_lookup (filter->aslist[direct].name);
4041 else
4042 filter->aslist[direct].aslist = NULL;
4049 /* Set route-map to the peer. */
4051 peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
4052 const char *name)
4054 struct bgp_filter *filter;
4055 struct peer_group *group;
4056 struct listnode *node, *nnode;
4058 if (! peer->afc[afi][safi])
4059 return BGP_ERR_PEER_INACTIVE;
4061 if (direct != RMAP_IN && direct != RMAP_OUT &&
4062 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4063 return BGP_ERR_INVALID_VALUE;
4065 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4066 && peer_is_group_member (peer, afi, safi))
4067 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4069 filter = &peer->filter[afi][safi];
4071 if (filter->map[direct].name)
4072 free (filter->map[direct].name);
4074 filter->map[direct].name = strdup (name);
4075 filter->map[direct].map = route_map_lookup_by_name (name);
4077 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4078 return 0;
4080 group = peer->group;
4081 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4083 filter = &peer->filter[afi][safi];
4085 if (! peer->af_group[afi][safi])
4086 continue;
4088 if (filter->map[direct].name)
4089 free (filter->map[direct].name);
4090 filter->map[direct].name = strdup (name);
4091 filter->map[direct].map = route_map_lookup_by_name (name);
4093 return 0;
4096 /* Unset route-map from the peer. */
4098 peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
4100 struct bgp_filter *filter;
4101 struct bgp_filter *gfilter;
4102 struct peer_group *group;
4103 struct listnode *node, *nnode;
4105 if (! peer->afc[afi][safi])
4106 return BGP_ERR_PEER_INACTIVE;
4108 if (direct != RMAP_IN && direct != RMAP_OUT &&
4109 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4110 return BGP_ERR_INVALID_VALUE;
4112 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4113 && peer_is_group_member (peer, afi, safi))
4114 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4116 filter = &peer->filter[afi][safi];
4118 /* apply peer-group filter */
4119 if (peer->af_group[afi][safi])
4121 gfilter = &peer->group->conf->filter[afi][safi];
4123 if (gfilter->map[direct].name)
4125 if (filter->map[direct].name)
4126 free (filter->map[direct].name);
4127 filter->map[direct].name = strdup (gfilter->map[direct].name);
4128 filter->map[direct].map = gfilter->map[direct].map;
4129 return 0;
4133 if (filter->map[direct].name)
4134 free (filter->map[direct].name);
4135 filter->map[direct].name = NULL;
4136 filter->map[direct].map = NULL;
4138 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4139 return 0;
4141 group = peer->group;
4142 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4144 filter = &peer->filter[afi][safi];
4146 if (! peer->af_group[afi][safi])
4147 continue;
4149 if (filter->map[direct].name)
4150 free (filter->map[direct].name);
4151 filter->map[direct].name = NULL;
4152 filter->map[direct].map = NULL;
4154 return 0;
4157 /* Set unsuppress-map to the peer. */
4159 peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
4160 const char *name)
4162 struct bgp_filter *filter;
4163 struct peer_group *group;
4164 struct listnode *node, *nnode;
4166 if (! peer->afc[afi][safi])
4167 return BGP_ERR_PEER_INACTIVE;
4169 if (peer_is_group_member (peer, afi, safi))
4170 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4172 filter = &peer->filter[afi][safi];
4174 if (filter->usmap.name)
4175 free (filter->usmap.name);
4177 filter->usmap.name = strdup (name);
4178 filter->usmap.map = route_map_lookup_by_name (name);
4180 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4181 return 0;
4183 group = peer->group;
4184 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4186 filter = &peer->filter[afi][safi];
4188 if (! peer->af_group[afi][safi])
4189 continue;
4191 if (filter->usmap.name)
4192 free (filter->usmap.name);
4193 filter->usmap.name = strdup (name);
4194 filter->usmap.map = route_map_lookup_by_name (name);
4196 return 0;
4199 /* Unset route-map from the peer. */
4201 peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
4203 struct bgp_filter *filter;
4204 struct peer_group *group;
4205 struct listnode *node, *nnode;
4207 if (! peer->afc[afi][safi])
4208 return BGP_ERR_PEER_INACTIVE;
4210 if (peer_is_group_member (peer, afi, safi))
4211 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4213 filter = &peer->filter[afi][safi];
4215 if (filter->usmap.name)
4216 free (filter->usmap.name);
4217 filter->usmap.name = NULL;
4218 filter->usmap.map = NULL;
4220 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4221 return 0;
4223 group = peer->group;
4224 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4226 filter = &peer->filter[afi][safi];
4228 if (! peer->af_group[afi][safi])
4229 continue;
4231 if (filter->usmap.name)
4232 free (filter->usmap.name);
4233 filter->usmap.name = NULL;
4234 filter->usmap.map = NULL;
4236 return 0;
4240 peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
4241 u_int32_t max, u_char threshold,
4242 int warning, u_int16_t restart)
4244 struct peer_group *group;
4245 struct listnode *node, *nnode;
4247 if (! peer->afc[afi][safi])
4248 return BGP_ERR_PEER_INACTIVE;
4250 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4251 peer->pmax[afi][safi] = max;
4252 peer->pmax_threshold[afi][safi] = threshold;
4253 peer->pmax_restart[afi][safi] = restart;
4254 if (warning)
4255 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4256 else
4257 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4259 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4260 return 0;
4262 group = peer->group;
4263 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4265 if (! peer->af_group[afi][safi])
4266 continue;
4268 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4269 peer->pmax[afi][safi] = max;
4270 peer->pmax_threshold[afi][safi] = threshold;
4271 peer->pmax_restart[afi][safi] = restart;
4272 if (warning)
4273 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4274 else
4275 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4277 return 0;
4281 peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
4283 struct peer_group *group;
4284 struct listnode *node, *nnode;
4286 if (! peer->afc[afi][safi])
4287 return BGP_ERR_PEER_INACTIVE;
4289 /* apply peer-group config */
4290 if (peer->af_group[afi][safi])
4292 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4293 PEER_FLAG_MAX_PREFIX))
4294 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4295 else
4296 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4298 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4299 PEER_FLAG_MAX_PREFIX_WARNING))
4300 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4301 else
4302 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4304 peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
4305 peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
4306 peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
4307 return 0;
4310 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4311 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4312 peer->pmax[afi][safi] = 0;
4313 peer->pmax_threshold[afi][safi] = 0;
4314 peer->pmax_restart[afi][safi] = 0;
4316 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4317 return 0;
4319 group = peer->group;
4320 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4322 if (! peer->af_group[afi][safi])
4323 continue;
4325 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4326 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4327 peer->pmax[afi][safi] = 0;
4328 peer->pmax_threshold[afi][safi] = 0;
4329 peer->pmax_restart[afi][safi] = 0;
4331 return 0;
4335 peer_clear (struct peer *peer)
4337 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4339 if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4341 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4342 if (peer->t_pmax_restart)
4344 BGP_TIMER_OFF (peer->t_pmax_restart);
4345 if (BGP_DEBUG (events, EVENTS))
4346 zlog_debug ("%s Maximum-prefix restart timer canceled",
4347 peer->host);
4349 BGP_EVENT_ADD (peer, BGP_Start);
4350 return 0;
4353 peer->v_start = BGP_INIT_START_TIMER;
4354 if (peer->status == Established)
4355 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
4356 BGP_NOTIFY_CEASE_ADMIN_RESET);
4357 else
4358 BGP_EVENT_ADD (peer, BGP_Stop);
4360 return 0;
4364 peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
4365 enum bgp_clear_type stype)
4367 if (peer->status != Established)
4368 return 0;
4370 if (! peer->afc[afi][safi])
4371 return BGP_ERR_AF_UNCONFIGURED;
4373 if (stype == BGP_CLEAR_SOFT_RSCLIENT)
4375 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
4376 return 0;
4377 bgp_check_local_routes_rsclient (peer, afi, safi);
4378 bgp_soft_reconfig_rsclient (peer, afi, safi);
4381 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
4382 bgp_announce_route (peer, afi, safi);
4384 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4386 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)
4387 && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
4388 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
4390 struct bgp_filter *filter = &peer->filter[afi][safi];
4391 u_char prefix_type;
4393 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
4394 prefix_type = ORF_TYPE_PREFIX;
4395 else
4396 prefix_type = ORF_TYPE_PREFIX_OLD;
4398 if (filter->plist[FILTER_IN].plist)
4400 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4401 bgp_route_refresh_send (peer, afi, safi,
4402 prefix_type, REFRESH_DEFER, 1);
4403 bgp_route_refresh_send (peer, afi, safi, prefix_type,
4404 REFRESH_IMMEDIATE, 0);
4406 else
4408 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4409 bgp_route_refresh_send (peer, afi, safi,
4410 prefix_type, REFRESH_IMMEDIATE, 1);
4411 else
4412 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4414 return 0;
4418 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
4419 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4421 /* If neighbor has soft reconfiguration inbound flag.
4422 Use Adj-RIB-In database. */
4423 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4424 bgp_soft_reconfig_in (peer, afi, safi);
4425 else
4427 /* If neighbor has route refresh capability, send route refresh
4428 message to the peer. */
4429 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4430 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4431 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4432 else
4433 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
4436 return 0;
4439 /* Display peer uptime.*/
4440 /* XXX: why does this function return char * when it takes buffer? */
4441 char *
4442 peer_uptime (time_t uptime2, char *buf, size_t len)
4444 time_t uptime1;
4445 struct tm *tm;
4447 /* Check buffer length. */
4448 if (len < BGP_UPTIME_LEN)
4450 zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
4451 /* XXX: should return status instead of buf... */
4452 snprintf (buf, len, "<error> ");
4453 return buf;
4456 /* If there is no connection has been done before print `never'. */
4457 if (uptime2 == 0)
4459 snprintf (buf, len, "never ");
4460 return buf;
4463 /* Get current time. */
4464 uptime1 = bgp_clock ();
4465 uptime1 -= uptime2;
4466 tm = gmtime (&uptime1);
4468 /* Making formatted timer strings. */
4469 #define ONE_DAY_SECOND 60*60*24
4470 #define ONE_WEEK_SECOND 60*60*24*7
4472 if (uptime1 < ONE_DAY_SECOND)
4473 snprintf (buf, len, "%02d:%02d:%02d",
4474 tm->tm_hour, tm->tm_min, tm->tm_sec);
4475 else if (uptime1 < ONE_WEEK_SECOND)
4476 snprintf (buf, len, "%dd%02dh%02dm",
4477 tm->tm_yday, tm->tm_hour, tm->tm_min);
4478 else
4479 snprintf (buf, len, "%02dw%dd%02dh",
4480 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
4481 return buf;
4484 static void
4485 bgp_config_write_filter (struct vty *vty, struct peer *peer,
4486 afi_t afi, safi_t safi)
4488 struct bgp_filter *filter;
4489 struct bgp_filter *gfilter = NULL;
4490 char *addr;
4491 int in = FILTER_IN;
4492 int out = FILTER_OUT;
4494 addr = peer->host;
4495 filter = &peer->filter[afi][safi];
4496 if (peer->af_group[afi][safi])
4497 gfilter = &peer->group->conf->filter[afi][safi];
4499 /* distribute-list. */
4500 if (filter->dlist[in].name)
4501 if (! gfilter || ! gfilter->dlist[in].name
4502 || strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
4503 vty_out (vty, " neighbor %s distribute-list %s in%s", addr,
4504 filter->dlist[in].name, VTY_NEWLINE);
4505 if (filter->dlist[out].name && ! gfilter)
4506 vty_out (vty, " neighbor %s distribute-list %s out%s", addr,
4507 filter->dlist[out].name, VTY_NEWLINE);
4509 /* prefix-list. */
4510 if (filter->plist[in].name)
4511 if (! gfilter || ! gfilter->plist[in].name
4512 || strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
4513 vty_out (vty, " neighbor %s prefix-list %s in%s", addr,
4514 filter->plist[in].name, VTY_NEWLINE);
4515 if (filter->plist[out].name && ! gfilter)
4516 vty_out (vty, " neighbor %s prefix-list %s out%s", addr,
4517 filter->plist[out].name, VTY_NEWLINE);
4519 /* route-map. */
4520 if (filter->map[RMAP_IN].name)
4521 if (! gfilter || ! gfilter->map[RMAP_IN].name
4522 || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
4523 vty_out (vty, " neighbor %s route-map %s in%s", addr,
4524 filter->map[RMAP_IN].name, VTY_NEWLINE);
4525 if (filter->map[RMAP_OUT].name && ! gfilter)
4526 vty_out (vty, " neighbor %s route-map %s out%s", addr,
4527 filter->map[RMAP_OUT].name, VTY_NEWLINE);
4528 if (filter->map[RMAP_IMPORT].name && ! gfilter)
4529 vty_out (vty, " neighbor %s route-map %s import%s", addr,
4530 filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
4531 if (filter->map[RMAP_EXPORT].name)
4532 if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
4533 || strcmp (filter->map[RMAP_EXPORT].name,
4534 gfilter->map[RMAP_EXPORT].name) != 0)
4535 vty_out (vty, " neighbor %s route-map %s export%s", addr,
4536 filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
4538 /* unsuppress-map */
4539 if (filter->usmap.name && ! gfilter)
4540 vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
4541 filter->usmap.name, VTY_NEWLINE);
4543 /* filter-list. */
4544 if (filter->aslist[in].name)
4545 if (! gfilter || ! gfilter->aslist[in].name
4546 || strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
4547 vty_out (vty, " neighbor %s filter-list %s in%s", addr,
4548 filter->aslist[in].name, VTY_NEWLINE);
4549 if (filter->aslist[out].name && ! gfilter)
4550 vty_out (vty, " neighbor %s filter-list %s out%s", addr,
4551 filter->aslist[out].name, VTY_NEWLINE);
4554 /* BGP peer configuration display function. */
4555 static void
4556 bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
4557 struct peer *peer, afi_t afi, safi_t safi)
4559 struct bgp_filter *filter;
4560 struct peer *g_peer = NULL;
4561 char buf[SU_ADDRSTRLEN];
4562 char *addr;
4564 filter = &peer->filter[afi][safi];
4565 addr = peer->host;
4566 if (peer_group_active (peer))
4567 g_peer = peer->group->conf;
4569 /************************************
4570 ****** Global to the neighbor ******
4571 ************************************/
4572 if (afi == AFI_IP && safi == SAFI_UNICAST)
4574 /* remote-as. */
4575 if (! peer_group_active (peer))
4577 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4578 vty_out (vty, " neighbor %s peer-group%s", addr,
4579 VTY_NEWLINE);
4580 if (peer->as)
4581 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4582 VTY_NEWLINE);
4584 else
4586 if (! g_peer->as)
4587 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4588 VTY_NEWLINE);
4589 if (peer->af_group[AFI_IP][SAFI_UNICAST])
4590 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4591 peer->group->name, VTY_NEWLINE);
4594 /* local-as. */
4595 if (peer->change_local_as)
4596 if (! peer_group_active (peer))
4597 vty_out (vty, " neighbor %s local-as %u%s%s", addr,
4598 peer->change_local_as,
4599 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
4600 " no-prepend" : "", VTY_NEWLINE);
4602 /* Description. */
4603 if (peer->desc)
4604 vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
4605 VTY_NEWLINE);
4607 /* Shutdown. */
4608 if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4609 if (! peer_group_active (peer) ||
4610 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
4611 vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
4613 /* Password. */
4614 if (peer->password)
4615 if (!peer_group_active (peer)
4616 || ! g_peer->password
4617 || strcmp (peer->password, g_peer->password) != 0)
4618 vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
4619 VTY_NEWLINE);
4621 /* BGP port. */
4622 if (peer->port != BGP_PORT_DEFAULT)
4623 vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
4624 VTY_NEWLINE);
4626 /* Local interface name. */
4627 if (peer->ifname)
4628 vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
4629 VTY_NEWLINE);
4631 /* Passive. */
4632 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
4633 if (! peer_group_active (peer) ||
4634 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
4635 vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
4637 /* EBGP multihop. */
4638 if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
4639 if (! peer_group_active (peer) ||
4640 g_peer->ttl != peer->ttl)
4641 vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
4642 VTY_NEWLINE);
4644 /* disable-connected-check. */
4645 if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4646 if (! peer_group_active (peer) ||
4647 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4648 vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
4650 /* Update-source. */
4651 if (peer->update_if)
4652 if (! peer_group_active (peer) || ! g_peer->update_if
4653 || strcmp (g_peer->update_if, peer->update_if) != 0)
4654 vty_out (vty, " neighbor %s update-source %s%s", addr,
4655 peer->update_if, VTY_NEWLINE);
4656 if (peer->update_source)
4657 if (! peer_group_active (peer) || ! g_peer->update_source
4658 || sockunion_cmp (g_peer->update_source,
4659 peer->update_source) != 0)
4660 vty_out (vty, " neighbor %s update-source %s%s", addr,
4661 sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN),
4662 VTY_NEWLINE);
4664 /* advertisement-interval */
4665 if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV))
4666 vty_out (vty, " neighbor %s advertisement-interval %d%s",
4667 addr, peer->v_routeadv, VTY_NEWLINE);
4669 /* timers. */
4670 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
4671 && ! peer_group_active (peer))
4672 vty_out (vty, " neighbor %s timers %d %d%s", addr,
4673 peer->keepalive, peer->holdtime, VTY_NEWLINE);
4675 if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT))
4676 vty_out (vty, " neighbor %s timers connect %d%s", addr,
4677 peer->connect, VTY_NEWLINE);
4679 /* Default weight. */
4680 if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
4681 if (! peer_group_active (peer) ||
4682 g_peer->weight != peer->weight)
4683 vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
4684 VTY_NEWLINE);
4686 /* Dynamic capability. */
4687 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
4688 if (! peer_group_active (peer) ||
4689 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
4690 vty_out (vty, " neighbor %s capability dynamic%s", addr,
4691 VTY_NEWLINE);
4693 /* dont capability negotiation. */
4694 if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
4695 if (! peer_group_active (peer) ||
4696 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
4697 vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
4698 VTY_NEWLINE);
4700 /* override capability negotiation. */
4701 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
4702 if (! peer_group_active (peer) ||
4703 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
4704 vty_out (vty, " neighbor %s override-capability%s", addr,
4705 VTY_NEWLINE);
4707 /* strict capability negotiation. */
4708 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
4709 if (! peer_group_active (peer) ||
4710 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
4711 vty_out (vty, " neighbor %s strict-capability-match%s", addr,
4712 VTY_NEWLINE);
4714 if (! peer_group_active (peer))
4716 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
4718 if (peer->afc[AFI_IP][SAFI_UNICAST])
4719 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4721 else
4723 if (! peer->afc[AFI_IP][SAFI_UNICAST])
4724 vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
4730 /************************************
4731 ****** Per AF to the neighbor ******
4732 ************************************/
4734 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
4736 if (peer->af_group[afi][safi])
4737 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4738 peer->group->name, VTY_NEWLINE);
4739 else
4740 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4743 /* ORF capability. */
4744 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
4745 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
4746 if (! peer->af_group[afi][safi])
4748 vty_out (vty, " neighbor %s capability orf prefix-list", addr);
4750 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
4751 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
4752 vty_out (vty, " both");
4753 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
4754 vty_out (vty, " send");
4755 else
4756 vty_out (vty, " receive");
4757 vty_out (vty, "%s", VTY_NEWLINE);
4760 /* Route reflector client. */
4761 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
4762 && ! peer->af_group[afi][safi])
4763 vty_out (vty, " neighbor %s route-reflector-client%s", addr,
4764 VTY_NEWLINE);
4766 /* Nexthop self. */
4767 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
4768 && ! peer->af_group[afi][safi])
4769 vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
4771 /* Remove private AS. */
4772 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
4773 && ! peer->af_group[afi][safi])
4774 vty_out (vty, " neighbor %s remove-private-AS%s",
4775 addr, VTY_NEWLINE);
4777 /* send-community print. */
4778 if (! peer->af_group[afi][safi])
4780 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4782 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
4783 && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4784 vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE);
4785 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4786 vty_out (vty, " neighbor %s send-community extended%s",
4787 addr, VTY_NEWLINE);
4788 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
4789 vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
4791 else
4793 if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
4794 && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4795 vty_out (vty, " no neighbor %s send-community both%s",
4796 addr, VTY_NEWLINE);
4797 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
4798 vty_out (vty, " no neighbor %s send-community extended%s",
4799 addr, VTY_NEWLINE);
4800 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
4801 vty_out (vty, " no neighbor %s send-community%s",
4802 addr, VTY_NEWLINE);
4806 /* Default information */
4807 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
4808 && ! peer->af_group[afi][safi])
4810 vty_out (vty, " neighbor %s default-originate", addr);
4811 if (peer->default_rmap[afi][safi].name)
4812 vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
4813 vty_out (vty, "%s", VTY_NEWLINE);
4816 /* Soft reconfiguration inbound. */
4817 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4818 if (! peer->af_group[afi][safi] ||
4819 ! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4820 vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
4821 VTY_NEWLINE);
4823 /* maximum-prefix. */
4824 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
4825 if (! peer->af_group[afi][safi]
4826 || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
4827 || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
4828 || CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
4829 != CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
4831 vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
4832 if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
4833 vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
4834 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
4835 vty_out (vty, " warning-only");
4836 if (peer->pmax_restart[afi][safi])
4837 vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]);
4838 vty_out (vty, "%s", VTY_NEWLINE);
4841 /* Route server client. */
4842 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
4843 && ! peer->af_group[afi][safi])
4844 vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
4846 /* Allow AS in. */
4847 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
4848 if (! peer_group_active (peer)
4849 || ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
4850 || peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
4852 if (peer->allowas_in[afi][safi] == 3)
4853 vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
4854 else
4855 vty_out (vty, " neighbor %s allowas-in %d%s", addr,
4856 peer->allowas_in[afi][safi], VTY_NEWLINE);
4859 /* Filter. */
4860 bgp_config_write_filter (vty, peer, afi, safi);
4862 /* atribute-unchanged. */
4863 if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
4864 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
4865 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
4866 && ! peer->af_group[afi][safi])
4868 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
4869 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
4870 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
4871 vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE);
4872 else
4873 vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr,
4874 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ?
4875 " as-path" : "",
4876 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ?
4877 " next-hop" : "",
4878 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
4879 " med" : "", VTY_NEWLINE);
4883 /* Display "address-family" configuration header. */
4884 void
4885 bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
4886 int *write)
4888 if (*write)
4889 return;
4891 if (afi == AFI_IP && safi == SAFI_UNICAST)
4892 return;
4894 vty_out (vty, "!%s address-family ", VTY_NEWLINE);
4896 if (afi == AFI_IP)
4898 if (safi == SAFI_MULTICAST)
4899 vty_out (vty, "ipv4 multicast");
4900 else if (safi == SAFI_MPLS_VPN)
4901 vty_out (vty, "vpnv4 unicast");
4903 else if (afi == AFI_IP6)
4905 vty_out (vty, "ipv6");
4907 if (safi == SAFI_MULTICAST)
4908 vty_out (vty, " multicast");
4911 vty_out (vty, "%s", VTY_NEWLINE);
4913 *write = 1;
4916 /* Address family based peer configuration display. */
4917 static int
4918 bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
4919 safi_t safi)
4921 int write = 0;
4922 struct peer *peer;
4923 struct peer_group *group;
4924 struct listnode *node, *nnode;
4926 bgp_config_write_network (vty, bgp, afi, safi, &write);
4928 bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
4930 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4932 if (group->conf->afc[afi][safi])
4934 bgp_config_write_family_header (vty, afi, safi, &write);
4935 bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
4938 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4940 if (peer->afc[afi][safi])
4942 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
4944 bgp_config_write_family_header (vty, afi, safi, &write);
4945 bgp_config_write_peer (vty, bgp, peer, afi, safi);
4949 if (write)
4950 vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
4952 return write;
4956 bgp_config_write (struct vty *vty)
4958 int write = 0;
4959 struct bgp *bgp;
4960 struct peer_group *group;
4961 struct peer *peer;
4962 struct listnode *node, *nnode;
4963 struct listnode *mnode, *mnnode;
4965 /* BGP Multiple instance. */
4966 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
4968 vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE);
4969 write++;
4972 /* BGP Config type. */
4973 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4975 vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE);
4976 write++;
4979 /* BGP configuration. */
4980 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4982 if (write)
4983 vty_out (vty, "!%s", VTY_NEWLINE);
4985 /* Router bgp ASN */
4986 vty_out (vty, "router bgp %u", bgp->as);
4988 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
4990 if (bgp->name)
4991 vty_out (vty, " view %s", bgp->name);
4993 vty_out (vty, "%s", VTY_NEWLINE);
4995 /* No Synchronization */
4996 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
4997 vty_out (vty, " no synchronization%s", VTY_NEWLINE);
4999 /* BGP fast-external-failover. */
5000 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
5001 vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE);
5003 /* BGP router ID. */
5004 if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID))
5005 vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id),
5006 VTY_NEWLINE);
5008 /* BGP log-neighbor-changes. */
5009 if (bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
5010 vty_out (vty, " bgp log-neighbor-changes%s", VTY_NEWLINE);
5012 /* BGP configuration. */
5013 if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
5014 vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
5016 /* BGP default ipv4-unicast. */
5017 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
5018 vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE);
5020 /* BGP default local-preference. */
5021 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
5022 vty_out (vty, " bgp default local-preference %d%s",
5023 bgp->default_local_pref, VTY_NEWLINE);
5025 /* BGP client-to-client reflection. */
5026 if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
5027 vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE);
5029 /* BGP cluster ID. */
5030 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID))
5031 vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id),
5032 VTY_NEWLINE);
5034 /* Confederation identifier*/
5035 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
5036 vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
5037 VTY_NEWLINE);
5039 /* Confederation peer */
5040 if (bgp->confed_peers_cnt > 0)
5042 int i;
5044 vty_out (vty, " bgp confederation peers");
5046 for (i = 0; i < bgp->confed_peers_cnt; i++)
5047 vty_out(vty, " %u", bgp->confed_peers[i]);
5049 vty_out (vty, "%s", VTY_NEWLINE);
5052 /* BGP enforce-first-as. */
5053 if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
5054 vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE);
5056 /* BGP deterministic-med. */
5057 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
5058 vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
5060 /* BGP graceful-restart. */
5061 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
5062 vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
5063 bgp->stalepath_time, VTY_NEWLINE);
5064 if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
5065 vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
5067 /* BGP bestpath method. */
5068 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
5069 vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
5070 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
5071 vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
5072 if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
5073 vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
5074 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
5075 || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5077 vty_out (vty, " bgp bestpath med");
5078 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED))
5079 vty_out (vty, " confed");
5080 if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5081 vty_out (vty, " missing-as-worst");
5082 vty_out (vty, "%s", VTY_NEWLINE);
5085 /* BGP network import check. */
5086 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
5087 vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
5089 /* BGP scan interval. */
5090 bgp_config_write_scan_time (vty);
5092 /* BGP flag dampening. */
5093 if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
5094 BGP_CONFIG_DAMPENING))
5095 bgp_config_write_damp (vty);
5097 /* BGP static route configuration. */
5098 bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5100 /* BGP redistribute configuration. */
5101 bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5103 /* BGP timers configuration. */
5104 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
5105 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
5106 vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive,
5107 bgp->default_holdtime, VTY_NEWLINE);
5109 /* peer-group */
5110 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5112 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
5115 /* Normal neighbor configuration. */
5116 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5118 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5119 bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
5122 /* Distance configuration. */
5123 bgp_config_write_distance (vty, bgp);
5125 /* No auto-summary */
5126 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5127 vty_out (vty, " no auto-summary%s", VTY_NEWLINE);
5129 /* IPv4 multicast configuration. */
5130 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
5132 /* IPv4 VPN configuration. */
5133 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
5135 /* IPv6 unicast configuration. */
5136 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
5138 /* IPv6 multicast configuration. */
5139 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
5141 write++;
5143 return write;
5146 void
5147 bgp_master_init (void)
5149 memset (&bgp_master, 0, sizeof (struct bgp_master));
5151 bm = &bgp_master;
5152 bm->bgp = list_new ();
5153 bm->listen_sockets = list_new ();
5154 bm->port = BGP_PORT_DEFAULT;
5155 bm->master = thread_master_create ();
5156 bm->start_time = bgp_clock ();
5160 void
5161 bgp_init (void)
5163 /* BGP VTY commands installation. */
5164 bgp_vty_init ();
5166 /* Init zebra. */
5167 bgp_zebra_init ();
5169 /* BGP inits. */
5170 bgp_attr_init ();
5171 bgp_debug_init ();
5172 bgp_dump_init ();
5173 bgp_route_init ();
5174 bgp_route_map_init ();
5175 bgp_scan_init ();
5176 bgp_mplsvpn_init ();
5178 /* Access list initialize. */
5179 access_list_init ();
5180 access_list_add_hook (peer_distribute_update);
5181 access_list_delete_hook (peer_distribute_update);
5183 /* Filter list initialize. */
5184 bgp_filter_init ();
5185 as_list_add_hook (peer_aslist_update);
5186 as_list_delete_hook (peer_aslist_update);
5188 /* Prefix list initialize.*/
5189 prefix_list_init ();
5190 prefix_list_add_hook (peer_prefix_list_update);
5191 prefix_list_delete_hook (peer_prefix_list_update);
5193 /* Community list initialize. */
5194 bgp_clist = community_list_init ();
5196 #ifdef HAVE_SNMP
5197 bgp_snmp_init ();
5198 #endif /* HAVE_SNMP */
5201 void
5202 bgp_terminate (void)
5204 struct bgp *bgp;
5205 struct peer *peer;
5206 struct listnode *node, *nnode;
5207 struct listnode *mnode, *mnnode;
5209 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5210 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5211 if (peer->status == Established)
5212 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
5213 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
5215 bgp_cleanup_routes ();
5217 if (bm->process_main_queue)
5219 work_queue_free (bm->process_main_queue);
5220 bm->process_main_queue = NULL;
5222 if (bm->process_rsclient_queue)
5224 work_queue_free (bm->process_rsclient_queue);
5225 bm->process_rsclient_queue = NULL;