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