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