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