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