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