]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgpd.c
2fe300c5a8a49407554c8abf594a777b027953c3
[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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 { 0, 0, 0 }
2359 };
2360
2361 /* Proper action set. */
2362 static int
2363 peer_flag_action_set (const struct peer_flag_action *action_list, int size,
2364 struct peer_flag_action *action, u_int32_t flag)
2365 {
2366 int i;
2367 int found = 0;
2368 int reset_in = 0;
2369 int reset_out = 0;
2370 const struct peer_flag_action *match = NULL;
2371
2372 /* Check peer's frag action. */
2373 for (i = 0; i < size; i++)
2374 {
2375 match = &action_list[i];
2376
2377 if (match->flag == 0)
2378 break;
2379
2380 if (match->flag & flag)
2381 {
2382 found = 1;
2383
2384 if (match->type == peer_change_reset_in)
2385 reset_in = 1;
2386 if (match->type == peer_change_reset_out)
2387 reset_out = 1;
2388 if (match->type == peer_change_reset)
2389 {
2390 reset_in = 1;
2391 reset_out = 1;
2392 }
2393 if (match->not_for_member)
2394 action->not_for_member = 1;
2395 }
2396 }
2397
2398 /* Set peer clear type. */
2399 if (reset_in && reset_out)
2400 action->type = peer_change_reset;
2401 else if (reset_in)
2402 action->type = peer_change_reset_in;
2403 else if (reset_out)
2404 action->type = peer_change_reset_out;
2405 else
2406 action->type = peer_change_none;
2407
2408 return found;
2409 }
2410
2411 static void
2412 peer_flag_modify_action (struct peer *peer, u_int32_t flag)
2413 {
2414 if (flag == PEER_FLAG_SHUTDOWN)
2415 {
2416 if (CHECK_FLAG (peer->flags, flag))
2417 {
2418 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2419 peer_nsf_stop (peer);
2420
2421 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2422 if (peer->t_pmax_restart)
2423 {
2424 BGP_TIMER_OFF (peer->t_pmax_restart);
2425 if (BGP_DEBUG (events, EVENTS))
2426 zlog_debug ("%s Maximum-prefix restart timer canceled",
2427 peer->host);
2428 }
2429
2430 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
2431 peer_nsf_stop (peer);
2432
2433 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2434 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2435 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
2436 else
2437 BGP_EVENT_ADD (peer, BGP_Stop);
2438 }
2439 else
2440 {
2441 peer->v_start = BGP_INIT_START_TIMER;
2442 BGP_EVENT_ADD (peer, BGP_Stop);
2443 }
2444 }
2445 else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2446 {
2447 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
2448 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2449 else if (flag == PEER_FLAG_PASSIVE)
2450 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
2451 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
2452 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
2453
2454 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2455 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2456 }
2457 else
2458 BGP_EVENT_ADD (peer, BGP_Stop);
2459 }
2460
2461 /* Change specified peer flag. */
2462 static int
2463 peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
2464 {
2465 int found;
2466 int size;
2467 struct peer_group *group;
2468 struct listnode *node, *nnode;
2469 struct peer_flag_action action;
2470
2471 memset (&action, 0, sizeof (struct peer_flag_action));
2472 size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
2473
2474 found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
2475
2476 /* No flag action is found. */
2477 if (! found)
2478 return BGP_ERR_INVALID_FLAG;
2479
2480 /* Not for peer-group member. */
2481 if (action.not_for_member && peer_group_active (peer))
2482 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2483
2484 /* When unset the peer-group member's flag we have to check
2485 peer-group configuration. */
2486 if (! set && peer_group_active (peer))
2487 if (CHECK_FLAG (peer->group->conf->flags, flag))
2488 {
2489 if (flag == PEER_FLAG_SHUTDOWN)
2490 return BGP_ERR_PEER_GROUP_SHUTDOWN;
2491 else
2492 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2493 }
2494
2495 /* Flag conflict check. */
2496 if (set
2497 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
2498 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
2499 return BGP_ERR_PEER_FLAG_CONFLICT;
2500
2501 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2502 {
2503 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2504 return 0;
2505 if (! set && ! CHECK_FLAG (peer->flags, flag))
2506 return 0;
2507 }
2508
2509 if (set)
2510 SET_FLAG (peer->flags, flag);
2511 else
2512 UNSET_FLAG (peer->flags, flag);
2513
2514 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2515 {
2516 if (action.type == peer_change_reset)
2517 peer_flag_modify_action (peer, flag);
2518
2519 return 0;
2520 }
2521
2522 /* peer-group member updates. */
2523 group = peer->group;
2524
2525 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2526 {
2527 if (set && CHECK_FLAG (peer->flags, flag) == flag)
2528 continue;
2529
2530 if (! set && ! CHECK_FLAG (peer->flags, flag))
2531 continue;
2532
2533 if (set)
2534 SET_FLAG (peer->flags, flag);
2535 else
2536 UNSET_FLAG (peer->flags, flag);
2537
2538 if (action.type == peer_change_reset)
2539 peer_flag_modify_action (peer, flag);
2540 }
2541 return 0;
2542 }
2543
2544 int
2545 peer_flag_set (struct peer *peer, u_int32_t flag)
2546 {
2547 return peer_flag_modify (peer, flag, 1);
2548 }
2549
2550 int
2551 peer_flag_unset (struct peer *peer, u_int32_t flag)
2552 {
2553 return peer_flag_modify (peer, flag, 0);
2554 }
2555
2556 static int
2557 peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
2558 {
2559 if (peer->af_group[afi][safi])
2560 return 1;
2561 return 0;
2562 }
2563
2564 static int
2565 peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
2566 int set)
2567 {
2568 int found;
2569 int size;
2570 struct listnode *node, *nnode;
2571 struct peer_group *group;
2572 struct peer_flag_action action;
2573
2574 memset (&action, 0, sizeof (struct peer_flag_action));
2575 size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action);
2576
2577 found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag);
2578
2579 /* No flag action is found. */
2580 if (! found)
2581 return BGP_ERR_INVALID_FLAG;
2582
2583 /* Adress family must be activated. */
2584 if (! peer->afc[afi][safi])
2585 return BGP_ERR_PEER_INACTIVE;
2586
2587 /* Not for peer-group member. */
2588 if (action.not_for_member && peer_is_group_member (peer, afi, safi))
2589 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
2590
2591 /* Spcecial check for reflector client. */
2592 if (flag & PEER_FLAG_REFLECTOR_CLIENT
2593 && peer_sort (peer) != BGP_PEER_IBGP)
2594 return BGP_ERR_NOT_INTERNAL_PEER;
2595
2596 /* Spcecial check for remove-private-AS. */
2597 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
2598 && peer_sort (peer) == BGP_PEER_IBGP)
2599 return BGP_ERR_REMOVE_PRIVATE_AS;
2600
2601 /* When unset the peer-group member's flag we have to check
2602 peer-group configuration. */
2603 if (! set && peer->af_group[afi][safi])
2604 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
2605 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
2606
2607 /* When current flag configuration is same as requested one. */
2608 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2609 {
2610 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2611 return 0;
2612 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2613 return 0;
2614 }
2615
2616 if (set)
2617 SET_FLAG (peer->af_flags[afi][safi], flag);
2618 else
2619 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2620
2621 /* Execute action when peer is established. */
2622 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2623 && peer->status == Established)
2624 {
2625 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2626 bgp_clear_adj_in (peer, afi, safi);
2627 else
2628 {
2629 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2630 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2631 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2632 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2633 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2634 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2635 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2636 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2637
2638 peer_change_action (peer, afi, safi, action.type);
2639 }
2640
2641 }
2642
2643 /* Peer group member updates. */
2644 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2645 {
2646 group = peer->group;
2647
2648 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2649 {
2650 if (! peer->af_group[afi][safi])
2651 continue;
2652
2653 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
2654 continue;
2655
2656 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
2657 continue;
2658
2659 if (set)
2660 SET_FLAG (peer->af_flags[afi][safi], flag);
2661 else
2662 UNSET_FLAG (peer->af_flags[afi][safi], flag);
2663
2664 if (peer->status == Established)
2665 {
2666 if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
2667 bgp_clear_adj_in (peer, afi, safi);
2668 else
2669 {
2670 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
2671 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
2672 else if (flag == PEER_FLAG_RSERVER_CLIENT)
2673 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
2674 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
2675 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2676 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
2677 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
2678
2679 peer_change_action (peer, afi, safi, action.type);
2680 }
2681 }
2682 }
2683 }
2684 return 0;
2685 }
2686
2687 int
2688 peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2689 {
2690 return peer_af_flag_modify (peer, afi, safi, flag, 1);
2691 }
2692
2693 int
2694 peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
2695 {
2696 return peer_af_flag_modify (peer, afi, safi, flag, 0);
2697 }
2698 \f
2699 /* EBGP multihop configuration. */
2700 int
2701 peer_ebgp_multihop_set (struct peer *peer, int ttl)
2702 {
2703 struct peer_group *group;
2704 struct listnode *node, *nnode;
2705 struct peer *peer1;
2706
2707 if (peer->sort == BGP_PEER_IBGP)
2708 return 0;
2709
2710 /* see comment in peer_ttl_security_hops_set() */
2711 if (ttl != MAXTTL)
2712 {
2713 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2714 {
2715 group = peer->group;
2716 if (group->conf->gtsm_hops != 0)
2717 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
2718
2719 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
2720 {
2721 if (peer1->sort == BGP_PEER_IBGP)
2722 continue;
2723
2724 if (peer1->gtsm_hops != 0)
2725 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
2726 }
2727 }
2728 else
2729 {
2730 if (peer->gtsm_hops != 0)
2731 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
2732 }
2733 }
2734
2735 peer->ttl = ttl;
2736
2737 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2738 {
2739 if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
2740 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2741 }
2742 else
2743 {
2744 group = peer->group;
2745 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2746 {
2747 if (peer->sort == BGP_PEER_IBGP)
2748 continue;
2749
2750 peer->ttl = group->conf->ttl;
2751
2752 if (peer->fd >= 0)
2753 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2754 }
2755 }
2756 return 0;
2757 }
2758
2759 int
2760 peer_ebgp_multihop_unset (struct peer *peer)
2761 {
2762 struct peer_group *group;
2763 struct listnode *node, *nnode;
2764
2765 if (peer->sort == BGP_PEER_IBGP)
2766 return 0;
2767
2768 if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
2769 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
2770
2771 if (peer_group_active (peer))
2772 peer->ttl = peer->group->conf->ttl;
2773 else
2774 peer->ttl = 1;
2775
2776 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2777 {
2778 if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
2779 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2780 }
2781 else
2782 {
2783 group = peer->group;
2784 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2785 {
2786 if (peer->sort == BGP_PEER_IBGP)
2787 continue;
2788
2789 peer->ttl = 1;
2790
2791 if (peer->fd >= 0)
2792 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2793 }
2794 }
2795 return 0;
2796 }
2797 \f
2798 /* Neighbor description. */
2799 int
2800 peer_description_set (struct peer *peer, char *desc)
2801 {
2802 if (peer->desc)
2803 XFREE (MTYPE_PEER_DESC, peer->desc);
2804
2805 peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
2806
2807 return 0;
2808 }
2809
2810 int
2811 peer_description_unset (struct peer *peer)
2812 {
2813 if (peer->desc)
2814 XFREE (MTYPE_PEER_DESC, peer->desc);
2815
2816 peer->desc = NULL;
2817
2818 return 0;
2819 }
2820 \f
2821 /* Neighbor update-source. */
2822 int
2823 peer_update_source_if_set (struct peer *peer, const char *ifname)
2824 {
2825 struct peer_group *group;
2826 struct listnode *node, *nnode;
2827
2828 if (peer->update_if)
2829 {
2830 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2831 && strcmp (peer->update_if, ifname) == 0)
2832 return 0;
2833
2834 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2835 peer->update_if = NULL;
2836 }
2837
2838 if (peer->update_source)
2839 {
2840 sockunion_free (peer->update_source);
2841 peer->update_source = NULL;
2842 }
2843
2844 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2845
2846 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2847 {
2848 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2849 {
2850 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2851 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2852 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2853 }
2854 else
2855 BGP_EVENT_ADD (peer, BGP_Stop);
2856 return 0;
2857 }
2858
2859 /* peer-group member updates. */
2860 group = peer->group;
2861 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2862 {
2863 if (peer->update_if)
2864 {
2865 if (strcmp (peer->update_if, ifname) == 0)
2866 continue;
2867
2868 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2869 peer->update_if = NULL;
2870 }
2871
2872 if (peer->update_source)
2873 {
2874 sockunion_free (peer->update_source);
2875 peer->update_source = NULL;
2876 }
2877
2878 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
2879
2880 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2881 {
2882 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2883 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2884 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2885 }
2886 else
2887 BGP_EVENT_ADD (peer, BGP_Stop);
2888 }
2889 return 0;
2890 }
2891
2892 int
2893 peer_update_source_addr_set (struct peer *peer, union sockunion *su)
2894 {
2895 struct peer_group *group;
2896 struct listnode *node, *nnode;
2897
2898 if (peer->update_source)
2899 {
2900 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2901 && sockunion_cmp (peer->update_source, su) == 0)
2902 return 0;
2903 sockunion_free (peer->update_source);
2904 peer->update_source = NULL;
2905 }
2906
2907 if (peer->update_if)
2908 {
2909 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2910 peer->update_if = NULL;
2911 }
2912
2913 peer->update_source = sockunion_dup (su);
2914
2915 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2916 {
2917 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2918 {
2919 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2920 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2921 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2922 }
2923 else
2924 BGP_EVENT_ADD (peer, BGP_Stop);
2925 return 0;
2926 }
2927
2928 /* peer-group member updates. */
2929 group = peer->group;
2930 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2931 {
2932 if (peer->update_source)
2933 {
2934 if (sockunion_cmp (peer->update_source, su) == 0)
2935 continue;
2936 sockunion_free (peer->update_source);
2937 peer->update_source = NULL;
2938 }
2939
2940 if (peer->update_if)
2941 {
2942 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2943 peer->update_if = NULL;
2944 }
2945
2946 peer->update_source = sockunion_dup (su);
2947
2948 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
2949 {
2950 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
2951 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
2952 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2953 }
2954 else
2955 BGP_EVENT_ADD (peer, BGP_Stop);
2956 }
2957 return 0;
2958 }
2959
2960 int
2961 peer_update_source_unset (struct peer *peer)
2962 {
2963 union sockunion *su;
2964 struct peer_group *group;
2965 struct listnode *node, *nnode;
2966
2967 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
2968 && ! peer->update_source
2969 && ! peer->update_if)
2970 return 0;
2971
2972 if (peer->update_source)
2973 {
2974 sockunion_free (peer->update_source);
2975 peer->update_source = NULL;
2976 }
2977 if (peer->update_if)
2978 {
2979 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
2980 peer->update_if = NULL;
2981 }
2982
2983 if (peer_group_active (peer))
2984 {
2985 group = peer->group;
2986
2987 if (group->conf->update_source)
2988 {
2989 su = sockunion_dup (group->conf->update_source);
2990 peer->update_source = su;
2991 }
2992 else if (group->conf->update_if)
2993 peer->update_if =
2994 XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
2995 }
2996
2997 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2998 {
2999 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3000 {
3001 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
3002 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3003 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3004 }
3005 else
3006 BGP_EVENT_ADD (peer, BGP_Stop);
3007 return 0;
3008 }
3009
3010 /* peer-group member updates. */
3011 group = peer->group;
3012 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3013 {
3014 if (! peer->update_source && ! peer->update_if)
3015 continue;
3016
3017 if (peer->update_source)
3018 {
3019 sockunion_free (peer->update_source);
3020 peer->update_source = NULL;
3021 }
3022
3023 if (peer->update_if)
3024 {
3025 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
3026 peer->update_if = NULL;
3027 }
3028
3029 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3030 {
3031 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
3032 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3033 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3034 }
3035 else
3036 BGP_EVENT_ADD (peer, BGP_Stop);
3037 }
3038 return 0;
3039 }
3040 \f
3041 int
3042 peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
3043 const char *rmap)
3044 {
3045 struct peer_group *group;
3046 struct listnode *node, *nnode;
3047
3048 /* Adress family must be activated. */
3049 if (! peer->afc[afi][safi])
3050 return BGP_ERR_PEER_INACTIVE;
3051
3052 /* Default originate can't be used for peer group memeber. */
3053 if (peer_is_group_member (peer, afi, safi))
3054 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3055
3056 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
3057 || (rmap && ! peer->default_rmap[afi][safi].name)
3058 || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
3059 {
3060 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3061
3062 if (rmap)
3063 {
3064 if (peer->default_rmap[afi][safi].name)
3065 free (peer->default_rmap[afi][safi].name);
3066 peer->default_rmap[afi][safi].name = strdup (rmap);
3067 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
3068 }
3069 }
3070
3071 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3072 {
3073 if (peer->status == Established && peer->afc_nego[afi][safi])
3074 bgp_default_originate (peer, afi, safi, 0);
3075 return 0;
3076 }
3077
3078 /* peer-group member updates. */
3079 group = peer->group;
3080 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3081 {
3082 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3083
3084 if (rmap)
3085 {
3086 if (peer->default_rmap[afi][safi].name)
3087 free (peer->default_rmap[afi][safi].name);
3088 peer->default_rmap[afi][safi].name = strdup (rmap);
3089 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
3090 }
3091
3092 if (peer->status == Established && peer->afc_nego[afi][safi])
3093 bgp_default_originate (peer, afi, safi, 0);
3094 }
3095 return 0;
3096 }
3097
3098 int
3099 peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
3100 {
3101 struct peer_group *group;
3102 struct listnode *node, *nnode;
3103
3104 /* Adress family must be activated. */
3105 if (! peer->afc[afi][safi])
3106 return BGP_ERR_PEER_INACTIVE;
3107
3108 /* Default originate can't be used for peer group memeber. */
3109 if (peer_is_group_member (peer, afi, safi))
3110 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3111
3112 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
3113 {
3114 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3115
3116 if (peer->default_rmap[afi][safi].name)
3117 free (peer->default_rmap[afi][safi].name);
3118 peer->default_rmap[afi][safi].name = NULL;
3119 peer->default_rmap[afi][safi].map = NULL;
3120 }
3121
3122 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3123 {
3124 if (peer->status == Established && peer->afc_nego[afi][safi])
3125 bgp_default_originate (peer, afi, safi, 1);
3126 return 0;
3127 }
3128
3129 /* peer-group member updates. */
3130 group = peer->group;
3131 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3132 {
3133 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
3134
3135 if (peer->default_rmap[afi][safi].name)
3136 free (peer->default_rmap[afi][safi].name);
3137 peer->default_rmap[afi][safi].name = NULL;
3138 peer->default_rmap[afi][safi].map = NULL;
3139
3140 if (peer->status == Established && peer->afc_nego[afi][safi])
3141 bgp_default_originate (peer, afi, safi, 1);
3142 }
3143 return 0;
3144 }
3145 \f
3146 int
3147 peer_port_set (struct peer *peer, u_int16_t port)
3148 {
3149 peer->port = port;
3150 return 0;
3151 }
3152
3153 int
3154 peer_port_unset (struct peer *peer)
3155 {
3156 peer->port = BGP_PORT_DEFAULT;
3157 return 0;
3158 }
3159 \f
3160 /* neighbor weight. */
3161 int
3162 peer_weight_set (struct peer *peer, u_int16_t weight)
3163 {
3164 struct peer_group *group;
3165 struct listnode *node, *nnode;
3166
3167 SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3168 peer->weight = weight;
3169
3170 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3171 return 0;
3172
3173 /* peer-group member updates. */
3174 group = peer->group;
3175 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3176 {
3177 peer->weight = group->conf->weight;
3178 }
3179 return 0;
3180 }
3181
3182 int
3183 peer_weight_unset (struct peer *peer)
3184 {
3185 struct peer_group *group;
3186 struct listnode *node, *nnode;
3187
3188 /* Set default weight. */
3189 if (peer_group_active (peer))
3190 peer->weight = peer->group->conf->weight;
3191 else
3192 peer->weight = 0;
3193
3194 UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
3195
3196 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3197 return 0;
3198
3199 /* peer-group member updates. */
3200 group = peer->group;
3201 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3202 {
3203 peer->weight = 0;
3204 }
3205 return 0;
3206 }
3207 \f
3208 int
3209 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
3210 {
3211 struct peer_group *group;
3212 struct listnode *node, *nnode;
3213
3214 /* Not for peer group memeber. */
3215 if (peer_group_active (peer))
3216 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3217
3218 /* keepalive value check. */
3219 if (keepalive > 65535)
3220 return BGP_ERR_INVALID_VALUE;
3221
3222 /* Holdtime value check. */
3223 if (holdtime > 65535)
3224 return BGP_ERR_INVALID_VALUE;
3225
3226 /* Holdtime value must be either 0 or greater than 3. */
3227 if (holdtime < 3 && holdtime != 0)
3228 return BGP_ERR_INVALID_VALUE;
3229
3230 /* Set value to the configuration. */
3231 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3232 peer->holdtime = holdtime;
3233 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
3234
3235 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3236 return 0;
3237
3238 /* peer-group member updates. */
3239 group = peer->group;
3240 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3241 {
3242 SET_FLAG (peer->config, PEER_CONFIG_TIMER);
3243 peer->holdtime = group->conf->holdtime;
3244 peer->keepalive = group->conf->keepalive;
3245 }
3246 return 0;
3247 }
3248
3249 int
3250 peer_timers_unset (struct peer *peer)
3251 {
3252 struct peer_group *group;
3253 struct listnode *node, *nnode;
3254
3255 if (peer_group_active (peer))
3256 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3257
3258 /* Clear configuration. */
3259 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3260 peer->keepalive = 0;
3261 peer->holdtime = 0;
3262
3263 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3264 return 0;
3265
3266 /* peer-group member updates. */
3267 group = peer->group;
3268 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3269 {
3270 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
3271 peer->holdtime = 0;
3272 peer->keepalive = 0;
3273 }
3274
3275 return 0;
3276 }
3277 \f
3278 int
3279 peer_timers_connect_set (struct peer *peer, u_int32_t connect)
3280 {
3281 if (peer_group_active (peer))
3282 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3283
3284 if (connect > 65535)
3285 return BGP_ERR_INVALID_VALUE;
3286
3287 /* Set value to the configuration. */
3288 SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3289 peer->connect = connect;
3290
3291 /* Set value to timer setting. */
3292 peer->v_connect = connect;
3293
3294 return 0;
3295 }
3296
3297 int
3298 peer_timers_connect_unset (struct peer *peer)
3299 {
3300 if (peer_group_active (peer))
3301 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3302
3303 /* Clear configuration. */
3304 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
3305 peer->connect = 0;
3306
3307 /* Set timer setting to default value. */
3308 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
3309
3310 return 0;
3311 }
3312 \f
3313 int
3314 peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
3315 {
3316 if (peer_group_active (peer))
3317 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3318
3319 if (routeadv > 600)
3320 return BGP_ERR_INVALID_VALUE;
3321
3322 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3323 peer->routeadv = routeadv;
3324 peer->v_routeadv = routeadv;
3325
3326 return 0;
3327 }
3328
3329 int
3330 peer_advertise_interval_unset (struct peer *peer)
3331 {
3332 if (peer_group_active (peer))
3333 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3334
3335 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
3336 peer->routeadv = 0;
3337
3338 if (peer->sort == BGP_PEER_IBGP)
3339 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
3340 else
3341 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
3342
3343 return 0;
3344 }
3345 \f
3346 /* neighbor interface */
3347 int
3348 peer_interface_set (struct peer *peer, const char *str)
3349 {
3350 if (peer->ifname)
3351 free (peer->ifname);
3352 peer->ifname = strdup (str);
3353
3354 return 0;
3355 }
3356
3357 int
3358 peer_interface_unset (struct peer *peer)
3359 {
3360 if (peer->ifname)
3361 free (peer->ifname);
3362 peer->ifname = NULL;
3363
3364 return 0;
3365 }
3366 \f
3367 /* Allow-as in. */
3368 int
3369 peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
3370 {
3371 struct peer_group *group;
3372 struct listnode *node, *nnode;
3373
3374 if (allow_num < 1 || allow_num > 10)
3375 return BGP_ERR_INVALID_VALUE;
3376
3377 if (peer->allowas_in[afi][safi] != allow_num)
3378 {
3379 peer->allowas_in[afi][safi] = allow_num;
3380 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3381 peer_change_action (peer, afi, safi, peer_change_reset_in);
3382 }
3383
3384 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3385 return 0;
3386
3387 group = peer->group;
3388 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3389 {
3390 if (peer->allowas_in[afi][safi] != allow_num)
3391 {
3392 peer->allowas_in[afi][safi] = allow_num;
3393 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
3394 peer_change_action (peer, afi, safi, peer_change_reset_in);
3395 }
3396
3397 }
3398 return 0;
3399 }
3400
3401 int
3402 peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
3403 {
3404 struct peer_group *group;
3405 struct listnode *node, *nnode;
3406
3407 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3408 {
3409 peer->allowas_in[afi][safi] = 0;
3410 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3411 }
3412
3413 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3414 return 0;
3415
3416 group = peer->group;
3417 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3418 {
3419 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
3420 {
3421 peer->allowas_in[afi][safi] = 0;
3422 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
3423 }
3424 }
3425 return 0;
3426 }
3427 \f
3428 int
3429 peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)
3430 {
3431 struct bgp *bgp = peer->bgp;
3432 struct peer_group *group;
3433 struct listnode *node, *nnode;
3434
3435 if (peer_sort (peer) != BGP_PEER_EBGP
3436 && peer_sort (peer) != BGP_PEER_INTERNAL)
3437 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
3438
3439 if (bgp->as == as)
3440 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
3441
3442 if (peer_group_active (peer))
3443 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3444
3445 if (peer->as == as)
3446 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
3447
3448 if (peer->change_local_as == as &&
3449 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
3450 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)) &&
3451 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && replace_as)
3452 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && ! replace_as)))
3453 return 0;
3454
3455 peer->change_local_as = as;
3456 if (no_prepend)
3457 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3458 else
3459 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3460
3461 if (replace_as)
3462 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3463 else
3464 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3465
3466 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3467 {
3468 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3469 {
3470 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3471 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3472 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3473 }
3474 else
3475 BGP_EVENT_ADD (peer, BGP_Stop);
3476
3477 return 0;
3478 }
3479
3480 group = peer->group;
3481 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3482 {
3483 peer->change_local_as = as;
3484 if (no_prepend)
3485 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3486 else
3487 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3488
3489 if (replace_as)
3490 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3491 else
3492 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3493
3494 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3495 {
3496 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3497 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3498 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3499 }
3500 else
3501 BGP_EVENT_ADD (peer, BGP_Stop);
3502 }
3503
3504 return 0;
3505 }
3506
3507 int
3508 peer_local_as_unset (struct peer *peer)
3509 {
3510 struct peer_group *group;
3511 struct listnode *node, *nnode;
3512
3513 if (peer_group_active (peer))
3514 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3515
3516 if (! peer->change_local_as)
3517 return 0;
3518
3519 peer->change_local_as = 0;
3520 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3521 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3522
3523 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3524 {
3525 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3526 {
3527 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3528 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3529 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3530 }
3531 else
3532 BGP_EVENT_ADD (peer, BGP_Stop);
3533
3534 return 0;
3535 }
3536
3537 group = peer->group;
3538 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3539 {
3540 peer->change_local_as = 0;
3541 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
3542 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
3543
3544 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3545 {
3546 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
3547 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
3548 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3549 }
3550 else
3551 BGP_EVENT_ADD (peer, BGP_Stop);
3552 }
3553 return 0;
3554 }
3555 \f
3556 /* Set password for authenticating with the peer. */
3557 int
3558 peer_password_set (struct peer *peer, const char *password)
3559 {
3560 struct listnode *nn, *nnode;
3561 int len = password ? strlen(password) : 0;
3562 int ret = BGP_SUCCESS;
3563
3564 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
3565 return BGP_ERR_INVALID_VALUE;
3566
3567 if (peer->password && strcmp (peer->password, password) == 0
3568 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3569 return 0;
3570
3571 if (peer->password)
3572 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3573
3574 peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
3575
3576 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3577 {
3578 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3579 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3580 else
3581 BGP_EVENT_ADD (peer, BGP_Stop);
3582
3583 return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
3584 }
3585
3586 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3587 {
3588 if (peer->password && strcmp (peer->password, password) == 0)
3589 continue;
3590
3591 if (peer->password)
3592 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3593
3594 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
3595
3596 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3597 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3598 else
3599 BGP_EVENT_ADD (peer, BGP_Stop);
3600
3601 if (bgp_md5_set (peer) < 0)
3602 ret = BGP_ERR_TCPSIG_FAILED;
3603 }
3604
3605 return ret;
3606 }
3607
3608 int
3609 peer_password_unset (struct peer *peer)
3610 {
3611 struct listnode *nn, *nnode;
3612
3613 if (!peer->password
3614 && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3615 return 0;
3616
3617 if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3618 {
3619 if (peer_group_active (peer)
3620 && peer->group->conf->password
3621 && strcmp (peer->group->conf->password, peer->password) == 0)
3622 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
3623
3624 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3625 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3626 else
3627 BGP_EVENT_ADD (peer, BGP_Stop);
3628
3629 if (peer->password)
3630 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3631
3632 peer->password = NULL;
3633
3634 bgp_md5_set (peer);
3635
3636 return 0;
3637 }
3638
3639 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3640 peer->password = NULL;
3641
3642 for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
3643 {
3644 if (!peer->password)
3645 continue;
3646
3647 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3648 bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3649 else
3650 BGP_EVENT_ADD (peer, BGP_Stop);
3651
3652 XFREE (MTYPE_PEER_PASSWORD, peer->password);
3653 peer->password = NULL;
3654
3655 bgp_md5_set (peer);
3656 }
3657
3658 return 0;
3659 }
3660 \f
3661 /* Set distribute list to the peer. */
3662 int
3663 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3664 const char *name)
3665 {
3666 struct bgp_filter *filter;
3667 struct peer_group *group;
3668 struct listnode *node, *nnode;
3669
3670 if (! peer->afc[afi][safi])
3671 return BGP_ERR_PEER_INACTIVE;
3672
3673 if (direct != FILTER_IN && direct != FILTER_OUT)
3674 return BGP_ERR_INVALID_VALUE;
3675
3676 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3677 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3678
3679 filter = &peer->filter[afi][safi];
3680
3681 if (filter->plist[direct].name)
3682 return BGP_ERR_PEER_FILTER_CONFLICT;
3683
3684 if (filter->dlist[direct].name)
3685 free (filter->dlist[direct].name);
3686 filter->dlist[direct].name = strdup (name);
3687 filter->dlist[direct].alist = access_list_lookup (afi, name);
3688
3689 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3690 return 0;
3691
3692 group = peer->group;
3693 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3694 {
3695 filter = &peer->filter[afi][safi];
3696
3697 if (! peer->af_group[afi][safi])
3698 continue;
3699
3700 if (filter->dlist[direct].name)
3701 free (filter->dlist[direct].name);
3702 filter->dlist[direct].name = strdup (name);
3703 filter->dlist[direct].alist = access_list_lookup (afi, name);
3704 }
3705
3706 return 0;
3707 }
3708
3709 int
3710 peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3711 {
3712 struct bgp_filter *filter;
3713 struct bgp_filter *gfilter;
3714 struct peer_group *group;
3715 struct listnode *node, *nnode;
3716
3717 if (! peer->afc[afi][safi])
3718 return BGP_ERR_PEER_INACTIVE;
3719
3720 if (direct != FILTER_IN && direct != FILTER_OUT)
3721 return BGP_ERR_INVALID_VALUE;
3722
3723 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3724 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3725
3726 filter = &peer->filter[afi][safi];
3727
3728 /* apply peer-group filter */
3729 if (peer->af_group[afi][safi])
3730 {
3731 gfilter = &peer->group->conf->filter[afi][safi];
3732
3733 if (gfilter->dlist[direct].name)
3734 {
3735 if (filter->dlist[direct].name)
3736 free (filter->dlist[direct].name);
3737 filter->dlist[direct].name = strdup (gfilter->dlist[direct].name);
3738 filter->dlist[direct].alist = gfilter->dlist[direct].alist;
3739 return 0;
3740 }
3741 }
3742
3743 if (filter->dlist[direct].name)
3744 free (filter->dlist[direct].name);
3745 filter->dlist[direct].name = NULL;
3746 filter->dlist[direct].alist = NULL;
3747
3748 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3749 return 0;
3750
3751 group = peer->group;
3752 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3753 {
3754 filter = &peer->filter[afi][safi];
3755
3756 if (! peer->af_group[afi][safi])
3757 continue;
3758
3759 if (filter->dlist[direct].name)
3760 free (filter->dlist[direct].name);
3761 filter->dlist[direct].name = NULL;
3762 filter->dlist[direct].alist = NULL;
3763 }
3764
3765 return 0;
3766 }
3767
3768 /* Update distribute list. */
3769 static void
3770 peer_distribute_update (struct access_list *access)
3771 {
3772 afi_t afi;
3773 safi_t safi;
3774 int direct;
3775 struct listnode *mnode, *mnnode;
3776 struct listnode *node, *nnode;
3777 struct bgp *bgp;
3778 struct peer *peer;
3779 struct peer_group *group;
3780 struct bgp_filter *filter;
3781
3782 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3783 {
3784 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3785 {
3786 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3787 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3788 {
3789 filter = &peer->filter[afi][safi];
3790
3791 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3792 {
3793 if (filter->dlist[direct].name)
3794 filter->dlist[direct].alist =
3795 access_list_lookup (afi, filter->dlist[direct].name);
3796 else
3797 filter->dlist[direct].alist = NULL;
3798 }
3799 }
3800 }
3801 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3802 {
3803 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3804 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3805 {
3806 filter = &group->conf->filter[afi][safi];
3807
3808 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3809 {
3810 if (filter->dlist[direct].name)
3811 filter->dlist[direct].alist =
3812 access_list_lookup (afi, filter->dlist[direct].name);
3813 else
3814 filter->dlist[direct].alist = NULL;
3815 }
3816 }
3817 }
3818 }
3819 }
3820 \f
3821 /* Set prefix list to the peer. */
3822 int
3823 peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3824 const char *name)
3825 {
3826 struct bgp_filter *filter;
3827 struct peer_group *group;
3828 struct listnode *node, *nnode;
3829
3830 if (! peer->afc[afi][safi])
3831 return BGP_ERR_PEER_INACTIVE;
3832
3833 if (direct != FILTER_IN && direct != FILTER_OUT)
3834 return BGP_ERR_INVALID_VALUE;
3835
3836 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3837 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3838
3839 filter = &peer->filter[afi][safi];
3840
3841 if (filter->dlist[direct].name)
3842 return BGP_ERR_PEER_FILTER_CONFLICT;
3843
3844 if (filter->plist[direct].name)
3845 free (filter->plist[direct].name);
3846 filter->plist[direct].name = strdup (name);
3847 filter->plist[direct].plist = prefix_list_lookup (afi, name);
3848
3849 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3850 return 0;
3851
3852 group = peer->group;
3853 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3854 {
3855 filter = &peer->filter[afi][safi];
3856
3857 if (! peer->af_group[afi][safi])
3858 continue;
3859
3860 if (filter->plist[direct].name)
3861 free (filter->plist[direct].name);
3862 filter->plist[direct].name = strdup (name);
3863 filter->plist[direct].plist = prefix_list_lookup (afi, name);
3864 }
3865 return 0;
3866 }
3867
3868 int
3869 peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
3870 {
3871 struct bgp_filter *filter;
3872 struct bgp_filter *gfilter;
3873 struct peer_group *group;
3874 struct listnode *node, *nnode;
3875
3876 if (! peer->afc[afi][safi])
3877 return BGP_ERR_PEER_INACTIVE;
3878
3879 if (direct != FILTER_IN && direct != FILTER_OUT)
3880 return BGP_ERR_INVALID_VALUE;
3881
3882 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3883 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3884
3885 filter = &peer->filter[afi][safi];
3886
3887 /* apply peer-group filter */
3888 if (peer->af_group[afi][safi])
3889 {
3890 gfilter = &peer->group->conf->filter[afi][safi];
3891
3892 if (gfilter->plist[direct].name)
3893 {
3894 if (filter->plist[direct].name)
3895 free (filter->plist[direct].name);
3896 filter->plist[direct].name = strdup (gfilter->plist[direct].name);
3897 filter->plist[direct].plist = gfilter->plist[direct].plist;
3898 return 0;
3899 }
3900 }
3901
3902 if (filter->plist[direct].name)
3903 free (filter->plist[direct].name);
3904 filter->plist[direct].name = NULL;
3905 filter->plist[direct].plist = NULL;
3906
3907 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3908 return 0;
3909
3910 group = peer->group;
3911 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
3912 {
3913 filter = &peer->filter[afi][safi];
3914
3915 if (! peer->af_group[afi][safi])
3916 continue;
3917
3918 if (filter->plist[direct].name)
3919 free (filter->plist[direct].name);
3920 filter->plist[direct].name = NULL;
3921 filter->plist[direct].plist = NULL;
3922 }
3923
3924 return 0;
3925 }
3926
3927 /* Update prefix-list list. */
3928 static void
3929 peer_prefix_list_update (struct prefix_list *plist)
3930 {
3931 struct listnode *mnode, *mnnode;
3932 struct listnode *node, *nnode;
3933 struct bgp *bgp;
3934 struct peer *peer;
3935 struct peer_group *group;
3936 struct bgp_filter *filter;
3937 afi_t afi;
3938 safi_t safi;
3939 int direct;
3940
3941 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
3942 {
3943 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
3944 {
3945 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3946 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3947 {
3948 filter = &peer->filter[afi][safi];
3949
3950 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3951 {
3952 if (filter->plist[direct].name)
3953 filter->plist[direct].plist =
3954 prefix_list_lookup (afi, filter->plist[direct].name);
3955 else
3956 filter->plist[direct].plist = NULL;
3957 }
3958 }
3959 }
3960 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
3961 {
3962 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3963 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3964 {
3965 filter = &group->conf->filter[afi][safi];
3966
3967 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
3968 {
3969 if (filter->plist[direct].name)
3970 filter->plist[direct].plist =
3971 prefix_list_lookup (afi, filter->plist[direct].name);
3972 else
3973 filter->plist[direct].plist = NULL;
3974 }
3975 }
3976 }
3977 }
3978 }
3979 \f
3980 int
3981 peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
3982 const char *name)
3983 {
3984 struct bgp_filter *filter;
3985 struct peer_group *group;
3986 struct listnode *node, *nnode;
3987
3988 if (! peer->afc[afi][safi])
3989 return BGP_ERR_PEER_INACTIVE;
3990
3991 if (direct != FILTER_IN && direct != FILTER_OUT)
3992 return BGP_ERR_INVALID_VALUE;
3993
3994 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
3995 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
3996
3997 filter = &peer->filter[afi][safi];
3998
3999 if (filter->aslist[direct].name)
4000 free (filter->aslist[direct].name);
4001 filter->aslist[direct].name = strdup (name);
4002 filter->aslist[direct].aslist = as_list_lookup (name);
4003
4004 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4005 return 0;
4006
4007 group = peer->group;
4008 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4009 {
4010 filter = &peer->filter[afi][safi];
4011
4012 if (! peer->af_group[afi][safi])
4013 continue;
4014
4015 if (filter->aslist[direct].name)
4016 free (filter->aslist[direct].name);
4017 filter->aslist[direct].name = strdup (name);
4018 filter->aslist[direct].aslist = as_list_lookup (name);
4019 }
4020 return 0;
4021 }
4022
4023 int
4024 peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
4025 {
4026 struct bgp_filter *filter;
4027 struct bgp_filter *gfilter;
4028 struct peer_group *group;
4029 struct listnode *node, *nnode;
4030
4031 if (! peer->afc[afi][safi])
4032 return BGP_ERR_PEER_INACTIVE;
4033
4034 if (direct != FILTER_IN && direct != FILTER_OUT)
4035 return BGP_ERR_INVALID_VALUE;
4036
4037 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
4038 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4039
4040 filter = &peer->filter[afi][safi];
4041
4042 /* apply peer-group filter */
4043 if (peer->af_group[afi][safi])
4044 {
4045 gfilter = &peer->group->conf->filter[afi][safi];
4046
4047 if (gfilter->aslist[direct].name)
4048 {
4049 if (filter->aslist[direct].name)
4050 free (filter->aslist[direct].name);
4051 filter->aslist[direct].name = strdup (gfilter->aslist[direct].name);
4052 filter->aslist[direct].aslist = gfilter->aslist[direct].aslist;
4053 return 0;
4054 }
4055 }
4056
4057 if (filter->aslist[direct].name)
4058 free (filter->aslist[direct].name);
4059 filter->aslist[direct].name = NULL;
4060 filter->aslist[direct].aslist = NULL;
4061
4062 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4063 return 0;
4064
4065 group = peer->group;
4066 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4067 {
4068 filter = &peer->filter[afi][safi];
4069
4070 if (! peer->af_group[afi][safi])
4071 continue;
4072
4073 if (filter->aslist[direct].name)
4074 free (filter->aslist[direct].name);
4075 filter->aslist[direct].name = NULL;
4076 filter->aslist[direct].aslist = NULL;
4077 }
4078
4079 return 0;
4080 }
4081
4082 static void
4083 peer_aslist_update (void)
4084 {
4085 afi_t afi;
4086 safi_t safi;
4087 int direct;
4088 struct listnode *mnode, *mnnode;
4089 struct listnode *node, *nnode;
4090 struct bgp *bgp;
4091 struct peer *peer;
4092 struct peer_group *group;
4093 struct bgp_filter *filter;
4094
4095 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
4096 {
4097 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
4098 {
4099 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4100 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4101 {
4102 filter = &peer->filter[afi][safi];
4103
4104 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4105 {
4106 if (filter->aslist[direct].name)
4107 filter->aslist[direct].aslist =
4108 as_list_lookup (filter->aslist[direct].name);
4109 else
4110 filter->aslist[direct].aslist = NULL;
4111 }
4112 }
4113 }
4114 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
4115 {
4116 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4117 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4118 {
4119 filter = &group->conf->filter[afi][safi];
4120
4121 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
4122 {
4123 if (filter->aslist[direct].name)
4124 filter->aslist[direct].aslist =
4125 as_list_lookup (filter->aslist[direct].name);
4126 else
4127 filter->aslist[direct].aslist = NULL;
4128 }
4129 }
4130 }
4131 }
4132 }
4133 \f
4134 /* Set route-map to the peer. */
4135 int
4136 peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
4137 const char *name)
4138 {
4139 struct bgp_filter *filter;
4140 struct peer_group *group;
4141 struct listnode *node, *nnode;
4142
4143 if (! peer->afc[afi][safi])
4144 return BGP_ERR_PEER_INACTIVE;
4145
4146 if (direct != RMAP_IN && direct != RMAP_OUT &&
4147 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4148 return BGP_ERR_INVALID_VALUE;
4149
4150 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4151 && peer_is_group_member (peer, afi, safi))
4152 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4153
4154 filter = &peer->filter[afi][safi];
4155
4156 if (filter->map[direct].name)
4157 free (filter->map[direct].name);
4158
4159 filter->map[direct].name = strdup (name);
4160 filter->map[direct].map = route_map_lookup_by_name (name);
4161
4162 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4163 return 0;
4164
4165 group = peer->group;
4166 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4167 {
4168 filter = &peer->filter[afi][safi];
4169
4170 if (! peer->af_group[afi][safi])
4171 continue;
4172
4173 if (filter->map[direct].name)
4174 free (filter->map[direct].name);
4175 filter->map[direct].name = strdup (name);
4176 filter->map[direct].map = route_map_lookup_by_name (name);
4177 }
4178 return 0;
4179 }
4180
4181 /* Unset route-map from the peer. */
4182 int
4183 peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
4184 {
4185 struct bgp_filter *filter;
4186 struct bgp_filter *gfilter;
4187 struct peer_group *group;
4188 struct listnode *node, *nnode;
4189
4190 if (! peer->afc[afi][safi])
4191 return BGP_ERR_PEER_INACTIVE;
4192
4193 if (direct != RMAP_IN && direct != RMAP_OUT &&
4194 direct != RMAP_IMPORT && direct != RMAP_EXPORT)
4195 return BGP_ERR_INVALID_VALUE;
4196
4197 if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
4198 && peer_is_group_member (peer, afi, safi))
4199 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4200
4201 filter = &peer->filter[afi][safi];
4202
4203 /* apply peer-group filter */
4204 if (peer->af_group[afi][safi])
4205 {
4206 gfilter = &peer->group->conf->filter[afi][safi];
4207
4208 if (gfilter->map[direct].name)
4209 {
4210 if (filter->map[direct].name)
4211 free (filter->map[direct].name);
4212 filter->map[direct].name = strdup (gfilter->map[direct].name);
4213 filter->map[direct].map = gfilter->map[direct].map;
4214 return 0;
4215 }
4216 }
4217
4218 if (filter->map[direct].name)
4219 free (filter->map[direct].name);
4220 filter->map[direct].name = NULL;
4221 filter->map[direct].map = NULL;
4222
4223 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4224 return 0;
4225
4226 group = peer->group;
4227 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4228 {
4229 filter = &peer->filter[afi][safi];
4230
4231 if (! peer->af_group[afi][safi])
4232 continue;
4233
4234 if (filter->map[direct].name)
4235 free (filter->map[direct].name);
4236 filter->map[direct].name = NULL;
4237 filter->map[direct].map = NULL;
4238 }
4239 return 0;
4240 }
4241 \f
4242 /* Set unsuppress-map to the peer. */
4243 int
4244 peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
4245 const char *name)
4246 {
4247 struct bgp_filter *filter;
4248 struct peer_group *group;
4249 struct listnode *node, *nnode;
4250
4251 if (! peer->afc[afi][safi])
4252 return BGP_ERR_PEER_INACTIVE;
4253
4254 if (peer_is_group_member (peer, afi, safi))
4255 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4256
4257 filter = &peer->filter[afi][safi];
4258
4259 if (filter->usmap.name)
4260 free (filter->usmap.name);
4261
4262 filter->usmap.name = strdup (name);
4263 filter->usmap.map = route_map_lookup_by_name (name);
4264
4265 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4266 return 0;
4267
4268 group = peer->group;
4269 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4270 {
4271 filter = &peer->filter[afi][safi];
4272
4273 if (! peer->af_group[afi][safi])
4274 continue;
4275
4276 if (filter->usmap.name)
4277 free (filter->usmap.name);
4278 filter->usmap.name = strdup (name);
4279 filter->usmap.map = route_map_lookup_by_name (name);
4280 }
4281 return 0;
4282 }
4283
4284 /* Unset route-map from the peer. */
4285 int
4286 peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
4287 {
4288 struct bgp_filter *filter;
4289 struct peer_group *group;
4290 struct listnode *node, *nnode;
4291
4292 if (! peer->afc[afi][safi])
4293 return BGP_ERR_PEER_INACTIVE;
4294
4295 if (peer_is_group_member (peer, afi, safi))
4296 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
4297
4298 filter = &peer->filter[afi][safi];
4299
4300 if (filter->usmap.name)
4301 free (filter->usmap.name);
4302 filter->usmap.name = NULL;
4303 filter->usmap.map = NULL;
4304
4305 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4306 return 0;
4307
4308 group = peer->group;
4309 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4310 {
4311 filter = &peer->filter[afi][safi];
4312
4313 if (! peer->af_group[afi][safi])
4314 continue;
4315
4316 if (filter->usmap.name)
4317 free (filter->usmap.name);
4318 filter->usmap.name = NULL;
4319 filter->usmap.map = NULL;
4320 }
4321 return 0;
4322 }
4323 \f
4324 int
4325 peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
4326 u_int32_t max, u_char threshold,
4327 int warning, u_int16_t restart)
4328 {
4329 struct peer_group *group;
4330 struct listnode *node, *nnode;
4331
4332 if (! peer->afc[afi][safi])
4333 return BGP_ERR_PEER_INACTIVE;
4334
4335 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4336 peer->pmax[afi][safi] = max;
4337 peer->pmax_threshold[afi][safi] = threshold;
4338 peer->pmax_restart[afi][safi] = restart;
4339 if (warning)
4340 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4341 else
4342 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4343
4344 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4345 return 0;
4346
4347 group = peer->group;
4348 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4349 {
4350 if (! peer->af_group[afi][safi])
4351 continue;
4352
4353 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4354 peer->pmax[afi][safi] = max;
4355 peer->pmax_threshold[afi][safi] = threshold;
4356 peer->pmax_restart[afi][safi] = restart;
4357 if (warning)
4358 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4359 else
4360 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4361 }
4362 return 0;
4363 }
4364
4365 int
4366 peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
4367 {
4368 struct peer_group *group;
4369 struct listnode *node, *nnode;
4370
4371 if (! peer->afc[afi][safi])
4372 return BGP_ERR_PEER_INACTIVE;
4373
4374 /* apply peer-group config */
4375 if (peer->af_group[afi][safi])
4376 {
4377 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4378 PEER_FLAG_MAX_PREFIX))
4379 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4380 else
4381 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4382
4383 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
4384 PEER_FLAG_MAX_PREFIX_WARNING))
4385 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4386 else
4387 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4388
4389 peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
4390 peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
4391 peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
4392 return 0;
4393 }
4394
4395 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4396 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4397 peer->pmax[afi][safi] = 0;
4398 peer->pmax_threshold[afi][safi] = 0;
4399 peer->pmax_restart[afi][safi] = 0;
4400
4401 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4402 return 0;
4403
4404 group = peer->group;
4405 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4406 {
4407 if (! peer->af_group[afi][safi])
4408 continue;
4409
4410 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
4411 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
4412 peer->pmax[afi][safi] = 0;
4413 peer->pmax_threshold[afi][safi] = 0;
4414 peer->pmax_restart[afi][safi] = 0;
4415 }
4416 return 0;
4417 }
4418
4419 static int is_ebgp_multihop_configured (struct peer *peer)
4420 {
4421 struct peer_group *group;
4422 struct listnode *node, *nnode;
4423 struct peer *peer1;
4424
4425 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4426 {
4427 group = peer->group;
4428 if ((peer_sort(peer) != BGP_PEER_IBGP) &&
4429 (group->conf->ttl != 1))
4430 return 1;
4431
4432 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
4433 {
4434 if ((peer_sort (peer1) != BGP_PEER_IBGP) &&
4435 (peer1->ttl != 1))
4436 return 1;
4437 }
4438 }
4439 else
4440 {
4441 if ((peer_sort(peer) != BGP_PEER_IBGP) &&
4442 (peer->ttl != 1))
4443 return 1;
4444 }
4445 return 0;
4446 }
4447
4448 /* Set # of hops between us and BGP peer. */
4449 int
4450 peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
4451 {
4452 struct peer_group *group;
4453 struct listnode *node, *nnode;
4454 int ret;
4455
4456 zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
4457
4458 /* We cannot configure ttl-security hops when ebgp-multihop is already
4459 set. For non peer-groups, the check is simple. For peer-groups, it's
4460 slightly messy, because we need to check both the peer-group structure
4461 and all peer-group members for any trace of ebgp-multihop configuration
4462 before actually applying the ttl-security rules. Cisco really made a
4463 mess of this configuration parameter, and OpenBGPD got it right.
4464 */
4465
4466 if (peer->gtsm_hops == 0)
4467 {
4468 if (is_ebgp_multihop_configured (peer))
4469 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4470
4471 /* specify MAXTTL on outgoing packets */
4472 /* Routine handles iBGP peers correctly */
4473 ret = peer_ebgp_multihop_set (peer, MAXTTL);
4474 if (ret != 0)
4475 return ret;
4476 }
4477
4478 peer->gtsm_hops = gtsm_hops;
4479
4480 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4481 {
4482 if (peer->fd >= 0)
4483 sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
4484 }
4485 else
4486 {
4487 group = peer->group;
4488 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4489 {
4490 peer->gtsm_hops = group->conf->gtsm_hops;
4491
4492 /* Change setting of existing peer
4493 * established then change value (may break connectivity)
4494 * not established yet (teardown session and restart)
4495 * no session then do nothing (will get handled by next connection)
4496 */
4497 if (peer->status == Established)
4498 {
4499 if (peer->fd >= 0 && peer->gtsm_hops != 0)
4500 sockopt_minttl (peer->su.sa.sa_family, peer->fd,
4501 MAXTTL + 1 - peer->gtsm_hops);
4502 }
4503 else if (peer->status < Established)
4504 {
4505 if (BGP_DEBUG (events, EVENTS))
4506 zlog_debug ("%s Min-ttl changed", peer->host);
4507 BGP_EVENT_ADD (peer, BGP_Stop);
4508 }
4509 }
4510 }
4511
4512 return 0;
4513 }
4514
4515 int
4516 peer_ttl_security_hops_unset (struct peer *peer)
4517 {
4518 struct peer_group *group;
4519 struct listnode *node, *nnode;
4520 struct peer *opeer;
4521
4522 zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
4523
4524 /* if a peer-group member, then reset to peer-group default rather than 0 */
4525 if (peer_group_active (peer))
4526 peer->gtsm_hops = peer->group->conf->gtsm_hops;
4527 else
4528 peer->gtsm_hops = 0;
4529
4530 opeer = peer;
4531 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4532 {
4533 if (peer->fd >= 0)
4534 sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
4535 }
4536 else
4537 {
4538 group = peer->group;
4539 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
4540 {
4541 peer->gtsm_hops = 0;
4542
4543 if (peer->fd >= 0)
4544 sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
4545 }
4546 }
4547
4548 return peer_ebgp_multihop_unset (opeer);
4549 }
4550 \f
4551 int
4552 peer_clear (struct peer *peer)
4553 {
4554 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4555 {
4556 if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4557 {
4558 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
4559 if (peer->t_pmax_restart)
4560 {
4561 BGP_TIMER_OFF (peer->t_pmax_restart);
4562 if (BGP_DEBUG (events, EVENTS))
4563 zlog_debug ("%s Maximum-prefix restart timer canceled",
4564 peer->host);
4565 }
4566 BGP_EVENT_ADD (peer, BGP_Start);
4567 return 0;
4568 }
4569
4570 peer->v_start = BGP_INIT_START_TIMER;
4571 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4572 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
4573 BGP_NOTIFY_CEASE_ADMIN_RESET);
4574 else
4575 BGP_EVENT_ADD (peer, BGP_Stop);
4576 }
4577 return 0;
4578 }
4579
4580 int
4581 peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
4582 enum bgp_clear_type stype)
4583 {
4584 if (peer->status != Established)
4585 return 0;
4586
4587 if (! peer->afc[afi][safi])
4588 return BGP_ERR_AF_UNCONFIGURED;
4589
4590 if (stype == BGP_CLEAR_SOFT_RSCLIENT)
4591 {
4592 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
4593 return 0;
4594 bgp_check_local_routes_rsclient (peer, afi, safi);
4595 bgp_soft_reconfig_rsclient (peer, afi, safi);
4596 }
4597
4598 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
4599 bgp_announce_route (peer, afi, safi);
4600
4601 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4602 {
4603 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)
4604 && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
4605 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
4606 {
4607 struct bgp_filter *filter = &peer->filter[afi][safi];
4608 u_char prefix_type;
4609
4610 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
4611 prefix_type = ORF_TYPE_PREFIX;
4612 else
4613 prefix_type = ORF_TYPE_PREFIX_OLD;
4614
4615 if (filter->plist[FILTER_IN].plist)
4616 {
4617 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4618 bgp_route_refresh_send (peer, afi, safi,
4619 prefix_type, REFRESH_DEFER, 1);
4620 bgp_route_refresh_send (peer, afi, safi, prefix_type,
4621 REFRESH_IMMEDIATE, 0);
4622 }
4623 else
4624 {
4625 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
4626 bgp_route_refresh_send (peer, afi, safi,
4627 prefix_type, REFRESH_IMMEDIATE, 1);
4628 else
4629 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4630 }
4631 return 0;
4632 }
4633 }
4634
4635 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
4636 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
4637 {
4638 /* If neighbor has soft reconfiguration inbound flag.
4639 Use Adj-RIB-In database. */
4640 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
4641 bgp_soft_reconfig_in (peer, afi, safi);
4642 else
4643 {
4644 /* If neighbor has route refresh capability, send route refresh
4645 message to the peer. */
4646 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4647 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4648 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
4649 else
4650 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
4651 }
4652 }
4653 return 0;
4654 }
4655 \f
4656 /* Display peer uptime.*/
4657 /* XXX: why does this function return char * when it takes buffer? */
4658 char *
4659 peer_uptime (time_t uptime2, char *buf, size_t len)
4660 {
4661 time_t uptime1;
4662 struct tm *tm;
4663
4664 /* Check buffer length. */
4665 if (len < BGP_UPTIME_LEN)
4666 {
4667 zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
4668 /* XXX: should return status instead of buf... */
4669 snprintf (buf, len, "<error> ");
4670 return buf;
4671 }
4672
4673 /* If there is no connection has been done before print `never'. */
4674 if (uptime2 == 0)
4675 {
4676 snprintf (buf, len, "never ");
4677 return buf;
4678 }
4679
4680 /* Get current time. */
4681 uptime1 = bgp_clock ();
4682 uptime1 -= uptime2;
4683 tm = gmtime (&uptime1);
4684
4685 /* Making formatted timer strings. */
4686 #define ONE_DAY_SECOND 60*60*24
4687 #define ONE_WEEK_SECOND 60*60*24*7
4688
4689 if (uptime1 < ONE_DAY_SECOND)
4690 snprintf (buf, len, "%02d:%02d:%02d",
4691 tm->tm_hour, tm->tm_min, tm->tm_sec);
4692 else if (uptime1 < ONE_WEEK_SECOND)
4693 snprintf (buf, len, "%dd%02dh%02dm",
4694 tm->tm_yday, tm->tm_hour, tm->tm_min);
4695 else
4696 snprintf (buf, len, "%02dw%dd%02dh",
4697 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
4698 return buf;
4699 }
4700 \f
4701 static void
4702 bgp_config_write_filter (struct vty *vty, struct peer *peer,
4703 afi_t afi, safi_t safi)
4704 {
4705 struct bgp_filter *filter;
4706 struct bgp_filter *gfilter = NULL;
4707 char *addr;
4708 int in = FILTER_IN;
4709 int out = FILTER_OUT;
4710
4711 addr = peer->host;
4712 filter = &peer->filter[afi][safi];
4713 if (peer->af_group[afi][safi])
4714 gfilter = &peer->group->conf->filter[afi][safi];
4715
4716 /* distribute-list. */
4717 if (filter->dlist[in].name)
4718 if (! gfilter || ! gfilter->dlist[in].name
4719 || strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
4720 vty_out (vty, " neighbor %s distribute-list %s in%s", addr,
4721 filter->dlist[in].name, VTY_NEWLINE);
4722 if (filter->dlist[out].name && ! gfilter)
4723 vty_out (vty, " neighbor %s distribute-list %s out%s", addr,
4724 filter->dlist[out].name, VTY_NEWLINE);
4725
4726 /* prefix-list. */
4727 if (filter->plist[in].name)
4728 if (! gfilter || ! gfilter->plist[in].name
4729 || strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
4730 vty_out (vty, " neighbor %s prefix-list %s in%s", addr,
4731 filter->plist[in].name, VTY_NEWLINE);
4732 if (filter->plist[out].name && ! gfilter)
4733 vty_out (vty, " neighbor %s prefix-list %s out%s", addr,
4734 filter->plist[out].name, VTY_NEWLINE);
4735
4736 /* route-map. */
4737 if (filter->map[RMAP_IN].name)
4738 if (! gfilter || ! gfilter->map[RMAP_IN].name
4739 || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
4740 vty_out (vty, " neighbor %s route-map %s in%s", addr,
4741 filter->map[RMAP_IN].name, VTY_NEWLINE);
4742 if (filter->map[RMAP_OUT].name && ! gfilter)
4743 vty_out (vty, " neighbor %s route-map %s out%s", addr,
4744 filter->map[RMAP_OUT].name, VTY_NEWLINE);
4745 if (filter->map[RMAP_IMPORT].name && ! gfilter)
4746 vty_out (vty, " neighbor %s route-map %s import%s", addr,
4747 filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
4748 if (filter->map[RMAP_EXPORT].name)
4749 if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
4750 || strcmp (filter->map[RMAP_EXPORT].name,
4751 gfilter->map[RMAP_EXPORT].name) != 0)
4752 vty_out (vty, " neighbor %s route-map %s export%s", addr,
4753 filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
4754
4755 /* unsuppress-map */
4756 if (filter->usmap.name && ! gfilter)
4757 vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
4758 filter->usmap.name, VTY_NEWLINE);
4759
4760 /* filter-list. */
4761 if (filter->aslist[in].name)
4762 if (! gfilter || ! gfilter->aslist[in].name
4763 || strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
4764 vty_out (vty, " neighbor %s filter-list %s in%s", addr,
4765 filter->aslist[in].name, VTY_NEWLINE);
4766 if (filter->aslist[out].name && ! gfilter)
4767 vty_out (vty, " neighbor %s filter-list %s out%s", addr,
4768 filter->aslist[out].name, VTY_NEWLINE);
4769 }
4770
4771 /* BGP peer configuration display function. */
4772 static void
4773 bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
4774 struct peer *peer, afi_t afi, safi_t safi)
4775 {
4776 struct peer *g_peer = NULL;
4777 char buf[SU_ADDRSTRLEN];
4778 char *addr;
4779
4780 addr = peer->host;
4781 if (peer_group_active (peer))
4782 g_peer = peer->group->conf;
4783
4784 /************************************
4785 ****** Global to the neighbor ******
4786 ************************************/
4787 if (afi == AFI_IP && safi == SAFI_UNICAST)
4788 {
4789 /* remote-as. */
4790 if (! peer_group_active (peer))
4791 {
4792 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
4793 vty_out (vty, " neighbor %s peer-group%s", addr,
4794 VTY_NEWLINE);
4795 if (peer->as)
4796 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4797 VTY_NEWLINE);
4798 }
4799 else
4800 {
4801 if (! g_peer->as)
4802 vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
4803 VTY_NEWLINE);
4804 if (peer->af_group[AFI_IP][SAFI_UNICAST])
4805 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4806 peer->group->name, VTY_NEWLINE);
4807 }
4808
4809 /* local-as. */
4810 if (peer->change_local_as)
4811 if (! peer_group_active (peer))
4812 vty_out (vty, " neighbor %s local-as %u%s%s%s", addr,
4813 peer->change_local_as,
4814 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
4815 " no-prepend" : "",
4816 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ?
4817 " replace-as" : "", VTY_NEWLINE);
4818
4819 /* Description. */
4820 if (peer->desc)
4821 vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
4822 VTY_NEWLINE);
4823
4824 /* Shutdown. */
4825 if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
4826 if (! peer_group_active (peer) ||
4827 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
4828 vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
4829
4830 /* Password. */
4831 if (peer->password)
4832 if (!peer_group_active (peer)
4833 || ! g_peer->password
4834 || strcmp (peer->password, g_peer->password) != 0)
4835 vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
4836 VTY_NEWLINE);
4837
4838 /* BGP port. */
4839 if (peer->port != BGP_PORT_DEFAULT)
4840 vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
4841 VTY_NEWLINE);
4842
4843 /* Local interface name. */
4844 if (peer->ifname)
4845 vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
4846 VTY_NEWLINE);
4847
4848 /* Passive. */
4849 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
4850 if (! peer_group_active (peer) ||
4851 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
4852 vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
4853
4854 /* EBGP multihop. */
4855 if (peer->sort != BGP_PEER_IBGP && peer->ttl != 1 &&
4856 !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL))
4857 if (! peer_group_active (peer) ||
4858 g_peer->ttl != peer->ttl)
4859 vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
4860 VTY_NEWLINE);
4861
4862 /* ttl-security hops */
4863 if (peer->gtsm_hops != 0)
4864 if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)
4865 vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
4866 peer->gtsm_hops, VTY_NEWLINE);
4867
4868 /* disable-connected-check. */
4869 if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4870 if (! peer_group_active (peer) ||
4871 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
4872 vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
4873
4874 /* Update-source. */
4875 if (peer->update_if)
4876 if (! peer_group_active (peer) || ! g_peer->update_if
4877 || strcmp (g_peer->update_if, peer->update_if) != 0)
4878 vty_out (vty, " neighbor %s update-source %s%s", addr,
4879 peer->update_if, VTY_NEWLINE);
4880 if (peer->update_source)
4881 if (! peer_group_active (peer) || ! g_peer->update_source
4882 || sockunion_cmp (g_peer->update_source,
4883 peer->update_source) != 0)
4884 vty_out (vty, " neighbor %s update-source %s%s", addr,
4885 sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN),
4886 VTY_NEWLINE);
4887
4888 /* advertisement-interval */
4889 if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV))
4890 vty_out (vty, " neighbor %s advertisement-interval %d%s",
4891 addr, peer->v_routeadv, VTY_NEWLINE);
4892
4893 /* timers. */
4894 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
4895 && ! peer_group_active (peer))
4896 vty_out (vty, " neighbor %s timers %d %d%s", addr,
4897 peer->keepalive, peer->holdtime, VTY_NEWLINE);
4898
4899 if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT))
4900 vty_out (vty, " neighbor %s timers connect %d%s", addr,
4901 peer->connect, VTY_NEWLINE);
4902
4903 /* Default weight. */
4904 if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
4905 if (! peer_group_active (peer) ||
4906 g_peer->weight != peer->weight)
4907 vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
4908 VTY_NEWLINE);
4909
4910 /* Dynamic capability. */
4911 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
4912 if (! peer_group_active (peer) ||
4913 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
4914 vty_out (vty, " neighbor %s capability dynamic%s", addr,
4915 VTY_NEWLINE);
4916
4917 /* dont capability negotiation. */
4918 if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
4919 if (! peer_group_active (peer) ||
4920 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
4921 vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
4922 VTY_NEWLINE);
4923
4924 /* override capability negotiation. */
4925 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
4926 if (! peer_group_active (peer) ||
4927 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
4928 vty_out (vty, " neighbor %s override-capability%s", addr,
4929 VTY_NEWLINE);
4930
4931 /* strict capability negotiation. */
4932 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
4933 if (! peer_group_active (peer) ||
4934 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
4935 vty_out (vty, " neighbor %s strict-capability-match%s", addr,
4936 VTY_NEWLINE);
4937
4938 if (! peer->af_group[AFI_IP][SAFI_UNICAST])
4939 {
4940 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
4941 {
4942 if (peer->afc[AFI_IP][SAFI_UNICAST])
4943 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4944 }
4945 else
4946 {
4947 if (! peer->afc[AFI_IP][SAFI_UNICAST])
4948 vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
4949 }
4950 }
4951 }
4952
4953
4954 /************************************
4955 ****** Per AF to the neighbor ******
4956 ************************************/
4957
4958 if (! (afi == AFI_IP && safi == SAFI_UNICAST))
4959 {
4960 if (peer->af_group[afi][safi])
4961 vty_out (vty, " neighbor %s peer-group %s%s", addr,
4962 peer->group->name, VTY_NEWLINE);
4963 else
4964 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
4965 }
4966
4967 /* ORF capability. */
4968 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
4969 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
4970 if (! peer->af_group[afi][safi])
4971 {
4972 vty_out (vty, " neighbor %s capability orf prefix-list", addr);
4973
4974 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
4975 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
4976 vty_out (vty, " both");
4977 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
4978 vty_out (vty, " send");
4979 else
4980 vty_out (vty, " receive");
4981 vty_out (vty, "%s", VTY_NEWLINE);
4982 }
4983
4984 /* Route reflector client. */
4985 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
4986 && ! peer->af_group[afi][safi])
4987 vty_out (vty, " neighbor %s route-reflector-client%s", addr,
4988 VTY_NEWLINE);
4989
4990 /* Nexthop self. */
4991 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
4992 && ! peer->af_group[afi][safi])
4993 vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
4994
4995 /* Remove private AS. */
4996 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
4997 && ! peer->af_group[afi][safi])
4998 vty_out (vty, " neighbor %s remove-private-AS%s",
4999 addr, VTY_NEWLINE);
5000
5001 /* send-community print. */
5002 if (! peer->af_group[afi][safi])
5003 {
5004 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5005 {
5006 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
5007 && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
5008 vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE);
5009 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
5010 vty_out (vty, " neighbor %s send-community extended%s",
5011 addr, VTY_NEWLINE);
5012 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
5013 vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
5014 }
5015 else
5016 {
5017 if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
5018 && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
5019 vty_out (vty, " no neighbor %s send-community both%s",
5020 addr, VTY_NEWLINE);
5021 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
5022 vty_out (vty, " no neighbor %s send-community extended%s",
5023 addr, VTY_NEWLINE);
5024 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
5025 vty_out (vty, " no neighbor %s send-community%s",
5026 addr, VTY_NEWLINE);
5027 }
5028 }
5029
5030 /* Default information */
5031 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
5032 && ! peer->af_group[afi][safi])
5033 {
5034 vty_out (vty, " neighbor %s default-originate", addr);
5035 if (peer->default_rmap[afi][safi].name)
5036 vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
5037 vty_out (vty, "%s", VTY_NEWLINE);
5038 }
5039
5040 /* Soft reconfiguration inbound. */
5041 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5042 if (! peer->af_group[afi][safi] ||
5043 ! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5044 vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
5045 VTY_NEWLINE);
5046
5047 /* maximum-prefix. */
5048 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
5049 if (! peer->af_group[afi][safi]
5050 || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
5051 || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
5052 || CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
5053 != CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
5054 {
5055 vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
5056 if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
5057 vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
5058 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
5059 vty_out (vty, " warning-only");
5060 if (peer->pmax_restart[afi][safi])
5061 vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]);
5062 vty_out (vty, "%s", VTY_NEWLINE);
5063 }
5064
5065 /* Route server client. */
5066 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
5067 && ! peer->af_group[afi][safi])
5068 vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
5069
5070 /* Nexthop-local unchanged. */
5071 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
5072 && ! peer->af_group[afi][safi])
5073 vty_out (vty, " neighbor %s nexthop-local unchanged%s", addr, VTY_NEWLINE);
5074
5075 /* Allow AS in. */
5076 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
5077 if (! peer_group_active (peer)
5078 || ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
5079 || peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
5080 {
5081 if (peer->allowas_in[afi][safi] == 3)
5082 vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
5083 else
5084 vty_out (vty, " neighbor %s allowas-in %d%s", addr,
5085 peer->allowas_in[afi][safi], VTY_NEWLINE);
5086 }
5087
5088 /* Filter. */
5089 bgp_config_write_filter (vty, peer, afi, safi);
5090
5091 /* atribute-unchanged. */
5092 if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
5093 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
5094 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
5095 && ! peer->af_group[afi][safi])
5096 {
5097 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
5098 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
5099 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
5100 vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE);
5101 else
5102 vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr,
5103 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ?
5104 " as-path" : "",
5105 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ?
5106 " next-hop" : "",
5107 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
5108 " med" : "", VTY_NEWLINE);
5109 }
5110 }
5111
5112 /* Display "address-family" configuration header. */
5113 void
5114 bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
5115 int *write)
5116 {
5117 if (*write)
5118 return;
5119
5120 if (afi == AFI_IP && safi == SAFI_UNICAST)
5121 return;
5122
5123 vty_out (vty, "!%s address-family ", VTY_NEWLINE);
5124
5125 if (afi == AFI_IP)
5126 {
5127 if (safi == SAFI_MULTICAST)
5128 vty_out (vty, "ipv4 multicast");
5129 else if (safi == SAFI_MPLS_VPN)
5130 vty_out (vty, "vpnv4 unicast");
5131 }
5132 else if (afi == AFI_IP6)
5133 {
5134 vty_out (vty, "ipv6");
5135
5136 if (safi == SAFI_MULTICAST)
5137 vty_out (vty, " multicast");
5138 }
5139
5140 vty_out (vty, "%s", VTY_NEWLINE);
5141
5142 *write = 1;
5143 }
5144
5145 /* Address family based peer configuration display. */
5146 static int
5147 bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
5148 safi_t safi)
5149 {
5150 int write = 0;
5151 struct peer *peer;
5152 struct peer_group *group;
5153 struct listnode *node, *nnode;
5154
5155 bgp_config_write_network (vty, bgp, afi, safi, &write);
5156
5157 bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
5158
5159 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5160 {
5161 if (group->conf->afc[afi][safi])
5162 {
5163 bgp_config_write_family_header (vty, afi, safi, &write);
5164 bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
5165 }
5166 }
5167 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5168 {
5169 if (peer->afc[afi][safi])
5170 {
5171 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5172 {
5173 bgp_config_write_family_header (vty, afi, safi, &write);
5174 bgp_config_write_peer (vty, bgp, peer, afi, safi);
5175 }
5176 }
5177 }
5178
5179 bgp_config_write_maxpaths (vty, bgp, afi, safi, &write);
5180
5181 if (write)
5182 vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
5183
5184 return write;
5185 }
5186
5187 int
5188 bgp_config_write (struct vty *vty)
5189 {
5190 int write = 0;
5191 struct bgp *bgp;
5192 struct peer_group *group;
5193 struct peer *peer;
5194 struct listnode *node, *nnode;
5195 struct listnode *mnode, *mnnode;
5196
5197 /* BGP Multiple instance. */
5198 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
5199 {
5200 vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE);
5201 write++;
5202 }
5203
5204 /* BGP Config type. */
5205 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5206 {
5207 vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE);
5208 write++;
5209 }
5210
5211 /* BGP configuration. */
5212 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5213 {
5214 if (write)
5215 vty_out (vty, "!%s", VTY_NEWLINE);
5216
5217 /* Router bgp ASN */
5218 vty_out (vty, "router bgp %u", bgp->as);
5219
5220 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
5221 {
5222 if (bgp->name)
5223 vty_out (vty, " view %s", bgp->name);
5224 }
5225 vty_out (vty, "%s", VTY_NEWLINE);
5226
5227 /* No Synchronization */
5228 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5229 vty_out (vty, " no synchronization%s", VTY_NEWLINE);
5230
5231 /* BGP fast-external-failover. */
5232 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
5233 vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE);
5234
5235 /* BGP router ID. */
5236 if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID))
5237 vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id),
5238 VTY_NEWLINE);
5239
5240 /* BGP log-neighbor-changes. */
5241 if (bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
5242 vty_out (vty, " bgp log-neighbor-changes%s", VTY_NEWLINE);
5243
5244 /* BGP configuration. */
5245 if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
5246 vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
5247
5248 /* BGP default ipv4-unicast. */
5249 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
5250 vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE);
5251
5252 /* BGP default local-preference. */
5253 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
5254 vty_out (vty, " bgp default local-preference %d%s",
5255 bgp->default_local_pref, VTY_NEWLINE);
5256
5257 /* BGP client-to-client reflection. */
5258 if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
5259 vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE);
5260
5261 /* BGP cluster ID. */
5262 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID))
5263 vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id),
5264 VTY_NEWLINE);
5265
5266 /* Confederation identifier*/
5267 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
5268 vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
5269 VTY_NEWLINE);
5270
5271 /* Confederation peer */
5272 if (bgp->confed_peers_cnt > 0)
5273 {
5274 int i;
5275
5276 vty_out (vty, " bgp confederation peers");
5277
5278 for (i = 0; i < bgp->confed_peers_cnt; i++)
5279 vty_out(vty, " %u", bgp->confed_peers[i]);
5280
5281 vty_out (vty, "%s", VTY_NEWLINE);
5282 }
5283
5284 /* BGP enforce-first-as. */
5285 if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
5286 vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE);
5287
5288 /* BGP deterministic-med. */
5289 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
5290 vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
5291
5292 /* BGP graceful-restart. */
5293 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
5294 vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
5295 bgp->stalepath_time, VTY_NEWLINE);
5296 if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
5297 vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
5298
5299 /* BGP bestpath method. */
5300 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
5301 vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
5302 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
5303 vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
5304 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
5305 vty_out (vty, " bgp bestpath as-path multipath-relax%s", VTY_NEWLINE);
5306 }
5307 if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
5308 vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
5309 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
5310 || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5311 {
5312 vty_out (vty, " bgp bestpath med");
5313 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED))
5314 vty_out (vty, " confed");
5315 if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
5316 vty_out (vty, " missing-as-worst");
5317 vty_out (vty, "%s", VTY_NEWLINE);
5318 }
5319
5320 /* BGP network import check. */
5321 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
5322 vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
5323
5324 /* BGP scan interval. */
5325 bgp_config_write_scan_time (vty);
5326
5327 /* BGP flag dampening. */
5328 if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
5329 BGP_CONFIG_DAMPENING))
5330 bgp_config_write_damp (vty);
5331
5332 /* BGP static route configuration. */
5333 bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5334
5335 /* BGP redistribute configuration. */
5336 bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5337
5338 /* BGP timers configuration. */
5339 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
5340 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
5341 vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive,
5342 bgp->default_holdtime, VTY_NEWLINE);
5343
5344 /* peer-group */
5345 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
5346 {
5347 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
5348 }
5349
5350 /* Normal neighbor configuration. */
5351 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5352 {
5353 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
5354 bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
5355 }
5356
5357 /* maximum-paths */
5358 bgp_config_write_maxpaths (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
5359
5360 /* Distance configuration. */
5361 bgp_config_write_distance (vty, bgp);
5362
5363 /* No auto-summary */
5364 if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
5365 vty_out (vty, " no auto-summary%s", VTY_NEWLINE);
5366
5367 /* IPv4 multicast configuration. */
5368 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
5369
5370 /* IPv4 VPN configuration. */
5371 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
5372
5373 /* IPv6 unicast configuration. */
5374 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
5375
5376 /* IPv6 multicast configuration. */
5377 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
5378
5379 write++;
5380 }
5381 return write;
5382 }
5383
5384 void
5385 bgp_master_init (void)
5386 {
5387 memset (&bgp_master, 0, sizeof (struct bgp_master));
5388
5389 bm = &bgp_master;
5390 bm->bgp = list_new ();
5391 bm->listen_sockets = list_new ();
5392 bm->port = BGP_PORT_DEFAULT;
5393 bm->master = thread_master_create ();
5394 bm->start_time = bgp_clock ();
5395 }
5396
5397 \f
5398 void
5399 bgp_init (void)
5400 {
5401 /* BGP VTY commands installation. */
5402 bgp_vty_init ();
5403
5404 /* Init zebra. */
5405 bgp_zebra_init ();
5406
5407 /* BGP inits. */
5408 bgp_attr_init ();
5409 bgp_debug_init ();
5410 bgp_dump_init ();
5411 bgp_route_init ();
5412 bgp_route_map_init ();
5413 bgp_address_init ();
5414 bgp_scan_init ();
5415 bgp_mplsvpn_init ();
5416
5417 /* Access list initialize. */
5418 access_list_init ();
5419 access_list_add_hook (peer_distribute_update);
5420 access_list_delete_hook (peer_distribute_update);
5421
5422 /* Filter list initialize. */
5423 bgp_filter_init ();
5424 as_list_add_hook (peer_aslist_update);
5425 as_list_delete_hook (peer_aslist_update);
5426
5427 /* Prefix list initialize.*/
5428 prefix_list_init ();
5429 prefix_list_add_hook (peer_prefix_list_update);
5430 prefix_list_delete_hook (peer_prefix_list_update);
5431
5432 /* Community list initialize. */
5433 bgp_clist = community_list_init ();
5434
5435 #ifdef HAVE_SNMP
5436 bgp_snmp_init ();
5437 #endif /* HAVE_SNMP */
5438 }
5439
5440 void
5441 bgp_terminate (void)
5442 {
5443 struct bgp *bgp;
5444 struct peer *peer;
5445 struct listnode *node, *nnode;
5446 struct listnode *mnode, *mnnode;
5447
5448 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
5449 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
5450 if (peer->status == Established)
5451 bgp_notify_send (peer, BGP_NOTIFY_CEASE,
5452 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
5453
5454 bgp_cleanup_routes ();
5455
5456 if (bm->process_main_queue)
5457 {
5458 work_queue_free (bm->process_main_queue);
5459 bm->process_main_queue = NULL;
5460 }
5461 if (bm->process_rsclient_queue)
5462 {
5463 work_queue_free (bm->process_rsclient_queue);
5464 bm->process_rsclient_queue = NULL;
5465 }
5466 }