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