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