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