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