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