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