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