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