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