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