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