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