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