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