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