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