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