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