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