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