]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgpd.c
Merge pull request #1885 from msablic/pim_mtrace_client
[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->inst_type = inst_type;
2867 bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
2868 : VRF_UNKNOWN;
2869 bgp->peer_self = peer_new(bgp);
2870 if (bgp->peer_self->host)
2871 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->host);
2872 bgp->peer_self->host =
2873 XSTRDUP(MTYPE_BGP_PEER_HOST, "Static announcement");
2874 if (bgp->peer_self->hostname != NULL) {
2875 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->hostname);
2876 bgp->peer_self->hostname = NULL;
2877 }
2878 if (cmd_hostname_get())
2879 bgp->peer_self->hostname =
2880 XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_hostname_get());
2881
2882 if (bgp->peer_self->domainname != NULL) {
2883 XFREE(MTYPE_BGP_PEER_HOST, bgp->peer_self->domainname);
2884 bgp->peer_self->domainname = NULL;
2885 }
2886 if (cmd_domainname_get())
2887 bgp->peer_self->domainname =
2888 XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get());
2889 bgp->peer = list_new();
2890 bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
2891 bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same,
2892 "BGP Peer Hash");
2893 bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
2894
2895 bgp->group = list_new();
2896 bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
2897
2898 FOREACH_AFI_SAFI (afi, safi) {
2899 bgp->route[afi][safi] = bgp_table_init(afi, safi);
2900 bgp->aggregate[afi][safi] = bgp_table_init(afi, safi);
2901 bgp->rib[afi][safi] = bgp_table_init(afi, safi);
2902
2903 /* Enable maximum-paths */
2904 bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
2905 multipath_num, 0);
2906 bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
2907 multipath_num, 0);
2908 }
2909
2910 bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
2911 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
2912 bgp->default_subgroup_pkt_queue_max =
2913 BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX;
2914 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
2915 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
2916 bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
2917 bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
2918 bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
2919 bgp->dynamic_neighbors_count = 0;
2920 #if DFLT_BGP_IMPORT_CHECK
2921 bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
2922 #endif
2923 #if DFLT_BGP_SHOW_HOSTNAME
2924 bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
2925 #endif
2926 #if DFLT_BGP_LOG_NEIGHBOR_CHANGES
2927 bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
2928 #endif
2929 #if DFLT_BGP_DETERMINISTIC_MED
2930 bgp_flag_set(bgp, BGP_FLAG_DETERMINISTIC_MED);
2931 #endif
2932 bgp->addpath_tx_id = BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE;
2933
2934 bgp->as = *as;
2935
2936 #if ENABLE_BGP_VNC
2937 if (inst_type != BGP_INSTANCE_TYPE_VRF) {
2938 bgp->rfapi = bgp_rfapi_new(bgp);
2939 assert(bgp->rfapi);
2940 assert(bgp->rfapi_cfg);
2941 }
2942 #endif /* ENABLE_BGP_VNC */
2943
2944 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
2945 bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE;
2946 bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent =
2947 MPLS_LABEL_NONE;
2948 }
2949 if (name) {
2950 bgp->name = XSTRDUP(MTYPE_BGP, name);
2951 } else {
2952 /* TODO - The startup timer needs to be run for the whole of BGP
2953 */
2954 thread_add_timer(bm->master, bgp_startup_timer_expire, bgp,
2955 bgp->restart_time, &bgp->t_startup);
2956 }
2957
2958 atomic_store_explicit(&bgp->wpkt_quanta, BGP_WRITE_PACKET_MAX,
2959 memory_order_relaxed);
2960 atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
2961 memory_order_relaxed);
2962 bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
2963
2964 QOBJ_REG(bgp, bgp);
2965
2966 update_bgp_group_init(bgp);
2967 bgp_evpn_init(bgp);
2968 return bgp;
2969 }
2970
2971 /* Return the "default VRF" instance of BGP. */
2972 struct bgp *bgp_get_default(void)
2973 {
2974 struct bgp *bgp;
2975 struct listnode *node, *nnode;
2976
2977 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
2978 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
2979 return bgp;
2980 return NULL;
2981 }
2982
2983 /* Lookup BGP entry. */
2984 struct bgp *bgp_lookup(as_t as, const char *name)
2985 {
2986 struct bgp *bgp;
2987 struct listnode *node, *nnode;
2988
2989 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
2990 if (bgp->as == as
2991 && ((bgp->name == NULL && name == NULL)
2992 || (bgp->name && name && strcmp(bgp->name, name) == 0)))
2993 return bgp;
2994 return NULL;
2995 }
2996
2997 /* Lookup BGP structure by view name. */
2998 struct bgp *bgp_lookup_by_name(const char *name)
2999 {
3000 struct bgp *bgp;
3001 struct listnode *node, *nnode;
3002
3003 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
3004 if ((bgp->name == NULL && name == NULL)
3005 || (bgp->name && name && strcmp(bgp->name, name) == 0))
3006 return bgp;
3007 return NULL;
3008 }
3009
3010 /* Lookup BGP instance based on VRF id. */
3011 /* Note: Only to be used for incoming messages from Zebra. */
3012 struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
3013 {
3014 struct vrf *vrf;
3015
3016 /* Lookup VRF (in tree) and follow link. */
3017 vrf = vrf_lookup_by_id(vrf_id);
3018 if (!vrf)
3019 return NULL;
3020 return (vrf->info) ? (struct bgp *)vrf->info : NULL;
3021 }
3022
3023 /* handle socket creation or deletion, if necessary
3024 * this is called for all new BGP instances
3025 */
3026 int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
3027 bool create)
3028 {
3029 int ret = 0;
3030
3031 /* Create BGP server socket, if listen mode not disabled */
3032 if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN))
3033 return 0;
3034 if (bgp->name && bgp->inst_type == BGP_INSTANCE_TYPE_VRF && vrf) {
3035 /*
3036 * suppress vrf socket
3037 */
3038 if (create == FALSE) {
3039 if (vrf_is_mapped_on_netns(vrf->vrf_id))
3040 bgp_close_vrf_socket(bgp);
3041 else
3042 ret = bgp_check_main_socket(create, bgp);
3043 return ret;
3044 }
3045 /* do nothing
3046 * if vrf_id did not change
3047 */
3048 if (vrf->vrf_id == old_vrf_id)
3049 return 0;
3050 if (old_vrf_id != VRF_UNKNOWN) {
3051 /* look for old socket. close it. */
3052 bgp_close_vrf_socket(bgp);
3053 }
3054 /* if backend is not yet identified ( VRF_UNKNOWN) then
3055 * creation will be done later
3056 */
3057 if (vrf->vrf_id == VRF_UNKNOWN)
3058 return 0;
3059 /* if BGP VRF instance requested
3060 * if backend is NETNS, create BGP server socket in the NETNS
3061 */
3062 if (vrf_is_mapped_on_netns(bgp->vrf_id)) {
3063 ret = bgp_socket(bgp, bm->port, bm->address);
3064 if (ret < 0)
3065 return BGP_ERR_INVALID_VALUE;
3066 return 0;
3067 }
3068 }
3069 /* if BGP VRF instance requested or VRF lite backend
3070 * if BGP non VRF instance, create it
3071 * if not already done
3072 */
3073 return bgp_check_main_socket(create, bgp);
3074 }
3075
3076 /* Called from VTY commands. */
3077 int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
3078 enum bgp_instance_type inst_type)
3079 {
3080 struct bgp *bgp;
3081 struct vrf *vrf = NULL;
3082
3083 /* Multiple instance check. */
3084 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE)) {
3085 if (name)
3086 bgp = bgp_lookup_by_name(name);
3087 else
3088 bgp = bgp_get_default();
3089
3090 /* Already exists. */
3091 if (bgp) {
3092 if (bgp->as != *as) {
3093 *as = bgp->as;
3094 return BGP_ERR_INSTANCE_MISMATCH;
3095 }
3096 if (bgp->inst_type != inst_type)
3097 return BGP_ERR_INSTANCE_MISMATCH;
3098 *bgp_val = bgp;
3099 return 0;
3100 }
3101 } else {
3102 /* BGP instance name can not be specified for single instance.
3103 */
3104 if (name)
3105 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
3106
3107 /* Get default BGP structure if exists. */
3108 bgp = bgp_get_default();
3109
3110 if (bgp) {
3111 if (bgp->as != *as) {
3112 *as = bgp->as;
3113 return BGP_ERR_AS_MISMATCH;
3114 }
3115 *bgp_val = bgp;
3116 return 0;
3117 }
3118 }
3119
3120 bgp = bgp_create(as, name, inst_type);
3121 bgp_router_id_set(bgp, &bgp->router_id_zebra);
3122 bgp_address_init(bgp);
3123 bgp_tip_hash_init(bgp);
3124 bgp_scan_init(bgp);
3125 *bgp_val = bgp;
3126
3127 bgp->t_rmap_def_originate_eval = NULL;
3128
3129 /* If Default instance or VRF, link to the VRF structure, if present. */
3130 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
3131 || bgp->inst_type == BGP_INSTANCE_TYPE_VRF) {
3132 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3133 if (vrf)
3134 bgp_vrf_link(bgp, vrf);
3135 }
3136 /* BGP server socket already processed if BGP instance
3137 * already part of the list
3138 */
3139 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, true);
3140 listnode_add(bm->bgp, bgp);
3141
3142 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
3143 bgp_zebra_instance_register(bgp);
3144
3145
3146 return 0;
3147 }
3148
3149 /*
3150 * Make BGP instance "up". Applies only to VRFs (non-default) and
3151 * implies the VRF has been learnt from Zebra.
3152 */
3153 void bgp_instance_up(struct bgp *bgp)
3154 {
3155 struct peer *peer;
3156 struct listnode *node, *next;
3157
3158 /* Register with zebra. */
3159 bgp_zebra_instance_register(bgp);
3160
3161 /* Kick off any peers that may have been configured. */
3162 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3163 if (!BGP_PEER_START_SUPPRESSED(peer))
3164 BGP_EVENT_ADD(peer, BGP_Start);
3165 }
3166
3167 /* Process any networks that have been configured. */
3168 bgp_static_add(bgp);
3169 }
3170
3171 /*
3172 * Make BGP instance "down". Applies only to VRFs (non-default) and
3173 * implies the VRF has been deleted by Zebra.
3174 */
3175 void bgp_instance_down(struct bgp *bgp)
3176 {
3177 struct peer *peer;
3178 struct listnode *node;
3179 struct listnode *next;
3180
3181 /* Stop timers. */
3182 if (bgp->t_rmap_def_originate_eval) {
3183 BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
3184 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3185 why? */
3186 }
3187
3188 /* Bring down peers, so corresponding routes are purged. */
3189 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3190 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3191 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3192 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3193 else
3194 bgp_session_reset(peer);
3195 }
3196
3197 /* Purge network and redistributed routes. */
3198 bgp_purge_static_redist_routes(bgp);
3199
3200 /* Cleanup registered nexthops (flags) */
3201 bgp_cleanup_nexthops(bgp);
3202 }
3203
3204 /* Delete BGP instance. */
3205 int bgp_delete(struct bgp *bgp)
3206 {
3207 struct peer *peer;
3208 struct peer_group *group;
3209 struct listnode *node, *next;
3210 struct vrf *vrf;
3211 afi_t afi;
3212 int i;
3213
3214 THREAD_OFF(bgp->t_startup);
3215
3216 if (BGP_DEBUG(zebra, ZEBRA)) {
3217 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
3218 zlog_debug("Deleting Default VRF");
3219 else
3220 zlog_debug("Deleting %s %s",
3221 (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3222 ? "VRF"
3223 : "VIEW",
3224 bgp->name);
3225 }
3226
3227 /* unmap from RT list */
3228 bgp_evpn_vrf_delete(bgp);
3229
3230 /* Stop timers. */
3231 if (bgp->t_rmap_def_originate_eval) {
3232 BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
3233 bgp_unlock(bgp); /* TODO - This timer is started with a lock -
3234 why? */
3235 }
3236
3237 /* Inform peers we're going down. */
3238 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
3239 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
3240 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3241 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3242 }
3243
3244 /* Delete static routes (networks). */
3245 bgp_static_delete(bgp);
3246
3247 /* Unset redistribution. */
3248 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3249 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
3250 if (i != ZEBRA_ROUTE_BGP)
3251 bgp_redistribute_unset(bgp, afi, i, 0);
3252
3253 /* Free peers and peer-groups. */
3254 for (ALL_LIST_ELEMENTS(bgp->group, node, next, group))
3255 peer_group_delete(group);
3256
3257 for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
3258 peer_delete(peer);
3259
3260 if (bgp->peer_self) {
3261 peer_delete(bgp->peer_self);
3262 bgp->peer_self = NULL;
3263 }
3264
3265 update_bgp_group_free(bgp);
3266
3267 /* TODO - Other memory may need to be freed - e.g., NHT */
3268
3269 #if ENABLE_BGP_VNC
3270 rfapi_delete(bgp);
3271 #endif
3272 bgp_cleanup_routes(bgp);
3273
3274 /* Remove visibility via the master list - there may however still be
3275 * routes to be processed still referencing the struct bgp.
3276 */
3277 listnode_delete(bm->bgp, bgp);
3278
3279 /* Deregister from Zebra, if needed */
3280 if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
3281 bgp_zebra_instance_deregister(bgp);
3282
3283 /* Free interfaces in this instance. */
3284 bgp_if_finish(bgp);
3285
3286 vrf = bgp_vrf_lookup_by_instance_type(bgp);
3287 bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
3288 if (vrf)
3289 bgp_vrf_unlink(bgp, vrf);
3290
3291 thread_master_free_unused(bm->master);
3292 bgp_unlock(bgp); /* initial reference */
3293
3294 return 0;
3295 }
3296
3297 void bgp_free(struct bgp *bgp)
3298 {
3299 afi_t afi;
3300 safi_t safi;
3301 struct bgp_table *table;
3302 struct bgp_node *rn;
3303 struct bgp_rmap *rmap;
3304
3305 QOBJ_UNREG(bgp);
3306
3307 list_delete_and_null(&bgp->group);
3308 list_delete_and_null(&bgp->peer);
3309
3310 if (bgp->peerhash) {
3311 hash_free(bgp->peerhash);
3312 bgp->peerhash = NULL;
3313 }
3314
3315 FOREACH_AFI_SAFI (afi, safi) {
3316 /* Special handling for 2-level routing tables. */
3317 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
3318 || safi == SAFI_EVPN) {
3319 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
3320 rn = bgp_route_next(rn)) {
3321 table = (struct bgp_table *)rn->info;
3322 bgp_table_finish(&table);
3323 }
3324 }
3325 if (bgp->route[afi][safi])
3326 bgp_table_finish(&bgp->route[afi][safi]);
3327 if (bgp->aggregate[afi][safi])
3328 bgp_table_finish(&bgp->aggregate[afi][safi]);
3329 if (bgp->rib[afi][safi])
3330 bgp_table_finish(&bgp->rib[afi][safi]);
3331 rmap = &bgp->table_map[afi][safi];
3332 if (rmap->name)
3333 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
3334 }
3335
3336 bgp_scan_finish(bgp);
3337 bgp_address_destroy(bgp);
3338 bgp_tip_hash_destroy(bgp);
3339
3340 bgp_evpn_cleanup(bgp);
3341
3342 if (bgp->name)
3343 XFREE(MTYPE_BGP, bgp->name);
3344
3345 XFREE(MTYPE_BGP, bgp);
3346 }
3347
3348 struct peer *peer_lookup_by_conf_if(struct bgp *bgp, const char *conf_if)
3349 {
3350 struct peer *peer;
3351 struct listnode *node, *nnode;
3352
3353 if (!conf_if)
3354 return NULL;
3355
3356 if (bgp != NULL) {
3357 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3358 if (peer->conf_if && !strcmp(peer->conf_if, conf_if)
3359 && !CHECK_FLAG(peer->sflags,
3360 PEER_STATUS_ACCEPT_PEER))
3361 return peer;
3362 } else if (bm->bgp != NULL) {
3363 struct listnode *bgpnode, *nbgpnode;
3364
3365 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3366 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3367 if (peer->conf_if
3368 && !strcmp(peer->conf_if, conf_if)
3369 && !CHECK_FLAG(peer->sflags,
3370 PEER_STATUS_ACCEPT_PEER))
3371 return peer;
3372 }
3373 return NULL;
3374 }
3375
3376 struct peer *peer_lookup_by_hostname(struct bgp *bgp, const char *hostname)
3377 {
3378 struct peer *peer;
3379 struct listnode *node, *nnode;
3380
3381 if (!hostname)
3382 return NULL;
3383
3384 if (bgp != NULL) {
3385 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3386 if (peer->hostname && !strcmp(peer->hostname, hostname)
3387 && !CHECK_FLAG(peer->sflags,
3388 PEER_STATUS_ACCEPT_PEER))
3389 return peer;
3390 } else if (bm->bgp != NULL) {
3391 struct listnode *bgpnode, *nbgpnode;
3392
3393 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3394 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
3395 if (peer->hostname
3396 && !strcmp(peer->hostname, hostname)
3397 && !CHECK_FLAG(peer->sflags,
3398 PEER_STATUS_ACCEPT_PEER))
3399 return peer;
3400 }
3401 return NULL;
3402 }
3403
3404 struct peer *peer_lookup(struct bgp *bgp, union sockunion *su)
3405 {
3406 struct peer *peer = NULL;
3407 struct peer tmp_peer;
3408
3409 memset(&tmp_peer, 0, sizeof(struct peer));
3410
3411 /*
3412 * We do not want to find the doppelganger peer so search for the peer
3413 * in
3414 * the hash that has PEER_FLAG_CONFIG_NODE
3415 */
3416 SET_FLAG(tmp_peer.flags, PEER_FLAG_CONFIG_NODE);
3417
3418 tmp_peer.su = *su;
3419
3420 if (bgp != NULL) {
3421 peer = hash_lookup(bgp->peerhash, &tmp_peer);
3422 } else if (bm->bgp != NULL) {
3423 struct listnode *bgpnode, *nbgpnode;
3424
3425 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp)) {
3426 /* Skip VRFs Lite only, this function will not be
3427 * invoked without an instance
3428 * when examining VRFs.
3429 */
3430 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
3431 && !vrf_is_mapped_on_netns(bgp->vrf_id))
3432 continue;
3433
3434 peer = hash_lookup(bgp->peerhash, &tmp_peer);
3435
3436 if (peer)
3437 break;
3438 }
3439 }
3440
3441 return peer;
3442 }
3443
3444 struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
3445 union sockunion *su,
3446 struct peer_group *group)
3447 {
3448 struct peer *peer;
3449 afi_t afi;
3450 safi_t safi;
3451
3452 /* Create peer first; we've already checked group config is valid. */
3453 peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
3454 group->conf->as_type, 0, 0, group);
3455 if (!peer)
3456 return NULL;
3457
3458 /* Link to group */
3459 peer = peer_lock(peer);
3460 listnode_add(group->peer, peer);
3461
3462 peer_group2peer_config_copy(group, peer);
3463
3464 /*
3465 * Bind peer for all AFs configured for the group. We don't call
3466 * peer_group_bind as that is sub-optimal and does some stuff we don't
3467 * want.
3468 */
3469 FOREACH_AFI_SAFI (afi, safi) {
3470 if (!group->conf->afc[afi][safi])
3471 continue;
3472 peer->afc[afi][safi] = 1;
3473
3474 if (!peer_af_find(peer, afi, safi))
3475 peer_af_create(peer, afi, safi);
3476
3477 peer_group2peer_config_copy_af(group, peer, afi, safi);
3478 }
3479
3480 /* Mark as dynamic, but also as a "config node" for other things to
3481 * work. */
3482 SET_FLAG(peer->flags, PEER_FLAG_DYNAMIC_NEIGHBOR);
3483 SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
3484
3485 return peer;
3486 }
3487
3488 struct prefix *
3489 peer_group_lookup_dynamic_neighbor_range(struct peer_group *group,
3490 struct prefix *prefix)
3491 {
3492 struct listnode *node, *nnode;
3493 struct prefix *range;
3494 afi_t afi;
3495
3496 afi = family2afi(prefix->family);
3497
3498 if (group->listen_range[afi])
3499 for (ALL_LIST_ELEMENTS(group->listen_range[afi], node, nnode,
3500 range))
3501 if (prefix_match(range, prefix))
3502 return range;
3503
3504 return NULL;
3505 }
3506
3507 struct peer_group *
3508 peer_group_lookup_dynamic_neighbor(struct bgp *bgp, struct prefix *prefix,
3509 struct prefix **listen_range)
3510 {
3511 struct prefix *range = NULL;
3512 struct peer_group *group = NULL;
3513 struct listnode *node, *nnode;
3514
3515 *listen_range = NULL;
3516 if (bgp != NULL) {
3517 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
3518 if ((range = peer_group_lookup_dynamic_neighbor_range(
3519 group, prefix)))
3520 break;
3521 } else if (bm->bgp != NULL) {
3522 struct listnode *bgpnode, *nbgpnode;
3523
3524 for (ALL_LIST_ELEMENTS(bm->bgp, bgpnode, nbgpnode, bgp))
3525 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
3526 if ((range = peer_group_lookup_dynamic_neighbor_range(
3527 group, prefix)))
3528 goto found_range;
3529 }
3530
3531 found_range:
3532 *listen_range = range;
3533 return (group && range) ? group : NULL;
3534 }
3535
3536 struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
3537 {
3538 struct peer_group *group;
3539 struct bgp *gbgp;
3540 struct peer *peer;
3541 struct prefix prefix;
3542 struct prefix *listen_range;
3543 int dncount;
3544 char buf[PREFIX2STR_BUFFER];
3545 char buf1[PREFIX2STR_BUFFER];
3546
3547 sockunion2hostprefix(su, &prefix);
3548
3549 /* See if incoming connection matches a configured listen range. */
3550 group = peer_group_lookup_dynamic_neighbor(bgp, &prefix, &listen_range);
3551
3552 if (!group)
3553 return NULL;
3554
3555
3556 gbgp = group->bgp;
3557
3558 if (!gbgp)
3559 return NULL;
3560
3561 prefix2str(&prefix, buf, sizeof(buf));
3562 prefix2str(listen_range, buf1, sizeof(buf1));
3563
3564 if (bgp_debug_neighbor_events(NULL))
3565 zlog_debug(
3566 "Dynamic Neighbor %s matches group %s listen range %s",
3567 buf, group->name, buf1);
3568
3569 /* Are we within the listen limit? */
3570 dncount = gbgp->dynamic_neighbors_count;
3571
3572 if (dncount >= gbgp->dynamic_neighbors_limit) {
3573 if (bgp_debug_neighbor_events(NULL))
3574 zlog_debug("Dynamic Neighbor %s rejected - at limit %d",
3575 inet_sutop(su, buf),
3576 gbgp->dynamic_neighbors_limit);
3577 return NULL;
3578 }
3579
3580 /* Ensure group is not disabled. */
3581 if (CHECK_FLAG(group->conf->flags, PEER_FLAG_SHUTDOWN)) {
3582 if (bgp_debug_neighbor_events(NULL))
3583 zlog_debug(
3584 "Dynamic Neighbor %s rejected - group %s disabled",
3585 buf, group->name);
3586 return NULL;
3587 }
3588
3589 /* Check that at least one AF is activated for the group. */
3590 if (!peer_group_af_configured(group)) {
3591 if (bgp_debug_neighbor_events(NULL))
3592 zlog_debug(
3593 "Dynamic Neighbor %s rejected - no AF activated for group %s",
3594 buf, group->name);
3595 return NULL;
3596 }
3597
3598 /* Create dynamic peer and bind to associated group. */
3599 peer = peer_create_bind_dynamic_neighbor(gbgp, su, group);
3600 assert(peer);
3601
3602 gbgp->dynamic_neighbors_count = ++dncount;
3603
3604 if (bgp_debug_neighbor_events(peer))
3605 zlog_debug("%s Dynamic Neighbor added, group %s count %d",
3606 peer->host, group->name, dncount);
3607
3608 return peer;
3609 }
3610
3611 void peer_drop_dynamic_neighbor(struct peer *peer)
3612 {
3613 int dncount = -1;
3614 if (peer->group && peer->group->bgp) {
3615 dncount = peer->group->bgp->dynamic_neighbors_count;
3616 if (dncount)
3617 peer->group->bgp->dynamic_neighbors_count = --dncount;
3618 }
3619 if (bgp_debug_neighbor_events(peer))
3620 zlog_debug("%s dropped from group %s, count %d", peer->host,
3621 peer->group->name, dncount);
3622 }
3623
3624
3625 /* If peer is configured at least one address family return 1. */
3626 int peer_active(struct peer *peer)
3627 {
3628 if (BGP_PEER_SU_UNSPEC(peer))
3629 return 0;
3630 if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST]
3631 || peer->afc[AFI_IP][SAFI_LABELED_UNICAST]
3632 || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP]
3633 || peer->afc[AFI_IP6][SAFI_UNICAST]
3634 || peer->afc[AFI_IP6][SAFI_MULTICAST]
3635 || peer->afc[AFI_IP6][SAFI_LABELED_UNICAST]
3636 || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
3637 || peer->afc[AFI_IP6][SAFI_ENCAP]
3638 || peer->afc[AFI_L2VPN][SAFI_EVPN])
3639 return 1;
3640 return 0;
3641 }
3642
3643 /* If peer is negotiated at least one address family return 1. */
3644 int peer_active_nego(struct peer *peer)
3645 {
3646 if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
3647 || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
3648 || peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
3649 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
3650 || peer->afc_nego[AFI_IP][SAFI_ENCAP]
3651 || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
3652 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
3653 || peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
3654 || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
3655 || peer->afc_nego[AFI_IP6][SAFI_ENCAP]
3656 || peer->afc_nego[AFI_L2VPN][SAFI_EVPN])
3657 return 1;
3658 return 0;
3659 }
3660
3661 /* peer_flag_change_type. */
3662 enum peer_change_type {
3663 peer_change_none,
3664 peer_change_reset,
3665 peer_change_reset_in,
3666 peer_change_reset_out,
3667 };
3668
3669 static void peer_change_action(struct peer *peer, afi_t afi, safi_t safi,
3670 enum peer_change_type type)
3671 {
3672 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
3673 return;
3674
3675 if (peer->status != Established)
3676 return;
3677
3678 if (type == peer_change_reset) {
3679 /* If we're resetting session, we've to delete both peer struct
3680 */
3681 if ((peer->doppelganger)
3682 && (peer->doppelganger->status != Deleted)
3683 && (!CHECK_FLAG(peer->doppelganger->flags,
3684 PEER_FLAG_CONFIG_NODE)))
3685 peer_delete(peer->doppelganger);
3686
3687 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3688 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3689 } else if (type == peer_change_reset_in) {
3690 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
3691 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
3692 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0);
3693 else {
3694 if ((peer->doppelganger)
3695 && (peer->doppelganger->status != Deleted)
3696 && (!CHECK_FLAG(peer->doppelganger->flags,
3697 PEER_FLAG_CONFIG_NODE)))
3698 peer_delete(peer->doppelganger);
3699
3700 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3701 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3702 }
3703 } else if (type == peer_change_reset_out) {
3704 update_group_adjust_peer(peer_af_find(peer, afi, safi));
3705 bgp_announce_route(peer, afi, safi);
3706 }
3707 }
3708
3709 struct peer_flag_action {
3710 /* Peer's flag. */
3711 u_int32_t flag;
3712
3713 /* This flag can be set for peer-group member. */
3714 u_char not_for_member;
3715
3716 /* Action when the flag is changed. */
3717 enum peer_change_type type;
3718
3719 /* Peer down cause */
3720 u_char peer_down;
3721 };
3722
3723 static const struct peer_flag_action peer_flag_action_list[] = {
3724 {PEER_FLAG_PASSIVE, 0, peer_change_reset},
3725 {PEER_FLAG_SHUTDOWN, 0, peer_change_reset},
3726 {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none},
3727 {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none},
3728 {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none},
3729 {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset},
3730 {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset},
3731 {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset},
3732 {0, 0, 0}};
3733
3734 static const struct peer_flag_action peer_af_flag_action_list[] = {
3735 {PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out},
3736 {PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out},
3737 {PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out},
3738 {PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out},
3739 {PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset},
3740 {PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset},
3741 {PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in},
3742 {PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out},
3743 {PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out},
3744 {PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out},
3745 // PEER_FLAG_DEFAULT_ORIGINATE
3746 {PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out},
3747 {PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in},
3748 {PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in},
3749 {PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset},
3750 {PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset},
3751 // PEER_FLAG_MAX_PREFIX
3752 // PEER_FLAG_MAX_PREFIX_WARNING
3753 {PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out},
3754 {PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out},
3755 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out},
3756 {PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out},
3757 {PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out},
3758 {PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out},
3759 {PEER_FLAG_ADDPATH_TX_ALL_PATHS, 1, peer_change_reset},
3760 {PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS, 1, peer_change_reset},
3761 {PEER_FLAG_WEIGHT, 0, peer_change_reset_in},
3762 {0, 0, 0}};
3763
3764 /* Proper action set. */
3765 static int peer_flag_action_set(const struct peer_flag_action *action_list,
3766 int size, struct peer_flag_action *action,
3767 u_int32_t flag)
3768 {
3769 int i;
3770 int found = 0;
3771 int reset_in = 0;
3772 int reset_out = 0;
3773 const struct peer_flag_action *match = NULL;
3774
3775 /* Check peer's frag action. */
3776 for (i = 0; i < size; i++) {
3777 match = &action_list[i];
3778
3779 if (match->flag == 0)
3780 break;
3781
3782 if (match->flag & flag) {
3783 found = 1;
3784
3785 if (match->type == peer_change_reset_in)
3786 reset_in = 1;
3787 if (match->type == peer_change_reset_out)
3788 reset_out = 1;
3789 if (match->type == peer_change_reset) {
3790 reset_in = 1;
3791 reset_out = 1;
3792 }
3793 if (match->not_for_member)
3794 action->not_for_member = 1;
3795 }
3796 }
3797
3798 /* Set peer clear type. */
3799 if (reset_in && reset_out)
3800 action->type = peer_change_reset;
3801 else if (reset_in)
3802 action->type = peer_change_reset_in;
3803 else if (reset_out)
3804 action->type = peer_change_reset_out;
3805 else
3806 action->type = peer_change_none;
3807
3808 return found;
3809 }
3810
3811 static void peer_flag_modify_action(struct peer *peer, u_int32_t flag)
3812 {
3813 if (flag == PEER_FLAG_SHUTDOWN) {
3814 if (CHECK_FLAG(peer->flags, flag)) {
3815 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
3816 peer_nsf_stop(peer);
3817
3818 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3819 if (peer->t_pmax_restart) {
3820 BGP_TIMER_OFF(peer->t_pmax_restart);
3821 if (bgp_debug_neighbor_events(peer))
3822 zlog_debug(
3823 "%s Maximum-prefix restart timer canceled",
3824 peer->host);
3825 }
3826
3827 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
3828 peer_nsf_stop(peer);
3829
3830 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
3831 char *msg = peer->tx_shutdown_message;
3832 size_t msglen;
3833
3834 if (!msg && peer_group_active(peer))
3835 msg = peer->group->conf
3836 ->tx_shutdown_message;
3837 msglen = msg ? strlen(msg) : 0;
3838 if (msglen > 128)
3839 msglen = 128;
3840
3841 if (msglen) {
3842 u_char msgbuf[129];
3843
3844 msgbuf[0] = msglen;
3845 memcpy(msgbuf + 1, msg, msglen);
3846
3847 bgp_notify_send_with_data(
3848 peer, BGP_NOTIFY_CEASE,
3849 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
3850 msgbuf, msglen + 1);
3851 } else
3852 bgp_notify_send(
3853 peer, BGP_NOTIFY_CEASE,
3854 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
3855 } else
3856 bgp_session_reset(peer);
3857 } else {
3858 peer->v_start = BGP_INIT_START_TIMER;
3859 BGP_EVENT_ADD(peer, BGP_Stop);
3860 }
3861 } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
3862 if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
3863 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
3864 else if (flag == PEER_FLAG_PASSIVE)
3865 peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
3866 else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
3867 peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
3868
3869 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
3870 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3871 } else
3872 bgp_session_reset(peer);
3873 }
3874
3875 /* Change specified peer flag. */
3876 static int peer_flag_modify(struct peer *peer, u_int32_t flag, int set)
3877 {
3878 int found;
3879 int size;
3880 struct peer_group *group;
3881 struct peer *tmp_peer;
3882 struct listnode *node, *nnode;
3883 struct peer_flag_action action;
3884
3885 memset(&action, 0, sizeof(struct peer_flag_action));
3886 size = sizeof peer_flag_action_list / sizeof(struct peer_flag_action);
3887
3888 found = peer_flag_action_set(peer_flag_action_list, size, &action,
3889 flag);
3890
3891 /* No flag action is found. */
3892 if (!found)
3893 return BGP_ERR_INVALID_FLAG;
3894
3895 /* When unset the peer-group member's flag we have to check
3896 peer-group configuration. */
3897 if (!set && peer_group_active(peer))
3898 if (CHECK_FLAG(peer->group->conf->flags, flag)) {
3899 if (flag == PEER_FLAG_SHUTDOWN)
3900 return BGP_ERR_PEER_GROUP_SHUTDOWN;
3901 }
3902
3903 /* Flag conflict check. */
3904 if (set && CHECK_FLAG(peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
3905 && CHECK_FLAG(peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
3906 return BGP_ERR_PEER_FLAG_CONFLICT;
3907
3908 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
3909 if (set && CHECK_FLAG(peer->flags, flag) == flag)
3910 return 0;
3911 if (!set && !CHECK_FLAG(peer->flags, flag))
3912 return 0;
3913 }
3914
3915 if (set)
3916 SET_FLAG(peer->flags, flag);
3917 else
3918 UNSET_FLAG(peer->flags, flag);
3919
3920 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
3921 if (action.type == peer_change_reset)
3922 peer_flag_modify_action(peer, flag);
3923
3924 return 0;
3925 }
3926
3927 /* peer-group member updates. */
3928 group = peer->group;
3929
3930 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
3931
3932 if (set && CHECK_FLAG(tmp_peer->flags, flag) == flag)
3933 continue;
3934
3935 if (!set && !CHECK_FLAG(tmp_peer->flags, flag))
3936 continue;
3937
3938 if (set)
3939 SET_FLAG(tmp_peer->flags, flag);
3940 else
3941 UNSET_FLAG(tmp_peer->flags, flag);
3942
3943 if (action.type == peer_change_reset)
3944 peer_flag_modify_action(tmp_peer, flag);
3945 }
3946 return 0;
3947 }
3948
3949 int peer_flag_set(struct peer *peer, u_int32_t flag)
3950 {
3951 return peer_flag_modify(peer, flag, 1);
3952 }
3953
3954 int peer_flag_unset(struct peer *peer, u_int32_t flag)
3955 {
3956 return peer_flag_modify(peer, flag, 0);
3957 }
3958
3959 static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
3960 u_int32_t flag, int set)
3961 {
3962 int found;
3963 int size;
3964 struct listnode *node, *nnode;
3965 struct peer_group *group;
3966 struct peer_flag_action action;
3967 struct peer *tmp_peer;
3968 struct bgp *bgp;
3969 int addpath_tx_used;
3970
3971 memset(&action, 0, sizeof(struct peer_flag_action));
3972 size = sizeof peer_af_flag_action_list
3973 / sizeof(struct peer_flag_action);
3974
3975 found = peer_flag_action_set(peer_af_flag_action_list, size, &action,
3976 flag);
3977
3978 /* No flag action is found. */
3979 if (!found)
3980 return BGP_ERR_INVALID_FLAG;
3981
3982 /* Special check for reflector client. */
3983 if (flag & PEER_FLAG_REFLECTOR_CLIENT
3984 && peer_sort(peer) != BGP_PEER_IBGP)
3985 return BGP_ERR_NOT_INTERNAL_PEER;
3986
3987 /* Special check for remove-private-AS. */
3988 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
3989 && peer_sort(peer) == BGP_PEER_IBGP)
3990 return BGP_ERR_REMOVE_PRIVATE_AS;
3991
3992 /* as-override is not allowed for IBGP peers */
3993 if (flag & PEER_FLAG_AS_OVERRIDE && peer_sort(peer) == BGP_PEER_IBGP)
3994 return BGP_ERR_AS_OVERRIDE;
3995
3996 /* When current flag configuration is same as requested one. */
3997 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
3998 if (set && CHECK_FLAG(peer->af_flags[afi][safi], flag) == flag)
3999 return 0;
4000 if (!set && !CHECK_FLAG(peer->af_flags[afi][safi], flag))
4001 return 0;
4002 }
4003
4004 if (set)
4005 SET_FLAG(peer->af_flags[afi][safi], flag);
4006 else
4007 UNSET_FLAG(peer->af_flags[afi][safi], flag);
4008
4009 /* Execute action when peer is established. */
4010 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4011 && peer->status == Established) {
4012 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4013 bgp_clear_adj_in(peer, afi, safi);
4014 else {
4015 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4016 peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
4017 else if (flag == PEER_FLAG_RSERVER_CLIENT)
4018 peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
4019 else if (flag == PEER_FLAG_ORF_PREFIX_SM)
4020 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4021 else if (flag == PEER_FLAG_ORF_PREFIX_RM)
4022 peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
4023
4024 peer_change_action(peer, afi, safi, action.type);
4025 }
4026 }
4027
4028 /* Peer group member updates. */
4029 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4030 group = peer->group;
4031
4032 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
4033 if (set
4034 && CHECK_FLAG(tmp_peer->af_flags[afi][safi], flag)
4035 == flag)
4036 continue;
4037
4038 if (!set
4039 && !CHECK_FLAG(tmp_peer->af_flags[afi][safi], flag))
4040 continue;
4041
4042 if (set)
4043 SET_FLAG(tmp_peer->af_flags[afi][safi], flag);
4044 else
4045 UNSET_FLAG(tmp_peer->af_flags[afi][safi], flag);
4046
4047 if (tmp_peer->status == Established) {
4048 if (!set && flag == PEER_FLAG_SOFT_RECONFIG)
4049 bgp_clear_adj_in(tmp_peer, afi, safi);
4050 else {
4051 if (flag == PEER_FLAG_REFLECTOR_CLIENT)
4052 tmp_peer->last_reset =
4053 PEER_DOWN_RR_CLIENT_CHANGE;
4054 else if (flag
4055 == PEER_FLAG_RSERVER_CLIENT)
4056 tmp_peer->last_reset =
4057 PEER_DOWN_RS_CLIENT_CHANGE;
4058 else if (flag
4059 == PEER_FLAG_ORF_PREFIX_SM)
4060 tmp_peer->last_reset =
4061 PEER_DOWN_CAPABILITY_CHANGE;
4062 else if (flag
4063 == PEER_FLAG_ORF_PREFIX_RM)
4064 tmp_peer->last_reset =
4065 PEER_DOWN_CAPABILITY_CHANGE;
4066
4067 peer_change_action(tmp_peer, afi, safi,
4068 action.type);
4069 }
4070 }
4071 }
4072 }
4073
4074 /* Track if addpath TX is in use */
4075 if (flag & (PEER_FLAG_ADDPATH_TX_ALL_PATHS
4076 | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
4077 bgp = peer->bgp;
4078 addpath_tx_used = 0;
4079
4080 if (set) {
4081 addpath_tx_used = 1;
4082
4083 if (flag & PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS) {
4084 if (!bgp_flag_check(
4085 bgp, BGP_FLAG_DETERMINISTIC_MED)) {
4086 zlog_warn(
4087 "%s: enabling bgp deterministic-med, this is required"
4088 " for addpath-tx-bestpath-per-AS",
4089 peer->host);
4090 bgp_flag_set(
4091 bgp,
4092 BGP_FLAG_DETERMINISTIC_MED);
4093 bgp_recalculate_all_bestpaths(bgp);
4094 }
4095 }
4096 } else {
4097 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode,
4098 tmp_peer)) {
4099 if (CHECK_FLAG(tmp_peer->af_flags[afi][safi],
4100 PEER_FLAG_ADDPATH_TX_ALL_PATHS)
4101 || CHECK_FLAG(
4102 tmp_peer->af_flags[afi][safi],
4103 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
4104 addpath_tx_used = 1;
4105 break;
4106 }
4107 }
4108 }
4109
4110 bgp->addpath_tx_used[afi][safi] = addpath_tx_used;
4111 }
4112
4113 return 0;
4114 }
4115
4116 int peer_af_flag_set(struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
4117 {
4118 return peer_af_flag_modify(peer, afi, safi, flag, 1);
4119 }
4120
4121 int peer_af_flag_unset(struct peer *peer, afi_t afi, safi_t safi,
4122 u_int32_t flag)
4123 {
4124 return peer_af_flag_modify(peer, afi, safi, flag, 0);
4125 }
4126
4127
4128 int peer_tx_shutdown_message_set(struct peer *peer, const char *msg)
4129 {
4130 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4131 peer->tx_shutdown_message =
4132 msg ? XSTRDUP(MTYPE_PEER_TX_SHUTDOWN_MSG, msg) : NULL;
4133 return 0;
4134 }
4135
4136 int peer_tx_shutdown_message_unset(struct peer *peer)
4137 {
4138 XFREE(MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
4139 return 0;
4140 }
4141
4142
4143 /* EBGP multihop configuration. */
4144 int peer_ebgp_multihop_set(struct peer *peer, int ttl)
4145 {
4146 struct peer_group *group;
4147 struct listnode *node, *nnode;
4148 struct peer *peer1;
4149
4150 if (peer->sort == BGP_PEER_IBGP || peer->conf_if)
4151 return 0;
4152
4153 /* see comment in peer_ttl_security_hops_set() */
4154 if (ttl != MAXTTL) {
4155 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4156 group = peer->group;
4157 if (group->conf->gtsm_hops != 0)
4158 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4159
4160 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
4161 peer1)) {
4162 if (peer1->sort == BGP_PEER_IBGP)
4163 continue;
4164
4165 if (peer1->gtsm_hops != 0)
4166 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4167 }
4168 } else {
4169 if (peer->gtsm_hops != 0)
4170 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4171 }
4172 }
4173
4174 peer->ttl = ttl;
4175
4176 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4177 if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP) {
4178 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4179 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4180 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4181 else
4182 bgp_session_reset(peer);
4183 }
4184 } else {
4185 group = peer->group;
4186 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4187 if (peer->sort == BGP_PEER_IBGP)
4188 continue;
4189
4190 peer->ttl = group->conf->ttl;
4191
4192 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4193 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4194 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4195 else
4196 bgp_session_reset(peer);
4197 }
4198 }
4199 return 0;
4200 }
4201
4202 int peer_ebgp_multihop_unset(struct peer *peer)
4203 {
4204 struct peer_group *group;
4205 struct listnode *node, *nnode;
4206
4207 if (peer->sort == BGP_PEER_IBGP)
4208 return 0;
4209
4210 if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
4211 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
4212
4213 if (peer_group_active(peer))
4214 peer->ttl = peer->group->conf->ttl;
4215 else
4216 peer->ttl = 1;
4217
4218 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4219 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4220 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4221 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4222 else
4223 bgp_session_reset(peer);
4224 } else {
4225 group = peer->group;
4226 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4227 if (peer->sort == BGP_PEER_IBGP)
4228 continue;
4229
4230 peer->ttl = 1;
4231
4232 if (peer->fd >= 0) {
4233 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
4234 bgp_notify_send(
4235 peer, BGP_NOTIFY_CEASE,
4236 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4237 else
4238 bgp_session_reset(peer);
4239 }
4240 }
4241 }
4242 return 0;
4243 }
4244
4245 /* Neighbor description. */
4246 int peer_description_set(struct peer *peer, const char *desc)
4247 {
4248 if (peer->desc)
4249 XFREE(MTYPE_PEER_DESC, peer->desc);
4250
4251 peer->desc = XSTRDUP(MTYPE_PEER_DESC, desc);
4252
4253 return 0;
4254 }
4255
4256 int peer_description_unset(struct peer *peer)
4257 {
4258 if (peer->desc)
4259 XFREE(MTYPE_PEER_DESC, peer->desc);
4260
4261 peer->desc = NULL;
4262
4263 return 0;
4264 }
4265
4266 /* Neighbor update-source. */
4267 int peer_update_source_if_set(struct peer *peer, const char *ifname)
4268 {
4269 struct peer_group *group;
4270 struct listnode *node, *nnode;
4271
4272 if (peer->update_if) {
4273 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4274 && strcmp(peer->update_if, ifname) == 0)
4275 return 0;
4276
4277 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4278 peer->update_if = NULL;
4279 }
4280
4281 if (peer->update_source) {
4282 sockunion_free(peer->update_source);
4283 peer->update_source = NULL;
4284 }
4285
4286 peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
4287
4288 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4289 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4290 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4291 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4292 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4293 } else
4294 bgp_session_reset(peer);
4295 return 0;
4296 }
4297
4298 /* peer-group member updates. */
4299 group = peer->group;
4300 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4301 if (peer->update_if) {
4302 if (strcmp(peer->update_if, ifname) == 0)
4303 continue;
4304
4305 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4306 peer->update_if = NULL;
4307 }
4308
4309 if (peer->update_source) {
4310 sockunion_free(peer->update_source);
4311 peer->update_source = NULL;
4312 }
4313
4314 peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname);
4315
4316 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4317 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4318 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4319 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4320 } else
4321 bgp_session_reset(peer);
4322 }
4323 return 0;
4324 }
4325
4326 int peer_update_source_addr_set(struct peer *peer, const union sockunion *su)
4327 {
4328 struct peer_group *group;
4329 struct listnode *node, *nnode;
4330
4331 if (peer->update_source) {
4332 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
4333 && sockunion_cmp(peer->update_source, su) == 0)
4334 return 0;
4335 sockunion_free(peer->update_source);
4336 peer->update_source = NULL;
4337 }
4338
4339 if (peer->update_if) {
4340 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4341 peer->update_if = NULL;
4342 }
4343
4344 peer->update_source = sockunion_dup(su);
4345
4346 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4347 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4348 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4349 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4350 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4351 } else
4352 bgp_session_reset(peer);
4353 return 0;
4354 }
4355
4356 /* peer-group member updates. */
4357 group = peer->group;
4358 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4359 if (peer->update_source) {
4360 if (sockunion_cmp(peer->update_source, su) == 0)
4361 continue;
4362 sockunion_free(peer->update_source);
4363 peer->update_source = NULL;
4364 }
4365
4366 if (peer->update_if) {
4367 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4368 peer->update_if = NULL;
4369 }
4370
4371 peer->update_source = sockunion_dup(su);
4372
4373 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4374 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4375 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4376 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4377 } else
4378 bgp_session_reset(peer);
4379 }
4380 return 0;
4381 }
4382
4383 int peer_update_source_unset(struct peer *peer)
4384 {
4385 union sockunion *su;
4386 struct peer_group *group;
4387 struct listnode *node, *nnode;
4388
4389 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP) && !peer->update_source
4390 && !peer->update_if)
4391 return 0;
4392
4393 if (peer->update_source) {
4394 sockunion_free(peer->update_source);
4395 peer->update_source = NULL;
4396 }
4397 if (peer->update_if) {
4398 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4399 peer->update_if = NULL;
4400 }
4401
4402 if (peer_group_active(peer)) {
4403 group = peer->group;
4404
4405 if (group->conf->update_source) {
4406 su = sockunion_dup(group->conf->update_source);
4407 peer->update_source = su;
4408 } else if (group->conf->update_if)
4409 peer->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE,
4410 group->conf->update_if);
4411 }
4412
4413 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4414 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4415 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4416 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4417 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4418 } else
4419 bgp_session_reset(peer);
4420 return 0;
4421 }
4422
4423 /* peer-group member updates. */
4424 group = peer->group;
4425 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4426 if (!peer->update_source && !peer->update_if)
4427 continue;
4428
4429 if (peer->update_source) {
4430 sockunion_free(peer->update_source);
4431 peer->update_source = NULL;
4432 }
4433
4434 if (peer->update_if) {
4435 XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
4436 peer->update_if = NULL;
4437 }
4438
4439 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
4440 peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
4441 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
4442 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
4443 } else
4444 bgp_session_reset(peer);
4445 }
4446 return 0;
4447 }
4448
4449 int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi,
4450 const char *rmap)
4451 {
4452 struct peer_group *group;
4453 struct listnode *node, *nnode;
4454
4455 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
4456 || (rmap && !peer->default_rmap[afi][safi].name)
4457 || (rmap
4458 && strcmp(rmap, peer->default_rmap[afi][safi].name) != 0)) {
4459 SET_FLAG(peer->af_flags[afi][safi],
4460 PEER_FLAG_DEFAULT_ORIGINATE);
4461
4462 if (rmap) {
4463 if (peer->default_rmap[afi][safi].name)
4464 XFREE(MTYPE_ROUTE_MAP_NAME,
4465 peer->default_rmap[afi][safi].name);
4466 peer->default_rmap[afi][safi].name =
4467 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4468 peer->default_rmap[afi][safi].map =
4469 route_map_lookup_by_name(rmap);
4470 }
4471 }
4472
4473 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4474 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4475 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4476 bgp_default_originate(peer, afi, safi, 0);
4477 bgp_announce_route(peer, afi, safi);
4478 }
4479 return 0;
4480 }
4481
4482 /* peer-group member updates. */
4483 group = peer->group;
4484 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4485 SET_FLAG(peer->af_flags[afi][safi],
4486 PEER_FLAG_DEFAULT_ORIGINATE);
4487
4488 if (rmap) {
4489 if (peer->default_rmap[afi][safi].name)
4490 XFREE(MTYPE_ROUTE_MAP_NAME,
4491 peer->default_rmap[afi][safi].name);
4492 peer->default_rmap[afi][safi].name =
4493 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4494 peer->default_rmap[afi][safi].map =
4495 route_map_lookup_by_name(rmap);
4496 }
4497
4498 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4499 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4500 bgp_default_originate(peer, afi, safi, 0);
4501 bgp_announce_route(peer, afi, safi);
4502 }
4503 }
4504 return 0;
4505 }
4506
4507 int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi)
4508 {
4509 struct peer_group *group;
4510 struct listnode *node, *nnode;
4511
4512 if (CHECK_FLAG(peer->af_flags[afi][safi],
4513 PEER_FLAG_DEFAULT_ORIGINATE)) {
4514 UNSET_FLAG(peer->af_flags[afi][safi],
4515 PEER_FLAG_DEFAULT_ORIGINATE);
4516
4517 if (peer->default_rmap[afi][safi].name)
4518 XFREE(MTYPE_ROUTE_MAP_NAME,
4519 peer->default_rmap[afi][safi].name);
4520 peer->default_rmap[afi][safi].name = NULL;
4521 peer->default_rmap[afi][safi].map = NULL;
4522 }
4523
4524 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4525 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4526 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4527 bgp_default_originate(peer, afi, safi, 1);
4528 bgp_announce_route(peer, afi, safi);
4529 }
4530 return 0;
4531 }
4532
4533 /* peer-group member updates. */
4534 group = peer->group;
4535 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4536 UNSET_FLAG(peer->af_flags[afi][safi],
4537 PEER_FLAG_DEFAULT_ORIGINATE);
4538
4539 if (peer->default_rmap[afi][safi].name)
4540 XFREE(MTYPE_ROUTE_MAP_NAME,
4541 peer->default_rmap[afi][safi].name);
4542 peer->default_rmap[afi][safi].name = NULL;
4543 peer->default_rmap[afi][safi].map = NULL;
4544
4545 if (peer->status == Established && peer->afc_nego[afi][safi]) {
4546 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4547 bgp_default_originate(peer, afi, safi, 1);
4548 bgp_announce_route(peer, afi, safi);
4549 }
4550 }
4551 return 0;
4552 }
4553
4554 int peer_port_set(struct peer *peer, u_int16_t port)
4555 {
4556 peer->port = port;
4557 return 0;
4558 }
4559
4560 int peer_port_unset(struct peer *peer)
4561 {
4562 peer->port = BGP_PORT_DEFAULT;
4563 return 0;
4564 }
4565
4566 /*
4567 * Helper function that is called after the name of the policy
4568 * being used by a peer has changed (AF specific). Automatically
4569 * initiates inbound or outbound processing as needed.
4570 */
4571 static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
4572 int outbound)
4573 {
4574 if (outbound) {
4575 update_group_adjust_peer(peer_af_find(peer, afi, safi));
4576 if (peer->status == Established)
4577 bgp_announce_route(peer, afi, safi);
4578 } else {
4579 if (peer->status != Established)
4580 return;
4581
4582 if (CHECK_FLAG(peer->af_flags[afi][safi],
4583 PEER_FLAG_SOFT_RECONFIG))
4584 bgp_soft_reconfig_in(peer, afi, safi);
4585 else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
4586 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
4587 bgp_route_refresh_send(peer, afi, safi, 0, 0, 0);
4588 }
4589 }
4590
4591
4592 /* neighbor weight. */
4593 int peer_weight_set(struct peer *peer, afi_t afi, safi_t safi, u_int16_t weight)
4594 {
4595 struct peer_group *group;
4596 struct listnode *node, *nnode;
4597
4598 if (peer->weight[afi][safi] != weight) {
4599 peer->weight[afi][safi] = weight;
4600 SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT);
4601 peer_on_policy_change(peer, afi, safi, 0);
4602 }
4603
4604 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4605 return 0;
4606
4607 /* peer-group member updates. */
4608 group = peer->group;
4609 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4610 if (peer->weight[afi][safi] != weight) {
4611 peer->weight[afi][safi] = weight;
4612 SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT);
4613 peer_on_policy_change(peer, afi, safi, 0);
4614 }
4615 }
4616 return 0;
4617 }
4618
4619 int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi)
4620 {
4621 struct peer_group *group;
4622 struct listnode *node, *nnode;
4623
4624 /* not the peer-group itself but a peer in a peer-group */
4625 if (peer_group_active(peer)) {
4626 group = peer->group;
4627
4628 /* inherit weight from the peer-group */
4629 if (CHECK_FLAG(group->conf->af_flags[afi][safi],
4630 PEER_FLAG_WEIGHT)) {
4631 peer->weight[afi][safi] =
4632 group->conf->weight[afi][safi];
4633 peer_af_flag_set(peer, afi, safi, PEER_FLAG_WEIGHT);
4634 peer_on_policy_change(peer, afi, safi, 0);
4635 } else {
4636 if (CHECK_FLAG(peer->af_flags[afi][safi],
4637 PEER_FLAG_WEIGHT)) {
4638 peer->weight[afi][safi] = 0;
4639 peer_af_flag_unset(peer, afi, safi,
4640 PEER_FLAG_WEIGHT);
4641 peer_on_policy_change(peer, afi, safi, 0);
4642 }
4643 }
4644 }
4645
4646 else {
4647 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_WEIGHT)) {
4648 peer->weight[afi][safi] = 0;
4649 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_WEIGHT);
4650 peer_on_policy_change(peer, afi, safi, 0);
4651 }
4652
4653 /* peer-group member updates. */
4654 group = peer->group;
4655
4656 if (group) {
4657 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
4658 peer)) {
4659 if (CHECK_FLAG(peer->af_flags[afi][safi],
4660 PEER_FLAG_WEIGHT)) {
4661 peer->weight[afi][safi] = 0;
4662 peer_af_flag_unset(peer, afi, safi,
4663 PEER_FLAG_WEIGHT);
4664 peer_on_policy_change(peer, afi, safi,
4665 0);
4666 }
4667 }
4668 }
4669 }
4670 return 0;
4671 }
4672
4673 int peer_timers_set(struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
4674 {
4675 struct peer_group *group;
4676 struct listnode *node, *nnode;
4677
4678 /* keepalive value check. */
4679 if (keepalive > 65535)
4680 return BGP_ERR_INVALID_VALUE;
4681
4682 /* Holdtime value check. */
4683 if (holdtime > 65535)
4684 return BGP_ERR_INVALID_VALUE;
4685
4686 /* Holdtime value must be either 0 or greater than 3. */
4687 if (holdtime < 3 && holdtime != 0)
4688 return BGP_ERR_INVALID_VALUE;
4689
4690 /* Set value to the configuration. */
4691 peer->holdtime = holdtime;
4692 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
4693
4694 /* First work on real peers with timers */
4695 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4696 SET_FLAG(peer->config, PEER_CONFIG_TIMER);
4697 UNSET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
4698 } else {
4699 /* Now work on the peer-group timers */
4700 SET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
4701
4702 /* peer-group member updates. */
4703 group = peer->group;
4704 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4705 /* Skip peers that have their own timers */
4706 if (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER))
4707 continue;
4708
4709 SET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
4710 peer->holdtime = group->conf->holdtime;
4711 peer->keepalive = group->conf->keepalive;
4712 }
4713 }
4714
4715 return 0;
4716 }
4717
4718 int peer_timers_unset(struct peer *peer)
4719 {
4720 struct peer_group *group;
4721 struct listnode *node, *nnode;
4722
4723 /* First work on real peers vs the peer-group */
4724 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4725 UNSET_FLAG(peer->config, PEER_CONFIG_TIMER);
4726 peer->keepalive = 0;
4727 peer->holdtime = 0;
4728
4729 if (peer->group && peer->group->conf->holdtime) {
4730 SET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
4731 peer->keepalive = peer->group->conf->keepalive;
4732 peer->holdtime = peer->group->conf->holdtime;
4733 }
4734 } else {
4735 /* peer-group member updates. */
4736 group = peer->group;
4737 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4738 if (!CHECK_FLAG(peer->config, PEER_CONFIG_TIMER)) {
4739 UNSET_FLAG(peer->config,
4740 PEER_GROUP_CONFIG_TIMER);
4741 peer->holdtime = 0;
4742 peer->keepalive = 0;
4743 }
4744 }
4745
4746 UNSET_FLAG(group->conf->config, PEER_GROUP_CONFIG_TIMER);
4747 group->conf->holdtime = 0;
4748 group->conf->keepalive = 0;
4749 }
4750
4751 return 0;
4752 }
4753
4754 int peer_timers_connect_set(struct peer *peer, u_int32_t connect)
4755 {
4756 struct peer_group *group;
4757 struct listnode *node, *nnode;
4758
4759 if (connect > 65535)
4760 return BGP_ERR_INVALID_VALUE;
4761
4762 /* Set value to the configuration. */
4763 SET_FLAG(peer->config, PEER_CONFIG_CONNECT);
4764 peer->connect = connect;
4765
4766 /* Set value to timer setting. */
4767 peer->v_connect = connect;
4768
4769 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4770 return 0;
4771
4772 /* peer-group member updates. */
4773 group = peer->group;
4774 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4775 SET_FLAG(peer->config, PEER_CONFIG_CONNECT);
4776 peer->connect = connect;
4777 peer->v_connect = connect;
4778 }
4779 return 0;
4780 }
4781
4782 int peer_timers_connect_unset(struct peer *peer)
4783 {
4784 struct peer_group *group;
4785 struct listnode *node, *nnode;
4786
4787 /* Clear configuration. */
4788 UNSET_FLAG(peer->config, PEER_CONFIG_CONNECT);
4789 peer->connect = 0;
4790
4791 /* Set timer setting to default value. */
4792 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
4793
4794 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4795 return 0;
4796
4797 /* peer-group member updates. */
4798 group = peer->group;
4799 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4800 UNSET_FLAG(peer->config, PEER_CONFIG_CONNECT);
4801 peer->connect = 0;
4802 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
4803 }
4804 return 0;
4805 }
4806
4807 int peer_advertise_interval_set(struct peer *peer, u_int32_t routeadv)
4808 {
4809 struct peer_group *group;
4810 struct listnode *node, *nnode;
4811
4812 if (routeadv > 600)
4813 return BGP_ERR_INVALID_VALUE;
4814
4815 SET_FLAG(peer->config, PEER_CONFIG_ROUTEADV);
4816 peer->routeadv = routeadv;
4817 peer->v_routeadv = routeadv;
4818
4819 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4820 update_group_adjust_peer_afs(peer);
4821 if (peer->status == Established)
4822 bgp_announce_route_all(peer);
4823 return 0;
4824 }
4825
4826 /* peer-group member updates. */
4827 group = peer->group;
4828 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4829 SET_FLAG(peer->config, PEER_CONFIG_ROUTEADV);
4830 peer->routeadv = routeadv;
4831 peer->v_routeadv = routeadv;
4832 update_group_adjust_peer_afs(peer);
4833 if (peer->status == Established)
4834 bgp_announce_route_all(peer);
4835 }
4836
4837 return 0;
4838 }
4839
4840 int peer_advertise_interval_unset(struct peer *peer)
4841 {
4842 struct peer_group *group;
4843 struct listnode *node, *nnode;
4844
4845 UNSET_FLAG(peer->config, PEER_CONFIG_ROUTEADV);
4846 peer->routeadv = 0;
4847
4848 if (peer->sort == BGP_PEER_IBGP)
4849 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
4850 else
4851 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
4852
4853 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4854 update_group_adjust_peer_afs(peer);
4855 if (peer->status == Established)
4856 bgp_announce_route_all(peer);
4857 return 0;
4858 }
4859
4860 /* peer-group member updates. */
4861 group = peer->group;
4862 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4863 UNSET_FLAG(peer->config, PEER_CONFIG_ROUTEADV);
4864 peer->routeadv = 0;
4865
4866 if (peer->sort == BGP_PEER_IBGP)
4867 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
4868 else
4869 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
4870
4871 update_group_adjust_peer_afs(peer);
4872 if (peer->status == Established)
4873 bgp_announce_route_all(peer);
4874 }
4875
4876 return 0;
4877 }
4878
4879 /* neighbor interface */
4880 void peer_interface_set(struct peer *peer, const char *str)
4881 {
4882 if (peer->ifname)
4883 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
4884 peer->ifname = XSTRDUP(MTYPE_BGP_PEER_IFNAME, str);
4885 }
4886
4887 void peer_interface_unset(struct peer *peer)
4888 {
4889 if (peer->ifname)
4890 XFREE(MTYPE_BGP_PEER_IFNAME, peer->ifname);
4891 peer->ifname = NULL;
4892 }
4893
4894 /* Allow-as in. */
4895 int peer_allowas_in_set(struct peer *peer, afi_t afi, safi_t safi,
4896 int allow_num, int origin)
4897 {
4898 struct peer_group *group;
4899 struct listnode *node, *nnode;
4900
4901 if (origin) {
4902 if (peer->allowas_in[afi][safi]
4903 || CHECK_FLAG(peer->af_flags[afi][safi],
4904 PEER_FLAG_ALLOWAS_IN)
4905 || !CHECK_FLAG(peer->af_flags[afi][safi],
4906 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
4907 peer->allowas_in[afi][safi] = 0;
4908 peer_af_flag_unset(peer, afi, safi,
4909 PEER_FLAG_ALLOWAS_IN);
4910 peer_af_flag_set(peer, afi, safi,
4911 PEER_FLAG_ALLOWAS_IN_ORIGIN);
4912 peer_on_policy_change(peer, afi, safi, 0);
4913 }
4914
4915 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4916 return 0;
4917
4918 group = peer->group;
4919 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4920 if (peer->allowas_in[afi][safi]
4921 || CHECK_FLAG(peer->af_flags[afi][safi],
4922 PEER_FLAG_ALLOWAS_IN)
4923 || !CHECK_FLAG(peer->af_flags[afi][safi],
4924 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
4925 peer->allowas_in[afi][safi] = 0;
4926 peer_af_flag_unset(peer, afi, safi,
4927 PEER_FLAG_ALLOWAS_IN);
4928 peer_af_flag_set(peer, afi, safi,
4929 PEER_FLAG_ALLOWAS_IN_ORIGIN);
4930 peer_on_policy_change(peer, afi, safi, 0);
4931 }
4932 }
4933 } else {
4934 if (allow_num < 1 || allow_num > 10)
4935 return BGP_ERR_INVALID_VALUE;
4936
4937 if (peer->allowas_in[afi][safi] != allow_num
4938 || CHECK_FLAG(peer->af_flags[afi][safi],
4939 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
4940 peer->allowas_in[afi][safi] = allow_num;
4941 peer_af_flag_set(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
4942 peer_af_flag_unset(peer, afi, safi,
4943 PEER_FLAG_ALLOWAS_IN_ORIGIN);
4944 peer_on_policy_change(peer, afi, safi, 0);
4945 }
4946
4947 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
4948 return 0;
4949
4950 group = peer->group;
4951 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
4952 if (peer->allowas_in[afi][safi] != allow_num
4953 || CHECK_FLAG(peer->af_flags[afi][safi],
4954 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
4955 peer->allowas_in[afi][safi] = allow_num;
4956 peer_af_flag_set(peer, afi, safi,
4957 PEER_FLAG_ALLOWAS_IN);
4958 peer_af_flag_unset(peer, afi, safi,
4959 PEER_FLAG_ALLOWAS_IN_ORIGIN);
4960 peer_on_policy_change(peer, afi, safi, 0);
4961 }
4962 }
4963 }
4964
4965 return 0;
4966 }
4967
4968 int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
4969 {
4970 struct peer_group *group;
4971 struct peer *tmp_peer;
4972 struct listnode *node, *nnode;
4973
4974 /* If this is a peer-group we must first clear the flags for all of the
4975 * peer-group members
4976 */
4977 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
4978 group = peer->group;
4979 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
4980 if (CHECK_FLAG(tmp_peer->af_flags[afi][safi],
4981 PEER_FLAG_ALLOWAS_IN)
4982 || CHECK_FLAG(tmp_peer->af_flags[afi][safi],
4983 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
4984 tmp_peer->allowas_in[afi][safi] = 0;
4985 peer_af_flag_unset(tmp_peer, afi, safi,
4986 PEER_FLAG_ALLOWAS_IN);
4987 peer_af_flag_unset(tmp_peer, afi, safi,
4988 PEER_FLAG_ALLOWAS_IN_ORIGIN);
4989 peer_on_policy_change(tmp_peer, afi, safi, 0);
4990 }
4991 }
4992 }
4993
4994 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)
4995 || CHECK_FLAG(peer->af_flags[afi][safi],
4996 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
4997 peer->allowas_in[afi][safi] = 0;
4998 peer_af_flag_unset(peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
4999 peer_af_flag_unset(peer, afi, safi,
5000 PEER_FLAG_ALLOWAS_IN_ORIGIN);
5001 peer_on_policy_change(peer, afi, safi, 0);
5002 }
5003
5004 return 0;
5005 }
5006
5007 int peer_local_as_set(struct peer *peer, as_t as, int no_prepend,
5008 int replace_as)
5009 {
5010 struct bgp *bgp = peer->bgp;
5011 struct peer_group *group;
5012 struct listnode *node, *nnode;
5013
5014 if (peer_sort(peer) != BGP_PEER_EBGP
5015 && peer_sort(peer) != BGP_PEER_INTERNAL)
5016 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
5017
5018 if (bgp->as == as)
5019 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
5020
5021 if (peer->as == as)
5022 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
5023
5024 if (peer->change_local_as == as
5025 && ((CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)
5026 && no_prepend)
5027 || (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)
5028 && !no_prepend))
5029 && ((CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS)
5030 && replace_as)
5031 || (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS)
5032 && !replace_as)))
5033 return 0;
5034
5035 peer->change_local_as = as;
5036 if (no_prepend)
5037 SET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5038 else
5039 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5040
5041 if (replace_as)
5042 SET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5043 else
5044 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5045
5046 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5047 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5048 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5049 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5050 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5051 } else
5052 bgp_session_reset(peer);
5053 return 0;
5054 }
5055
5056 group = peer->group;
5057 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5058 peer->change_local_as = as;
5059 if (no_prepend)
5060 SET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5061 else
5062 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5063
5064 if (replace_as)
5065 SET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5066 else
5067 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5068
5069 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5070 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5071 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5072 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5073 } else
5074 BGP_EVENT_ADD(peer, BGP_Stop);
5075 }
5076
5077 return 0;
5078 }
5079
5080 int peer_local_as_unset(struct peer *peer)
5081 {
5082 struct peer_group *group;
5083 struct listnode *node, *nnode;
5084
5085 if (!peer->change_local_as)
5086 return 0;
5087
5088 peer->change_local_as = 0;
5089 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5090 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5091
5092 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5093 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5094 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5095 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5096 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5097 } else
5098 BGP_EVENT_ADD(peer, BGP_Stop);
5099
5100 return 0;
5101 }
5102
5103 group = peer->group;
5104 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5105 peer->change_local_as = 0;
5106 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
5107 UNSET_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
5108
5109 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
5110 peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
5111 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5112 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5113 } else
5114 bgp_session_reset(peer);
5115 }
5116 return 0;
5117 }
5118
5119 /* Set password for authenticating with the peer. */
5120 int peer_password_set(struct peer *peer, const char *password)
5121 {
5122 struct listnode *nn, *nnode;
5123 int len = password ? strlen(password) : 0;
5124 int ret = BGP_SUCCESS;
5125
5126 if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
5127 return BGP_ERR_INVALID_VALUE;
5128
5129 if (peer->password && strcmp(peer->password, password) == 0
5130 && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5131 return 0;
5132
5133 if (peer->password)
5134 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5135
5136 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
5137
5138 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5139 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5140 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5141 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5142 else
5143 bgp_session_reset(peer);
5144
5145 if (BGP_PEER_SU_UNSPEC(peer))
5146 return BGP_SUCCESS;
5147
5148 return (bgp_md5_set(peer) >= 0) ? BGP_SUCCESS
5149 : BGP_ERR_TCPSIG_FAILED;
5150 }
5151
5152 for (ALL_LIST_ELEMENTS(peer->group->peer, nn, nnode, peer)) {
5153 if (peer->password && strcmp(peer->password, password) == 0)
5154 continue;
5155
5156 if (peer->password)
5157 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5158
5159 peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
5160
5161 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5162 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5163 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5164 else
5165 bgp_session_reset(peer);
5166
5167 if (!BGP_PEER_SU_UNSPEC(peer)) {
5168 if (bgp_md5_set(peer) < 0)
5169 ret = BGP_ERR_TCPSIG_FAILED;
5170 }
5171 }
5172
5173 return ret;
5174 }
5175
5176 int peer_password_unset(struct peer *peer)
5177 {
5178 struct listnode *nn, *nnode;
5179
5180 if (!peer->password && !CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5181 return 0;
5182
5183 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5184 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5185 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5186 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5187 else
5188 bgp_session_reset(peer);
5189
5190 if (peer->password)
5191 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5192
5193 peer->password = NULL;
5194
5195 if (!BGP_PEER_SU_UNSPEC(peer))
5196 bgp_md5_unset(peer);
5197
5198 return 0;
5199 }
5200
5201 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5202 peer->password = NULL;
5203
5204 for (ALL_LIST_ELEMENTS(peer->group->peer, nn, nnode, peer)) {
5205 if (!peer->password)
5206 continue;
5207
5208 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
5209 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
5210 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
5211 else
5212 bgp_session_reset(peer);
5213
5214 XFREE(MTYPE_PEER_PASSWORD, peer->password);
5215 peer->password = NULL;
5216
5217 if (!BGP_PEER_SU_UNSPEC(peer))
5218 bgp_md5_unset(peer);
5219 }
5220
5221 return 0;
5222 }
5223
5224
5225 /* Set distribute list to the peer. */
5226 int peer_distribute_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5227 const char *name)
5228 {
5229 struct bgp_filter *filter;
5230 struct peer_group *group;
5231 struct listnode *node, *nnode;
5232
5233 if (direct != FILTER_IN && direct != FILTER_OUT)
5234 return BGP_ERR_INVALID_VALUE;
5235
5236 filter = &peer->filter[afi][safi];
5237
5238 if (filter->plist[direct].name)
5239 return BGP_ERR_PEER_FILTER_CONFLICT;
5240
5241 if (filter->dlist[direct].name)
5242 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[direct].name);
5243 filter->dlist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5244 filter->dlist[direct].alist = access_list_lookup(afi, name);
5245
5246 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5247 peer_on_policy_change(peer, afi, safi,
5248 (direct == FILTER_OUT) ? 1 : 0);
5249 return 0;
5250 }
5251
5252 group = peer->group;
5253 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5254 filter = &peer->filter[afi][safi];
5255
5256 if (filter->dlist[direct].name)
5257 XFREE(MTYPE_BGP_FILTER_NAME,
5258 filter->dlist[direct].name);
5259 filter->dlist[direct].name =
5260 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5261 filter->dlist[direct].alist = access_list_lookup(afi, name);
5262 peer_on_policy_change(peer, afi, safi,
5263 (direct == FILTER_OUT) ? 1 : 0);
5264 }
5265
5266 return 0;
5267 }
5268
5269 int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
5270 {
5271 struct bgp_filter *filter;
5272 struct bgp_filter *gfilter;
5273 struct peer_group *group;
5274 struct listnode *node, *nnode;
5275
5276 if (direct != FILTER_IN && direct != FILTER_OUT)
5277 return BGP_ERR_INVALID_VALUE;
5278
5279 filter = &peer->filter[afi][safi];
5280
5281 /* apply peer-group filter */
5282 if (peer_group_active(peer)) {
5283 gfilter = &peer->group->conf->filter[afi][safi];
5284
5285 if (gfilter->dlist[direct].name) {
5286 if (filter->dlist[direct].name)
5287 XFREE(MTYPE_BGP_FILTER_NAME,
5288 filter->dlist[direct].name);
5289 filter->dlist[direct].name =
5290 XSTRDUP(MTYPE_BGP_FILTER_NAME,
5291 gfilter->dlist[direct].name);
5292 filter->dlist[direct].alist =
5293 gfilter->dlist[direct].alist;
5294 peer_on_policy_change(peer, afi, safi,
5295 (direct == FILTER_OUT) ? 1 : 0);
5296 return 0;
5297 }
5298 }
5299
5300 if (filter->dlist[direct].name)
5301 XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[direct].name);
5302 filter->dlist[direct].name = NULL;
5303 filter->dlist[direct].alist = NULL;
5304
5305 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5306 peer_on_policy_change(peer, afi, safi,
5307 (direct == FILTER_OUT) ? 1 : 0);
5308 return 0;
5309 }
5310
5311 group = peer->group;
5312 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5313 filter = &peer->filter[afi][safi];
5314
5315 if (filter->dlist[direct].name)
5316 XFREE(MTYPE_BGP_FILTER_NAME,
5317 filter->dlist[direct].name);
5318 filter->dlist[direct].name = NULL;
5319 filter->dlist[direct].alist = NULL;
5320 peer_on_policy_change(peer, afi, safi,
5321 (direct == FILTER_OUT) ? 1 : 0);
5322 }
5323
5324 return 0;
5325 }
5326
5327 /* Update distribute list. */
5328 static void peer_distribute_update(struct access_list *access)
5329 {
5330 afi_t afi;
5331 safi_t safi;
5332 int direct;
5333 struct listnode *mnode, *mnnode;
5334 struct listnode *node, *nnode;
5335 struct bgp *bgp;
5336 struct peer *peer;
5337 struct peer_group *group;
5338 struct bgp_filter *filter;
5339
5340 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5341 if (access->name)
5342 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
5343 access->name, 0, 0);
5344 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5345 FOREACH_AFI_SAFI (afi, safi) {
5346 filter = &peer->filter[afi][safi];
5347
5348 for (direct = FILTER_IN; direct < FILTER_MAX;
5349 direct++) {
5350 if (filter->dlist[direct].name)
5351 filter->dlist[direct]
5352 .alist = access_list_lookup(
5353 afi,
5354 filter->dlist[direct]
5355 .name);
5356 else
5357 filter->dlist[direct].alist =
5358 NULL;
5359 }
5360 }
5361 }
5362 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
5363 FOREACH_AFI_SAFI (afi, safi) {
5364 filter = &group->conf->filter[afi][safi];
5365
5366 for (direct = FILTER_IN; direct < FILTER_MAX;
5367 direct++) {
5368 if (filter->dlist[direct].name)
5369 filter->dlist[direct]
5370 .alist = access_list_lookup(
5371 afi,
5372 filter->dlist[direct]
5373 .name);
5374 else
5375 filter->dlist[direct].alist =
5376 NULL;
5377 }
5378 }
5379 }
5380 #if ENABLE_BGP_VNC
5381 vnc_prefix_list_update(bgp);
5382 #endif
5383 }
5384 }
5385
5386 /* Set prefix list to the peer. */
5387 int peer_prefix_list_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5388 const char *name)
5389 {
5390 struct bgp_filter *filter;
5391 struct peer_group *group;
5392 struct listnode *node, *nnode;
5393
5394 if (direct != FILTER_IN && direct != FILTER_OUT)
5395 return BGP_ERR_INVALID_VALUE;
5396
5397 filter = &peer->filter[afi][safi];
5398
5399 if (filter->dlist[direct].name)
5400 return BGP_ERR_PEER_FILTER_CONFLICT;
5401
5402 if (filter->plist[direct].name)
5403 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[direct].name);
5404 filter->plist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5405 filter->plist[direct].plist = prefix_list_lookup(afi, name);
5406
5407 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5408 peer_on_policy_change(peer, afi, safi,
5409 (direct == FILTER_OUT) ? 1 : 0);
5410 return 0;
5411 }
5412
5413 group = peer->group;
5414 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5415 filter = &peer->filter[afi][safi];
5416
5417 if (filter->plist[direct].name)
5418 XFREE(MTYPE_BGP_FILTER_NAME,
5419 filter->plist[direct].name);
5420 filter->plist[direct].name =
5421 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5422 filter->plist[direct].plist = prefix_list_lookup(afi, name);
5423 peer_on_policy_change(peer, afi, safi,
5424 (direct == FILTER_OUT) ? 1 : 0);
5425 }
5426 return 0;
5427 }
5428
5429 int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi,
5430 int direct)
5431 {
5432 struct bgp_filter *filter;
5433 struct bgp_filter *gfilter;
5434 struct peer_group *group;
5435 struct listnode *node, *nnode;
5436
5437 if (direct != FILTER_IN && direct != FILTER_OUT)
5438 return BGP_ERR_INVALID_VALUE;
5439
5440 filter = &peer->filter[afi][safi];
5441
5442 /* apply peer-group filter */
5443 if (peer_group_active(peer)) {
5444 gfilter = &peer->group->conf->filter[afi][safi];
5445
5446 if (gfilter->plist[direct].name) {
5447 if (filter->plist[direct].name)
5448 XFREE(MTYPE_BGP_FILTER_NAME,
5449 filter->plist[direct].name);
5450 filter->plist[direct].name =
5451 XSTRDUP(MTYPE_BGP_FILTER_NAME,
5452 gfilter->plist[direct].name);
5453 filter->plist[direct].plist =
5454 gfilter->plist[direct].plist;
5455 peer_on_policy_change(peer, afi, safi,
5456 (direct == FILTER_OUT) ? 1 : 0);
5457 return 0;
5458 }
5459 }
5460
5461 if (filter->plist[direct].name)
5462 XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[direct].name);
5463 filter->plist[direct].name = NULL;
5464 filter->plist[direct].plist = NULL;
5465
5466 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5467 peer_on_policy_change(peer, afi, safi,
5468 (direct == FILTER_OUT) ? 1 : 0);
5469 return 0;
5470 }
5471
5472 group = peer->group;
5473 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5474 filter = &peer->filter[afi][safi];
5475
5476 if (filter->plist[direct].name)
5477 XFREE(MTYPE_BGP_FILTER_NAME,
5478 filter->plist[direct].name);
5479 filter->plist[direct].name = NULL;
5480 filter->plist[direct].plist = NULL;
5481 peer_on_policy_change(peer, afi, safi,
5482 (direct == FILTER_OUT) ? 1 : 0);
5483 }
5484
5485 return 0;
5486 }
5487
5488 /* Update prefix-list list. */
5489 static void peer_prefix_list_update(struct prefix_list *plist)
5490 {
5491 struct listnode *mnode, *mnnode;
5492 struct listnode *node, *nnode;
5493 struct bgp *bgp;
5494 struct peer *peer;
5495 struct peer_group *group;
5496 struct bgp_filter *filter;
5497 afi_t afi;
5498 safi_t safi;
5499 int direct;
5500
5501 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5502
5503 /*
5504 * Update the prefix-list on update groups.
5505 */
5506 update_group_policy_update(
5507 bgp, BGP_POLICY_PREFIX_LIST,
5508 plist ? prefix_list_name(plist) : NULL, 0, 0);
5509
5510 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5511 FOREACH_AFI_SAFI (afi, safi) {
5512 filter = &peer->filter[afi][safi];
5513
5514 for (direct = FILTER_IN; direct < FILTER_MAX;
5515 direct++) {
5516 if (filter->plist[direct].name)
5517 filter->plist[direct]
5518 .plist = prefix_list_lookup(
5519 afi,
5520 filter->plist[direct]
5521 .name);
5522 else
5523 filter->plist[direct].plist =
5524 NULL;
5525 }
5526 }
5527 }
5528 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
5529 FOREACH_AFI_SAFI (afi, safi) {
5530 filter = &group->conf->filter[afi][safi];
5531
5532 for (direct = FILTER_IN; direct < FILTER_MAX;
5533 direct++) {
5534 if (filter->plist[direct].name)
5535 filter->plist[direct]
5536 .plist = prefix_list_lookup(
5537 afi,
5538 filter->plist[direct]
5539 .name);
5540 else
5541 filter->plist[direct].plist =
5542 NULL;
5543 }
5544 }
5545 }
5546 }
5547 }
5548
5549 int peer_aslist_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5550 const char *name)
5551 {
5552 struct bgp_filter *filter;
5553 struct peer_group *group;
5554 struct listnode *node, *nnode;
5555
5556 if (direct != FILTER_IN && direct != FILTER_OUT)
5557 return BGP_ERR_INVALID_VALUE;
5558
5559 filter = &peer->filter[afi][safi];
5560
5561 if (filter->aslist[direct].name)
5562 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[direct].name);
5563 filter->aslist[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5564 filter->aslist[direct].aslist = as_list_lookup(name);
5565
5566 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5567 peer_on_policy_change(peer, afi, safi,
5568 (direct == FILTER_OUT) ? 1 : 0);
5569 return 0;
5570 }
5571
5572 group = peer->group;
5573 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5574 filter = &peer->filter[afi][safi];
5575
5576 if (filter->aslist[direct].name)
5577 XFREE(MTYPE_BGP_FILTER_NAME,
5578 filter->aslist[direct].name);
5579 filter->aslist[direct].name =
5580 XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5581 filter->aslist[direct].aslist = as_list_lookup(name);
5582 peer_on_policy_change(peer, afi, safi,
5583 (direct == FILTER_OUT) ? 1 : 0);
5584 }
5585 return 0;
5586 }
5587
5588 int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
5589 {
5590 struct bgp_filter *filter;
5591 struct bgp_filter *gfilter;
5592 struct peer_group *group;
5593 struct listnode *node, *nnode;
5594
5595 if (direct != FILTER_IN && direct != FILTER_OUT)
5596 return BGP_ERR_INVALID_VALUE;
5597
5598 filter = &peer->filter[afi][safi];
5599
5600 /* apply peer-group filter */
5601 if (peer_group_active(peer)) {
5602 gfilter = &peer->group->conf->filter[afi][safi];
5603
5604 if (gfilter->aslist[direct].name) {
5605 if (filter->aslist[direct].name)
5606 XFREE(MTYPE_BGP_FILTER_NAME,
5607 filter->aslist[direct].name);
5608 filter->aslist[direct].name =
5609 XSTRDUP(MTYPE_BGP_FILTER_NAME,
5610 gfilter->aslist[direct].name);
5611 filter->aslist[direct].aslist =
5612 gfilter->aslist[direct].aslist;
5613 peer_on_policy_change(peer, afi, safi,
5614 (direct == FILTER_OUT) ? 1 : 0);
5615 return 0;
5616 }
5617 }
5618
5619 if (filter->aslist[direct].name)
5620 XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[direct].name);
5621 filter->aslist[direct].name = NULL;
5622 filter->aslist[direct].aslist = NULL;
5623
5624 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5625 peer_on_policy_change(peer, afi, safi,
5626 (direct == FILTER_OUT) ? 1 : 0);
5627 return 0;
5628 }
5629
5630 group = peer->group;
5631 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5632 filter = &peer->filter[afi][safi];
5633
5634 if (filter->aslist[direct].name)
5635 XFREE(MTYPE_BGP_FILTER_NAME,
5636 filter->aslist[direct].name);
5637 filter->aslist[direct].name = NULL;
5638 filter->aslist[direct].aslist = NULL;
5639 peer_on_policy_change(peer, afi, safi,
5640 (direct == FILTER_OUT) ? 1 : 0);
5641 }
5642
5643 return 0;
5644 }
5645
5646 static void peer_aslist_update(const char *aslist_name)
5647 {
5648 afi_t afi;
5649 safi_t safi;
5650 int direct;
5651 struct listnode *mnode, *mnnode;
5652 struct listnode *node, *nnode;
5653 struct bgp *bgp;
5654 struct peer *peer;
5655 struct peer_group *group;
5656 struct bgp_filter *filter;
5657
5658 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
5659 update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
5660 aslist_name, 0, 0);
5661
5662 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
5663 FOREACH_AFI_SAFI (afi, safi) {
5664 filter = &peer->filter[afi][safi];
5665
5666 for (direct = FILTER_IN; direct < FILTER_MAX;
5667 direct++) {
5668 if (filter->aslist[direct].name)
5669 filter->aslist[direct]
5670 .aslist = as_list_lookup(
5671 filter->aslist[direct]
5672 .name);
5673 else
5674 filter->aslist[direct].aslist =
5675 NULL;
5676 }
5677 }
5678 }
5679 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
5680 FOREACH_AFI_SAFI (afi, safi) {
5681 filter = &group->conf->filter[afi][safi];
5682
5683 for (direct = FILTER_IN; direct < FILTER_MAX;
5684 direct++) {
5685 if (filter->aslist[direct].name)
5686 filter->aslist[direct]
5687 .aslist = as_list_lookup(
5688 filter->aslist[direct]
5689 .name);
5690 else
5691 filter->aslist[direct].aslist =
5692 NULL;
5693 }
5694 }
5695 }
5696 }
5697 }
5698
5699 static void peer_aslist_add(char *aslist_name)
5700 {
5701 peer_aslist_update(aslist_name);
5702 route_map_notify_dependencies((char *)aslist_name,
5703 RMAP_EVENT_ASLIST_ADDED);
5704 }
5705
5706 static void peer_aslist_del(const char *aslist_name)
5707 {
5708 peer_aslist_update(aslist_name);
5709 route_map_notify_dependencies(aslist_name, RMAP_EVENT_ASLIST_DELETED);
5710 }
5711
5712
5713 int peer_route_map_set(struct peer *peer, afi_t afi, safi_t safi, int direct,
5714 const char *name)
5715 {
5716 struct bgp_filter *filter;
5717 struct peer_group *group;
5718 struct listnode *node, *nnode;
5719
5720 if (direct != RMAP_IN && direct != RMAP_OUT)
5721 return BGP_ERR_INVALID_VALUE;
5722
5723 filter = &peer->filter[afi][safi];
5724
5725 if (filter->map[direct].name)
5726 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
5727
5728 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5729 filter->map[direct].map = route_map_lookup_by_name(name);
5730
5731 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5732 peer_on_policy_change(peer, afi, safi,
5733 (direct == RMAP_OUT) ? 1 : 0);
5734 return 0;
5735 }
5736
5737 group = peer->group;
5738 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5739 filter = &peer->filter[afi][safi];
5740
5741 if (filter->map[direct].name)
5742 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
5743 filter->map[direct].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5744 filter->map[direct].map = route_map_lookup_by_name(name);
5745 peer_on_policy_change(peer, afi, safi,
5746 (direct == RMAP_OUT) ? 1 : 0);
5747 }
5748 return 0;
5749 }
5750
5751 /* Unset route-map from the peer. */
5752 int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct)
5753 {
5754 struct bgp_filter *filter;
5755 struct bgp_filter *gfilter;
5756 struct peer_group *group;
5757 struct listnode *node, *nnode;
5758
5759 if (direct != RMAP_IN && direct != RMAP_OUT)
5760 return BGP_ERR_INVALID_VALUE;
5761
5762 filter = &peer->filter[afi][safi];
5763
5764 /* apply peer-group filter */
5765 if (peer_group_active(peer)) {
5766 gfilter = &peer->group->conf->filter[afi][safi];
5767
5768 if (gfilter->map[direct].name) {
5769 if (filter->map[direct].name)
5770 XFREE(MTYPE_BGP_FILTER_NAME,
5771 filter->map[direct].name);
5772 filter->map[direct].name =
5773 XSTRDUP(MTYPE_BGP_FILTER_NAME,
5774 gfilter->map[direct].name);
5775 filter->map[direct].map = gfilter->map[direct].map;
5776 peer_on_policy_change(peer, afi, safi,
5777 (direct == RMAP_OUT) ? 1 : 0);
5778 return 0;
5779 }
5780 }
5781
5782 if (filter->map[direct].name)
5783 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
5784 filter->map[direct].name = NULL;
5785 filter->map[direct].map = NULL;
5786
5787 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5788 peer_on_policy_change(peer, afi, safi,
5789 (direct == RMAP_OUT) ? 1 : 0);
5790 return 0;
5791 }
5792
5793 group = peer->group;
5794 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5795 filter = &peer->filter[afi][safi];
5796
5797 if (filter->map[direct].name)
5798 XFREE(MTYPE_BGP_FILTER_NAME, filter->map[direct].name);
5799 filter->map[direct].name = NULL;
5800 filter->map[direct].map = NULL;
5801 peer_on_policy_change(peer, afi, safi,
5802 (direct == RMAP_OUT) ? 1 : 0);
5803 }
5804 return 0;
5805 }
5806
5807 /* Set unsuppress-map to the peer. */
5808 int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
5809 const char *name)
5810 {
5811 struct bgp_filter *filter;
5812 struct peer_group *group;
5813 struct listnode *node, *nnode;
5814
5815 filter = &peer->filter[afi][safi];
5816
5817 if (filter->usmap.name)
5818 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
5819
5820 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5821 filter->usmap.map = route_map_lookup_by_name(name);
5822
5823 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5824 peer_on_policy_change(peer, afi, safi, 1);
5825 return 0;
5826 }
5827
5828 group = peer->group;
5829 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5830 filter = &peer->filter[afi][safi];
5831
5832 if (filter->usmap.name)
5833 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
5834 filter->usmap.name = XSTRDUP(MTYPE_BGP_FILTER_NAME, name);
5835 filter->usmap.map = route_map_lookup_by_name(name);
5836 peer_on_policy_change(peer, afi, safi, 1);
5837 }
5838 return 0;
5839 }
5840
5841 /* Unset route-map from the peer. */
5842 int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
5843 {
5844 struct bgp_filter *filter;
5845 struct peer_group *group;
5846 struct listnode *node, *nnode;
5847
5848 filter = &peer->filter[afi][safi];
5849
5850 if (filter->usmap.name)
5851 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
5852 filter->usmap.name = NULL;
5853 filter->usmap.map = NULL;
5854
5855 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5856 peer_on_policy_change(peer, afi, safi, 1);
5857 return 0;
5858 }
5859
5860 group = peer->group;
5861 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5862 filter = &peer->filter[afi][safi];
5863
5864 if (filter->usmap.name)
5865 XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
5866 filter->usmap.name = NULL;
5867 filter->usmap.map = NULL;
5868 peer_on_policy_change(peer, afi, safi, 1);
5869 }
5870 return 0;
5871 }
5872
5873 int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
5874 u_int32_t max, u_char threshold, int warning,
5875 u_int16_t restart)
5876 {
5877 struct peer_group *group;
5878 struct listnode *node, *nnode;
5879
5880 SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
5881 peer->pmax[afi][safi] = max;
5882 peer->pmax_threshold[afi][safi] = threshold;
5883 peer->pmax_restart[afi][safi] = restart;
5884 if (warning)
5885 SET_FLAG(peer->af_flags[afi][safi],
5886 PEER_FLAG_MAX_PREFIX_WARNING);
5887 else
5888 UNSET_FLAG(peer->af_flags[afi][safi],
5889 PEER_FLAG_MAX_PREFIX_WARNING);
5890
5891 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5892 group = peer->group;
5893 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5894 SET_FLAG(peer->af_flags[afi][safi],
5895 PEER_FLAG_MAX_PREFIX);
5896 peer->pmax[afi][safi] = max;
5897 peer->pmax_threshold[afi][safi] = threshold;
5898 peer->pmax_restart[afi][safi] = restart;
5899 if (warning)
5900 SET_FLAG(peer->af_flags[afi][safi],
5901 PEER_FLAG_MAX_PREFIX_WARNING);
5902 else
5903 UNSET_FLAG(peer->af_flags[afi][safi],
5904 PEER_FLAG_MAX_PREFIX_WARNING);
5905
5906 if ((peer->status == Established)
5907 && (peer->afc[afi][safi]))
5908 bgp_maximum_prefix_overflow(peer, afi, safi, 1);
5909 }
5910 } else {
5911 if ((peer->status == Established) && (peer->afc[afi][safi]))
5912 bgp_maximum_prefix_overflow(peer, afi, safi, 1);
5913 }
5914
5915 return 0;
5916 }
5917
5918 int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi)
5919 {
5920 struct peer_group *group;
5921 struct listnode *node, *nnode;
5922
5923 /* apply peer-group config */
5924 if (peer_group_active(peer)) {
5925 if (CHECK_FLAG(peer->group->conf->af_flags[afi][safi],
5926 PEER_FLAG_MAX_PREFIX))
5927 SET_FLAG(peer->af_flags[afi][safi],
5928 PEER_FLAG_MAX_PREFIX);
5929 else
5930 UNSET_FLAG(peer->af_flags[afi][safi],
5931 PEER_FLAG_MAX_PREFIX);
5932
5933 if (CHECK_FLAG(peer->group->conf->af_flags[afi][safi],
5934 PEER_FLAG_MAX_PREFIX_WARNING))
5935 SET_FLAG(peer->af_flags[afi][safi],
5936 PEER_FLAG_MAX_PREFIX_WARNING);
5937 else
5938 UNSET_FLAG(peer->af_flags[afi][safi],
5939 PEER_FLAG_MAX_PREFIX_WARNING);
5940
5941 peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
5942 peer->pmax_threshold[afi][safi] =
5943 peer->group->conf->pmax_threshold[afi][safi];
5944 peer->pmax_restart[afi][safi] =
5945 peer->group->conf->pmax_restart[afi][safi];
5946 return 0;
5947 }
5948
5949 UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
5950 UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
5951 peer->pmax[afi][safi] = 0;
5952 peer->pmax_threshold[afi][safi] = 0;
5953 peer->pmax_restart[afi][safi] = 0;
5954
5955 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
5956 return 0;
5957
5958 group = peer->group;
5959 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
5960 UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
5961 UNSET_FLAG(peer->af_flags[afi][safi],
5962 PEER_FLAG_MAX_PREFIX_WARNING);
5963 peer->pmax[afi][safi] = 0;
5964 peer->pmax_threshold[afi][safi] = 0;
5965 peer->pmax_restart[afi][safi] = 0;
5966 }
5967 return 0;
5968 }
5969
5970 int is_ebgp_multihop_configured(struct peer *peer)
5971 {
5972 struct peer_group *group;
5973 struct listnode *node, *nnode;
5974 struct peer *peer1;
5975
5976 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
5977 group = peer->group;
5978 if ((peer_sort(peer) != BGP_PEER_IBGP)
5979 && (group->conf->ttl != 1))
5980 return 1;
5981
5982 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer1)) {
5983 if ((peer_sort(peer1) != BGP_PEER_IBGP)
5984 && (peer1->ttl != 1))
5985 return 1;
5986 }
5987 } else {
5988 if ((peer_sort(peer) != BGP_PEER_IBGP) && (peer->ttl != 1))
5989 return 1;
5990 }
5991 return 0;
5992 }
5993
5994 /* Set # of hops between us and BGP peer. */
5995 int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops)
5996 {
5997 struct peer_group *group;
5998 struct listnode *node, *nnode;
5999 int ret;
6000
6001 zlog_debug("peer_ttl_security_hops_set: set gtsm_hops to %d for %s",
6002 gtsm_hops, peer->host);
6003
6004 /* We cannot configure ttl-security hops when ebgp-multihop is already
6005 set. For non peer-groups, the check is simple. For peer-groups,
6006 it's
6007 slightly messy, because we need to check both the peer-group
6008 structure
6009 and all peer-group members for any trace of ebgp-multihop
6010 configuration
6011 before actually applying the ttl-security rules. Cisco really made a
6012 mess of this configuration parameter, and OpenBGPD got it right.
6013 */
6014
6015 if ((peer->gtsm_hops == 0) && (peer->sort != BGP_PEER_IBGP)) {
6016 if (is_ebgp_multihop_configured(peer))
6017 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
6018
6019 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6020 peer->gtsm_hops = gtsm_hops;
6021
6022 /* Calling ebgp multihop also resets the session.
6023 * On restart, NHT will get setup correctly as will the
6024 * min & max ttls on the socket. The return value is
6025 * irrelevant.
6026 */
6027 ret = peer_ebgp_multihop_set(peer, MAXTTL);
6028
6029 if (ret != 0)
6030 return ret;
6031 } else {
6032 group = peer->group;
6033 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
6034 peer)) {
6035 peer->gtsm_hops = group->conf->gtsm_hops;
6036
6037 /* Calling ebgp multihop also resets the
6038 * session.
6039 * On restart, NHT will get setup correctly as
6040 * will the
6041 * min & max ttls on the socket. The return
6042 * value is
6043 * irrelevant.
6044 */
6045 peer_ebgp_multihop_set(peer, MAXTTL);
6046 }
6047 }
6048 } else {
6049 /* Post the first gtsm setup or if its ibgp, maxttl setting
6050 * isn't
6051 * necessary, just set the minttl.
6052 */
6053 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6054 peer->gtsm_hops = gtsm_hops;
6055
6056 if (peer->fd >= 0)
6057 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
6058 MAXTTL + 1 - gtsm_hops);
6059 if ((peer->status < Established) && peer->doppelganger
6060 && (peer->doppelganger->fd >= 0))
6061 sockopt_minttl(peer->su.sa.sa_family,
6062 peer->doppelganger->fd,
6063 MAXTTL + 1 - gtsm_hops);
6064 } else {
6065 group = peer->group;
6066 for (ALL_LIST_ELEMENTS(group->peer, node, nnode,
6067 peer)) {
6068 peer->gtsm_hops = group->conf->gtsm_hops;
6069
6070 /* Change setting of existing peer
6071 * established then change value (may break
6072 * connectivity)
6073 * not established yet (teardown session and
6074 * restart)
6075 * no session then do nothing (will get
6076 * handled by next connection)
6077 */
6078 if (peer->fd >= 0 && peer->gtsm_hops != 0)
6079 sockopt_minttl(
6080 peer->su.sa.sa_family, peer->fd,
6081 MAXTTL + 1 - peer->gtsm_hops);
6082 if ((peer->status < Established)
6083 && peer->doppelganger
6084 && (peer->doppelganger->fd >= 0))
6085 sockopt_minttl(peer->su.sa.sa_family,
6086 peer->doppelganger->fd,
6087 MAXTTL + 1 - gtsm_hops);
6088 }
6089 }
6090 }
6091
6092 return 0;
6093 }
6094
6095 int peer_ttl_security_hops_unset(struct peer *peer)
6096 {
6097 struct peer_group *group;
6098 struct listnode *node, *nnode;
6099 int ret = 0;
6100
6101 zlog_debug("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s",
6102 peer->host);
6103
6104 /* if a peer-group member, then reset to peer-group default rather than
6105 * 0 */
6106 if (peer_group_active(peer))
6107 peer->gtsm_hops = peer->group->conf->gtsm_hops;
6108 else
6109 peer->gtsm_hops = 0;
6110
6111 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6112 /* Invoking ebgp_multihop_set will set the TTL back to the
6113 * original
6114 * value as well as restting the NHT and such. The session is
6115 * reset.
6116 */
6117 if (peer->sort == BGP_PEER_EBGP)
6118 ret = peer_ebgp_multihop_unset(peer);
6119 else {
6120 if (peer->fd >= 0)
6121 sockopt_minttl(peer->su.sa.sa_family, peer->fd,
6122 0);
6123
6124 if ((peer->status < Established) && peer->doppelganger
6125 && (peer->doppelganger->fd >= 0))
6126 sockopt_minttl(peer->su.sa.sa_family,
6127 peer->doppelganger->fd, 0);
6128 }
6129 } else {
6130 group = peer->group;
6131 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
6132 peer->gtsm_hops = 0;
6133 if (peer->sort == BGP_PEER_EBGP)
6134 ret = peer_ebgp_multihop_unset(peer);
6135 else {
6136 if (peer->fd >= 0)
6137 sockopt_minttl(peer->su.sa.sa_family,
6138 peer->fd, 0);
6139
6140 if ((peer->status < Established)
6141 && peer->doppelganger
6142 && (peer->doppelganger->fd >= 0))
6143 sockopt_minttl(peer->su.sa.sa_family,
6144 peer->doppelganger->fd,
6145 0);
6146 }
6147 }
6148 }
6149
6150 return ret;
6151 }
6152
6153 /*
6154 * If peer clear is invoked in a loop for all peers on the BGP instance,
6155 * it may end up freeing the doppelganger, and if this was the next node
6156 * to the current node, we would end up accessing the freed next node.
6157 * Pass along additional parameter which can be updated if next node
6158 * is freed; only required when walking the peer list on BGP instance.
6159 */
6160 int peer_clear(struct peer *peer, struct listnode **nnode)
6161 {
6162 if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) {
6163 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) {
6164 UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
6165 if (peer->t_pmax_restart) {
6166 BGP_TIMER_OFF(peer->t_pmax_restart);
6167 if (bgp_debug_neighbor_events(peer))
6168 zlog_debug(
6169 "%s Maximum-prefix restart timer canceled",
6170 peer->host);
6171 }
6172 BGP_EVENT_ADD(peer, BGP_Start);
6173 return 0;
6174 }
6175
6176 peer->v_start = BGP_INIT_START_TIMER;
6177 if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
6178 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
6179 BGP_NOTIFY_CEASE_ADMIN_RESET);
6180 else
6181 bgp_session_reset_safe(peer, nnode);
6182 }
6183 return 0;
6184 }
6185
6186 int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi,
6187 enum bgp_clear_type stype)
6188 {
6189 struct peer_af *paf;
6190
6191 if (peer->status != Established)
6192 return 0;
6193
6194 if (!peer->afc[afi][safi])
6195 return BGP_ERR_AF_UNCONFIGURED;
6196
6197 peer->rtt = sockopt_tcp_rtt(peer->fd);
6198
6199 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) {
6200 /* Clear the "neighbor x.x.x.x default-originate" flag */
6201 paf = peer_af_find(peer, afi, safi);
6202 if (paf && paf->subgroup
6203 && CHECK_FLAG(paf->subgroup->sflags,
6204 SUBGRP_STATUS_DEFAULT_ORIGINATE))
6205 UNSET_FLAG(paf->subgroup->sflags,
6206 SUBGRP_STATUS_DEFAULT_ORIGINATE);
6207
6208 bgp_announce_route(peer, afi, safi);
6209 }
6210
6211 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
6212 if (CHECK_FLAG(peer->af_cap[afi][safi],
6213 PEER_CAP_ORF_PREFIX_SM_ADV)
6214 && (CHECK_FLAG(peer->af_cap[afi][safi],
6215 PEER_CAP_ORF_PREFIX_RM_RCV)
6216 || CHECK_FLAG(peer->af_cap[afi][safi],
6217 PEER_CAP_ORF_PREFIX_RM_OLD_RCV))) {
6218 struct bgp_filter *filter = &peer->filter[afi][safi];
6219 u_char prefix_type;
6220
6221 if (CHECK_FLAG(peer->af_cap[afi][safi],
6222 PEER_CAP_ORF_PREFIX_RM_RCV))
6223 prefix_type = ORF_TYPE_PREFIX;
6224 else
6225 prefix_type = ORF_TYPE_PREFIX_OLD;
6226
6227 if (filter->plist[FILTER_IN].plist) {
6228 if (CHECK_FLAG(peer->af_sflags[afi][safi],
6229 PEER_STATUS_ORF_PREFIX_SEND))
6230 bgp_route_refresh_send(
6231 peer, afi, safi, prefix_type,
6232 REFRESH_DEFER, 1);
6233 bgp_route_refresh_send(peer, afi, safi,
6234 prefix_type,
6235 REFRESH_IMMEDIATE, 0);
6236 } else {
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_IMMEDIATE, 1);
6242 else
6243 bgp_route_refresh_send(peer, afi, safi,
6244 0, 0, 0);
6245 }
6246 return 0;
6247 }
6248 }
6249
6250 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
6251 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) {
6252 /* If neighbor has soft reconfiguration inbound flag.
6253 Use Adj-RIB-In database. */
6254 if (CHECK_FLAG(peer->af_flags[afi][safi],
6255 PEER_FLAG_SOFT_RECONFIG))
6256 bgp_soft_reconfig_in(peer, afi, safi);
6257 else {
6258 /* If neighbor has route refresh capability, send route
6259 refresh
6260 message to the peer. */
6261 if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV)
6262 || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV))
6263 bgp_route_refresh_send(peer, afi, safi, 0, 0,
6264 0);
6265 else
6266 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
6267 }
6268 }
6269 return 0;
6270 }
6271
6272 /* Display peer uptime.*/
6273 char *peer_uptime(time_t uptime2, char *buf, size_t len, u_char use_json,
6274 json_object *json)
6275 {
6276 time_t uptime1, epoch_tbuf;
6277 struct tm *tm;
6278
6279 /* Check buffer length. */
6280 if (len < BGP_UPTIME_LEN) {
6281 if (!use_json) {
6282 zlog_warn("peer_uptime (): buffer shortage %lu",
6283 (u_long)len);
6284 /* XXX: should return status instead of buf... */
6285 snprintf(buf, len, "<error> ");
6286 }
6287 return buf;
6288 }
6289
6290 /* If there is no connection has been done before print `never'. */
6291 if (uptime2 == 0) {
6292 if (use_json) {
6293 json_object_string_add(json, "peerUptime", "never");
6294 json_object_int_add(json, "peerUptimeMsec", 0);
6295 } else
6296 snprintf(buf, len, "never");
6297 return buf;
6298 }
6299
6300 /* Get current time. */
6301 uptime1 = bgp_clock();
6302 uptime1 -= uptime2;
6303 tm = gmtime(&uptime1);
6304
6305 if (uptime1 < ONE_DAY_SECOND)
6306 snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
6307 tm->tm_sec);
6308 else if (uptime1 < ONE_WEEK_SECOND)
6309 snprintf(buf, len, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour,
6310 tm->tm_min);
6311 else if (uptime1 < ONE_YEAR_SECOND)
6312 snprintf(buf, len, "%02dw%dd%02dh", tm->tm_yday / 7,
6313 tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour);
6314 else
6315 snprintf(buf, len, "%02dy%02dw%dd", tm->tm_year - 70,
6316 tm->tm_yday / 7,
6317 tm->tm_yday - ((tm->tm_yday / 7) * 7));
6318
6319 if (use_json) {
6320 epoch_tbuf = time(NULL) - uptime1;
6321 json_object_string_add(json, "peerUptime", buf);
6322 json_object_int_add(json, "peerUptimeMsec", uptime1 * 1000);
6323 json_object_int_add(json, "peerUptimeEstablishedEpoch",
6324 epoch_tbuf);
6325 }
6326
6327 return buf;
6328 }
6329
6330 static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
6331 afi_t afi, safi_t safi)
6332 {
6333 struct bgp_filter *filter;
6334 struct bgp_filter *gfilter = NULL;
6335 char *addr;
6336 int in = FILTER_IN;
6337 int out = FILTER_OUT;
6338
6339 addr = peer->host;
6340 filter = &peer->filter[afi][safi];
6341
6342 if (peer_group_active(peer))
6343 gfilter = &peer->group->conf->filter[afi][safi];
6344
6345 /* distribute-list. */
6346 if (filter->dlist[in].name)
6347 if (!gfilter || !gfilter->dlist[in].name
6348 || strcmp(filter->dlist[in].name, gfilter->dlist[in].name)
6349 != 0) {
6350 vty_out(vty, " neighbor %s distribute-list %s in\n",
6351 addr, filter->dlist[in].name);
6352 }
6353
6354 if (filter->dlist[out].name && !gfilter) {
6355 vty_out(vty, " neighbor %s distribute-list %s out\n", addr,
6356 filter->dlist[out].name);
6357 }
6358
6359 /* prefix-list. */
6360 if (filter->plist[in].name)
6361 if (!gfilter || !gfilter->plist[in].name
6362 || strcmp(filter->plist[in].name, gfilter->plist[in].name)
6363 != 0) {
6364 vty_out(vty, " neighbor %s prefix-list %s in\n", addr,
6365 filter->plist[in].name);
6366 }
6367
6368 if (filter->plist[out].name)
6369 if (!gfilter || !gfilter->plist[out].name
6370 || strcmp(filter->plist[out].name, gfilter->plist[out].name)
6371 != 0) {
6372 vty_out(vty, " neighbor %s prefix-list %s out\n", addr,
6373 filter->plist[out].name);
6374 }
6375
6376 /* route-map. */
6377 if (filter->map[RMAP_IN].name)
6378 if (!gfilter || !gfilter->map[RMAP_IN].name
6379 || strcmp(filter->map[RMAP_IN].name,
6380 gfilter->map[RMAP_IN].name)
6381 != 0) {
6382 vty_out(vty, " neighbor %s route-map %s in\n", addr,
6383 filter->map[RMAP_IN].name);
6384 }
6385
6386 if (filter->map[RMAP_OUT].name)
6387 if (!gfilter || !gfilter->map[RMAP_OUT].name
6388 || strcmp(filter->map[RMAP_OUT].name,
6389 gfilter->map[RMAP_OUT].name)
6390 != 0) {
6391 vty_out(vty, " neighbor %s route-map %s out\n", addr,
6392 filter->map[RMAP_OUT].name);
6393 }
6394
6395 /* unsuppress-map */
6396 if (filter->usmap.name && !gfilter) {
6397 vty_out(vty, " neighbor %s unsuppress-map %s\n", addr,
6398 filter->usmap.name);
6399 }
6400
6401 /* filter-list. */
6402 if (filter->aslist[in].name)
6403 if (!gfilter || !gfilter->aslist[in].name
6404 || strcmp(filter->aslist[in].name, gfilter->aslist[in].name)
6405 != 0) {
6406 vty_out(vty, " neighbor %s filter-list %s in\n", addr,
6407 filter->aslist[in].name);
6408 }
6409
6410 if (filter->aslist[out].name && !gfilter) {
6411 vty_out(vty, " neighbor %s filter-list %s out\n", addr,
6412 filter->aslist[out].name);
6413 }
6414 }
6415
6416 /* BGP peer configuration display function. */
6417 static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
6418 struct peer *peer)
6419 {
6420 struct peer *g_peer = NULL;
6421 char buf[SU_ADDRSTRLEN];
6422 char *addr;
6423 int if_pg_printed = FALSE;
6424 int if_ras_printed = FALSE;
6425
6426 /* Skip dynamic neighbors. */
6427 if (peer_dynamic_neighbor(peer))
6428 return;
6429
6430 if (peer->conf_if)
6431 addr = peer->conf_if;
6432 else
6433 addr = peer->host;
6434
6435 /************************************
6436 ****** Global to the neighbor ******
6437 ************************************/
6438 if (peer->conf_if) {
6439 if (CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
6440 vty_out(vty, " neighbor %s interface v6only", addr);
6441 else
6442 vty_out(vty, " neighbor %s interface", addr);
6443
6444 if (peer_group_active(peer)) {
6445 vty_out(vty, " peer-group %s", peer->group->name);
6446 if_pg_printed = TRUE;
6447 } else if (peer->as_type == AS_SPECIFIED) {
6448 vty_out(vty, " remote-as %u", peer->as);
6449 if_ras_printed = TRUE;
6450 } else if (peer->as_type == AS_INTERNAL) {
6451 vty_out(vty, " remote-as internal");
6452 if_ras_printed = TRUE;
6453 } else if (peer->as_type == AS_EXTERNAL) {
6454 vty_out(vty, " remote-as external");
6455 if_ras_printed = TRUE;
6456 }
6457
6458 vty_out(vty, "\n");
6459 }
6460
6461 /* remote-as and peer-group */
6462 /* peer is a member of a peer-group */
6463 if (peer_group_active(peer)) {
6464 g_peer = peer->group->conf;
6465
6466 if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) {
6467 if (peer->as_type == AS_SPECIFIED) {
6468 vty_out(vty, " neighbor %s remote-as %u\n",
6469 addr, peer->as);
6470 } else if (peer->as_type == AS_INTERNAL) {
6471 vty_out(vty,
6472 " neighbor %s remote-as internal\n",
6473 addr);
6474 } else if (peer->as_type == AS_EXTERNAL) {
6475 vty_out(vty,
6476 " neighbor %s remote-as external\n",
6477 addr);
6478 }
6479 }
6480
6481 /* For swpX peers we displayed the peer-group
6482 * via 'neighbor swpX interface peer-group WORD' */
6483 if (!if_pg_printed)
6484 vty_out(vty, " neighbor %s peer-group %s\n", addr,
6485 peer->group->name);
6486 }
6487
6488 /* peer is NOT a member of a peer-group */
6489 else {
6490 /* peer is a peer-group, declare the peer-group */
6491 if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
6492 vty_out(vty, " neighbor %s peer-group\n", addr);
6493 }
6494
6495 if (!if_ras_printed) {
6496 if (peer->as_type == AS_SPECIFIED) {
6497 vty_out(vty, " neighbor %s remote-as %u\n",
6498 addr, peer->as);
6499 } else if (peer->as_type == AS_INTERNAL) {
6500 vty_out(vty,
6501 " neighbor %s remote-as internal\n",
6502 addr);
6503 } else if (peer->as_type == AS_EXTERNAL) {
6504 vty_out(vty,
6505 " neighbor %s remote-as external\n",
6506 addr);
6507 }
6508 }
6509 }
6510
6511 /* local-as */
6512 if (peer->change_local_as) {
6513 if (!peer_group_active(peer)
6514 || peer->change_local_as != g_peer->change_local_as
6515 || (CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)
6516 != CHECK_FLAG(g_peer->flags,
6517 PEER_FLAG_LOCAL_AS_NO_PREPEND))
6518 || (CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS)
6519 != CHECK_FLAG(g_peer->flags,
6520 PEER_FLAG_LOCAL_AS_REPLACE_AS))) {
6521 vty_out(vty, " neighbor %s local-as %u%s%s\n", addr,
6522 peer->change_local_as,
6523 CHECK_FLAG(peer->flags,
6524 PEER_FLAG_LOCAL_AS_NO_PREPEND)
6525 ? " no-prepend"
6526 : "",
6527 CHECK_FLAG(peer->flags,
6528 PEER_FLAG_LOCAL_AS_REPLACE_AS)
6529 ? " replace-as"
6530 : "");
6531 }
6532 }
6533
6534 /* description */
6535 if (peer->desc) {
6536 vty_out(vty, " neighbor %s description %s\n", addr, peer->desc);
6537 }
6538
6539 /* shutdown */
6540 if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) {
6541 if (!peer_group_active(peer)
6542 || !CHECK_FLAG(g_peer->flags, PEER_FLAG_SHUTDOWN)
6543 || peer->tx_shutdown_message) {
6544 if (peer->tx_shutdown_message)
6545 vty_out(vty,
6546 " neighbor %s shutdown message %s\n",
6547 addr, peer->tx_shutdown_message);
6548 else
6549 vty_out(vty, " neighbor %s shutdown\n", addr);
6550 }
6551 }
6552
6553 /* bfd */
6554 if (peer->bfd_info) {
6555 if (!peer_group_active(peer) || !g_peer->bfd_info) {
6556 bgp_bfd_peer_config_write(vty, peer, addr);
6557 }
6558 }
6559
6560 /* password */
6561 if (peer->password) {
6562 if (!peer_group_active(peer) || !g_peer->password
6563 || strcmp(peer->password, g_peer->password) != 0) {
6564 vty_out(vty, " neighbor %s password %s\n", addr,
6565 peer->password);
6566 }
6567 }
6568
6569 /* neighbor solo */
6570 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)) {
6571 if (!peer_group_active(peer)) {
6572 vty_out(vty, " neighbor %s solo\n", addr);
6573 }
6574 }
6575
6576 /* BGP port */
6577 if (peer->port != BGP_PORT_DEFAULT) {
6578 vty_out(vty, " neighbor %s port %d\n", addr, peer->port);
6579 }
6580
6581 /* Local interface name */
6582 if (peer->ifname) {
6583 vty_out(vty, " neighbor %s interface %s\n", addr, peer->ifname);
6584 }
6585
6586 /* passive */
6587 if (CHECK_FLAG(peer->flags, PEER_FLAG_PASSIVE)) {
6588 if (!peer_group_active(peer)
6589 || !CHECK_FLAG(g_peer->flags, PEER_FLAG_PASSIVE)) {
6590 vty_out(vty, " neighbor %s passive\n", addr);
6591 }
6592 }
6593
6594 /* ebgp-multihop */
6595 if (peer->sort != BGP_PEER_IBGP && peer->ttl != 1
6596 && !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL)) {
6597 if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) {
6598 vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr,
6599 peer->ttl);
6600 }
6601 }
6602
6603 /* ttl-security hops */
6604 if (peer->gtsm_hops != 0) {
6605 if (!peer_group_active(peer)
6606 || g_peer->gtsm_hops != peer->gtsm_hops) {
6607 vty_out(vty, " neighbor %s ttl-security hops %d\n",
6608 addr, peer->gtsm_hops);
6609 }
6610 }
6611
6612 /* disable-connected-check */
6613 if (CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) {
6614 if (!peer_group_active(peer)
6615 || !CHECK_FLAG(g_peer->flags,
6616 PEER_FLAG_DISABLE_CONNECTED_CHECK)) {
6617 vty_out(vty, " neighbor %s disable-connected-check\n",
6618 addr);
6619 }
6620 }
6621
6622 /* update-source */
6623 if (peer->update_if) {
6624 if (!peer_group_active(peer) || !g_peer->update_if
6625 || strcmp(g_peer->update_if, peer->update_if) != 0) {
6626 vty_out(vty, " neighbor %s update-source %s\n", addr,
6627 peer->update_if);
6628 }
6629 }
6630 if (peer->update_source) {
6631 if (!peer_group_active(peer) || !g_peer->update_source
6632 || sockunion_cmp(g_peer->update_source, peer->update_source)
6633 != 0) {
6634 vty_out(vty, " neighbor %s update-source %s\n", addr,
6635 sockunion2str(peer->update_source, buf,
6636 SU_ADDRSTRLEN));
6637 }
6638 }
6639
6640 /* advertisement-interval */
6641 if (CHECK_FLAG(peer->config, PEER_CONFIG_ROUTEADV)
6642 && ((!peer_group_active(peer)
6643 && peer->v_routeadv != BGP_DEFAULT_EBGP_ROUTEADV)
6644 || (peer_group_active(peer)
6645 && peer->v_routeadv != g_peer->v_routeadv))) {
6646 vty_out(vty, " neighbor %s advertisement-interval %u\n", addr,
6647 peer->v_routeadv);
6648 }
6649
6650 /* timers */
6651 if ((PEER_OR_GROUP_TIMER_SET(peer))
6652 && ((!peer_group_active(peer)
6653 && (peer->keepalive != BGP_DEFAULT_KEEPALIVE
6654 || peer->holdtime != BGP_DEFAULT_HOLDTIME))
6655 || (peer_group_active(peer)
6656 && (peer->keepalive != g_peer->keepalive
6657 || peer->holdtime != g_peer->holdtime)))) {
6658 vty_out(vty, " neighbor %s timers %u %u\n", addr,
6659 peer->keepalive, peer->holdtime);
6660 }
6661
6662 if (CHECK_FLAG(peer->config, PEER_CONFIG_CONNECT)
6663 && ((!peer_group_active(peer)
6664 && peer->connect != BGP_DEFAULT_CONNECT_RETRY)
6665 || (peer_group_active(peer)
6666 && peer->connect != g_peer->connect)))
6667
6668 {
6669 vty_out(vty, " neighbor %s timers connect %u\n", addr,
6670 peer->connect);
6671 }
6672
6673 /* capability dynamic */
6674 if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
6675 if (!peer_group_active(peer)
6676 || !CHECK_FLAG(g_peer->flags,
6677 PEER_FLAG_DYNAMIC_CAPABILITY)) {
6678 vty_out(vty, " neighbor %s capability dynamic\n", addr);
6679 }
6680 }
6681
6682 /* capability extended-nexthop */
6683 if (peer->ifp && !CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)) {
6684 if (!peer_group_active(peer)
6685 || !CHECK_FLAG(g_peer->flags, PEER_FLAG_CAPABILITY_ENHE)) {
6686 vty_out(vty,
6687 " no neighbor %s capability extended-nexthop\n",
6688 addr);
6689 }
6690 }
6691
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 " neighbor %s capability extended-nexthop\n",
6697 addr);
6698 }
6699 }
6700
6701 /* dont-capability-negotiation */
6702 if (CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY)) {
6703 if (!peer_group_active(peer)
6704 || !CHECK_FLAG(g_peer->flags, PEER_FLAG_DONT_CAPABILITY)) {
6705 vty_out(vty, " neighbor %s dont-capability-negotiate\n",
6706 addr);
6707 }
6708 }
6709
6710 /* override-capability */
6711 if (CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
6712 if (!peer_group_active(peer)
6713 || !CHECK_FLAG(g_peer->flags,
6714 PEER_FLAG_OVERRIDE_CAPABILITY)) {
6715 vty_out(vty, " neighbor %s override-capability\n",
6716 addr);
6717 }
6718 }
6719
6720 /* strict-capability-match */
6721 if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
6722 if (!peer_group_active(peer)
6723 || !CHECK_FLAG(g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
6724 vty_out(vty, " neighbor %s strict-capability-match\n",
6725 addr);
6726 }
6727 }
6728 }
6729
6730 /* BGP peer configuration display function. */
6731 static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
6732 struct peer *peer, afi_t afi, safi_t safi)
6733 {
6734 struct peer *g_peer = NULL;
6735 char *addr;
6736
6737 /* Skip dynamic neighbors. */
6738 if (peer_dynamic_neighbor(peer))
6739 return;
6740
6741 if (peer->conf_if)
6742 addr = peer->conf_if;
6743 else
6744 addr = peer->host;
6745
6746 /************************************
6747 ****** Per AF to the neighbor ******
6748 ************************************/
6749 if (peer_group_active(peer)) {
6750 g_peer = peer->group->conf;
6751
6752 /* If the peer-group is active but peer is not, print a 'no
6753 * activate' */
6754 if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) {
6755 vty_out(vty, " no neighbor %s activate\n", addr);
6756 }
6757
6758 /* If the peer-group is not active but peer is, print an
6759 'activate' */
6760 else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) {
6761 vty_out(vty, " neighbor %s activate\n", addr);
6762 }
6763 } else {
6764 if (peer->afc[afi][safi]) {
6765 if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
6766 if (bgp_flag_check(bgp,
6767 BGP_FLAG_NO_DEFAULT_IPV4)) {
6768 vty_out(vty, " neighbor %s activate\n",
6769 addr);
6770 }
6771 } else
6772 vty_out(vty, " neighbor %s activate\n", addr);
6773 } else {
6774 if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
6775 if (!bgp_flag_check(bgp,
6776 BGP_FLAG_NO_DEFAULT_IPV4)) {
6777 vty_out(vty,
6778 " no neighbor %s activate\n",
6779 addr);
6780 }
6781 }
6782 }
6783 }
6784
6785 /* addpath TX knobs */
6786 if (peergroup_af_flag_check(peer, afi, safi,
6787 PEER_FLAG_ADDPATH_TX_ALL_PATHS)) {
6788 vty_out(vty, " neighbor %s addpath-tx-all-paths\n", addr);
6789 }
6790
6791 if (peergroup_af_flag_check(peer, afi, safi,
6792 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
6793 vty_out(vty, " neighbor %s addpath-tx-bestpath-per-AS\n",
6794 addr);
6795 }
6796
6797 /* ORF capability. */
6798 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM)
6799 || peergroup_af_flag_check(peer, afi, safi,
6800 PEER_FLAG_ORF_PREFIX_RM)) {
6801 vty_out(vty, " neighbor %s capability orf prefix-list", addr);
6802
6803 if (peergroup_af_flag_check(peer, afi, safi,
6804 PEER_FLAG_ORF_PREFIX_SM)
6805 && peergroup_af_flag_check(peer, afi, safi,
6806 PEER_FLAG_ORF_PREFIX_RM))
6807 vty_out(vty, " both");
6808 else if (peergroup_af_flag_check(peer, afi, safi,
6809 PEER_FLAG_ORF_PREFIX_SM))
6810 vty_out(vty, " send");
6811 else
6812 vty_out(vty, " receive");
6813 vty_out(vty, "\n");
6814 }
6815
6816 /* Route reflector client. */
6817 if (peergroup_af_flag_check(peer, afi, safi,
6818 PEER_FLAG_REFLECTOR_CLIENT)) {
6819 vty_out(vty, " neighbor %s route-reflector-client\n", addr);
6820 }
6821
6822 /* next-hop-self force */
6823 if (peergroup_af_flag_check(peer, afi, safi,
6824 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
6825 vty_out(vty, " neighbor %s next-hop-self force\n", addr);
6826 }
6827
6828 /* next-hop-self */
6829 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) {
6830 vty_out(vty, " neighbor %s next-hop-self\n", addr);
6831 }
6832
6833 /* remove-private-AS */
6834 if (peergroup_af_flag_check(peer, afi, safi,
6835 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) {
6836 vty_out(vty, " neighbor %s remove-private-AS all replace-AS\n",
6837 addr);
6838 }
6839
6840 else if (peergroup_af_flag_check(peer, afi, safi,
6841 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) {
6842 vty_out(vty, " neighbor %s remove-private-AS replace-AS\n",
6843 addr);
6844 }
6845
6846 else if (peergroup_af_flag_check(peer, afi, safi,
6847 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
6848 vty_out(vty, " neighbor %s remove-private-AS all\n", addr);
6849 }
6850
6851 else if (peergroup_af_flag_check(peer, afi, safi,
6852 PEER_FLAG_REMOVE_PRIVATE_AS)) {
6853 vty_out(vty, " neighbor %s remove-private-AS\n", addr);
6854 }
6855
6856 /* as-override */
6857 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
6858 vty_out(vty, " neighbor %s as-override\n", addr);
6859 }
6860
6861 /* send-community print. */
6862 if (bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
6863 if (peergroup_af_flag_check(peer, afi, safi,
6864 PEER_FLAG_SEND_COMMUNITY)
6865 && peergroup_af_flag_check(peer, afi, safi,
6866 PEER_FLAG_SEND_EXT_COMMUNITY)
6867 && peergroup_af_flag_check(
6868 peer, afi, safi,
6869 PEER_FLAG_SEND_LARGE_COMMUNITY)) {
6870 vty_out(vty, " neighbor %s send-community all\n",
6871 addr);
6872 } else if (peergroup_af_flag_check(
6873 peer, afi, safi,
6874 PEER_FLAG_SEND_LARGE_COMMUNITY)) {
6875 vty_out(vty, " neighbor %s send-community large\n",
6876 addr);
6877 } else if (peergroup_af_flag_check(
6878 peer, afi, safi,
6879 PEER_FLAG_SEND_EXT_COMMUNITY)) {
6880 vty_out(vty, " neighbor %s send-community extended\n",
6881 addr);
6882 } else if (peergroup_af_flag_check(peer, afi, safi,
6883 PEER_FLAG_SEND_COMMUNITY)) {
6884 vty_out(vty, " neighbor %s send-community\n", addr);
6885 }
6886 } else {
6887 if (!peer_af_flag_check(peer, afi, safi,
6888 PEER_FLAG_SEND_COMMUNITY)
6889 && (!g_peer || peer_af_flag_check(g_peer, afi, safi,
6890 PEER_FLAG_SEND_COMMUNITY))
6891 && !peer_af_flag_check(peer, afi, safi,
6892 PEER_FLAG_SEND_EXT_COMMUNITY)
6893 && (!g_peer
6894 || peer_af_flag_check(g_peer, afi, safi,
6895 PEER_FLAG_SEND_EXT_COMMUNITY))
6896 && !peer_af_flag_check(peer, afi, safi,
6897 PEER_FLAG_SEND_LARGE_COMMUNITY)
6898 && (!g_peer || peer_af_flag_check(
6899 g_peer, afi, safi,
6900 PEER_FLAG_SEND_LARGE_COMMUNITY))) {
6901 vty_out(vty, " no neighbor %s send-community all\n",
6902 addr);
6903 } else {
6904 if (!peer_af_flag_check(peer, afi, safi,
6905 PEER_FLAG_SEND_LARGE_COMMUNITY)
6906 && (!g_peer
6907 || peer_af_flag_check(
6908 g_peer, afi, safi,
6909 PEER_FLAG_SEND_LARGE_COMMUNITY))) {
6910 vty_out(vty,
6911 " no neighbor %s send-community large\n",
6912 addr);
6913 }
6914
6915 if (!peer_af_flag_check(peer, afi, safi,
6916 PEER_FLAG_SEND_EXT_COMMUNITY)
6917 && (!g_peer
6918 || peer_af_flag_check(
6919 g_peer, afi, safi,
6920 PEER_FLAG_SEND_EXT_COMMUNITY))) {
6921 vty_out(vty,
6922 " no neighbor %s send-community extended\n",
6923 addr);
6924 }
6925
6926 if (!peer_af_flag_check(peer, afi, safi,
6927 PEER_FLAG_SEND_COMMUNITY)
6928 && (!g_peer || peer_af_flag_check(
6929 g_peer, afi, safi,
6930 PEER_FLAG_SEND_COMMUNITY))) {
6931 vty_out(vty,
6932 " no neighbor %s send-community\n",
6933 addr);
6934 }
6935 }
6936 }
6937
6938 /* Default information */
6939 if (peergroup_af_flag_check(peer, afi, safi,
6940 PEER_FLAG_DEFAULT_ORIGINATE)
6941 || (g_peer
6942 && ((peer->default_rmap[afi][safi].name
6943 && !g_peer->default_rmap[afi][safi].name)
6944 || (!peer->default_rmap[afi][safi].name
6945 && g_peer->default_rmap[afi][safi].name)
6946 || (peer->default_rmap[afi][safi].name
6947 && strcmp(peer->default_rmap[afi][safi].name,
6948 g_peer->default_rmap[afi][safi].name))))) {
6949 vty_out(vty, " neighbor %s default-originate", addr);
6950 if (peer->default_rmap[afi][safi].name)
6951 vty_out(vty, " route-map %s",
6952 peer->default_rmap[afi][safi].name);
6953 vty_out(vty, "\n");
6954 }
6955
6956 /* Soft reconfiguration inbound. */
6957 if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) {
6958 vty_out(vty, " neighbor %s soft-reconfiguration inbound\n",
6959 addr);
6960 }
6961
6962 /* maximum-prefix. */
6963 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
6964 if (!peer_group_active(peer)
6965 || g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
6966 || g_peer->pmax_threshold[afi][safi]
6967 != peer->pmax_threshold[afi][safi]
6968 || CHECK_FLAG(g_peer->af_flags[afi][safi],
6969 PEER_FLAG_MAX_PREFIX_WARNING)
6970 != CHECK_FLAG(peer->af_flags[afi][safi],
6971 PEER_FLAG_MAX_PREFIX_WARNING)) {
6972 vty_out(vty, " neighbor %s maximum-prefix %lu", addr,
6973 peer->pmax[afi][safi]);
6974 if (peer->pmax_threshold[afi][safi]
6975 != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
6976 vty_out(vty, " %u",
6977 peer->pmax_threshold[afi][safi]);
6978 if (CHECK_FLAG(peer->af_flags[afi][safi],
6979 PEER_FLAG_MAX_PREFIX_WARNING))
6980 vty_out(vty, " warning-only");
6981 if (peer->pmax_restart[afi][safi])
6982 vty_out(vty, " restart %u",
6983 peer->pmax_restart[afi][safi]);
6984 vty_out(vty, "\n");
6985 }
6986
6987 /* Route server client. */
6988 if (peergroup_af_flag_check(peer, afi, safi,
6989 PEER_FLAG_RSERVER_CLIENT)) {
6990 vty_out(vty, " neighbor %s route-server-client\n", addr);
6991 }
6992
6993 /* Nexthop-local unchanged. */
6994 if (peergroup_af_flag_check(peer, afi, safi,
6995 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) {
6996 vty_out(vty, " neighbor %s nexthop-local unchanged\n", addr);
6997 }
6998
6999 /* allowas-in <1-10> */
7000 if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) {
7001 if (!peer_group_active(peer)
7002 || !peer_af_flag_check(g_peer, afi, safi,
7003 PEER_FLAG_ALLOWAS_IN)
7004 || peer->allowas_in[afi][safi]
7005 != g_peer->allowas_in[afi][safi]) {
7006 if (peer->allowas_in[afi][safi] == 3) {
7007 vty_out(vty, " neighbor %s allowas-in\n",
7008 addr);
7009 } else {
7010 vty_out(vty, " neighbor %s allowas-in %d\n",
7011 addr, peer->allowas_in[afi][safi]);
7012 }
7013 }
7014 }
7015
7016 /* allowas-in origin */
7017 else if (peer_af_flag_check(peer, afi, safi,
7018 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
7019 if (!peer_group_active(peer)
7020 || !peer_af_flag_check(g_peer, afi, safi,
7021 PEER_FLAG_ALLOWAS_IN_ORIGIN)) {
7022 vty_out(vty, " neighbor %s allowas-in origin\n", addr);
7023 }
7024 }
7025
7026 /* weight */
7027 if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_WEIGHT))
7028 if (!peer_group_active(peer)
7029 || !peer_af_flag_check(g_peer, afi, safi, PEER_FLAG_WEIGHT)
7030 || peer->weight[afi][safi] != g_peer->weight[afi][safi]) {
7031 if (peer->weight[afi][safi]) {
7032 vty_out(vty, " neighbor %s weight %lu\n", addr,
7033 peer->weight[afi][safi]);
7034 }
7035 }
7036
7037 /* Filter. */
7038 bgp_config_write_filter(vty, peer, afi, safi);
7039
7040 /* atribute-unchanged. */
7041 if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED)
7042 || peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED)
7043 || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
7044
7045 if (!peer_group_active(peer)
7046 || peergroup_af_flag_check(peer, afi, safi,
7047 PEER_FLAG_AS_PATH_UNCHANGED)
7048 || peergroup_af_flag_check(peer, afi, safi,
7049 PEER_FLAG_NEXTHOP_UNCHANGED)
7050 || peergroup_af_flag_check(peer, afi, safi,
7051 PEER_FLAG_MED_UNCHANGED)) {
7052
7053 vty_out(vty,
7054 " neighbor %s attribute-unchanged%s%s%s\n",
7055 addr,
7056 peer_af_flag_check(peer, afi, safi,
7057 PEER_FLAG_AS_PATH_UNCHANGED)
7058 ? " as-path"
7059 : "",
7060 peer_af_flag_check(peer, afi, safi,
7061 PEER_FLAG_NEXTHOP_UNCHANGED)
7062 ? " next-hop"
7063 : "",
7064 peer_af_flag_check(peer, afi, safi,
7065 PEER_FLAG_MED_UNCHANGED)
7066 ? " med"
7067 : "");
7068 }
7069 }
7070 }
7071
7072 /* Address family based peer configuration display. */
7073 static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi,
7074 safi_t safi)
7075 {
7076 struct peer *peer;
7077 struct peer_group *group;
7078 struct listnode *node, *nnode;
7079
7080
7081 vty_frame(vty, " !\n address-family ");
7082 if (afi == AFI_IP) {
7083 if (safi == SAFI_UNICAST)
7084 vty_frame(vty, "ipv4 unicast");
7085 else if (safi == SAFI_LABELED_UNICAST)
7086 vty_frame(vty, "ipv4 labeled-unicast");
7087 else if (safi == SAFI_MULTICAST)
7088 vty_frame(vty, "ipv4 multicast");
7089 else if (safi == SAFI_MPLS_VPN)
7090 vty_frame(vty, "ipv4 vpn");
7091 else if (safi == SAFI_ENCAP)
7092 vty_frame(vty, "ipv4 encap");
7093 } else if (afi == AFI_IP6) {
7094 if (safi == SAFI_UNICAST)
7095 vty_frame(vty, "ipv6 unicast");
7096 else if (safi == SAFI_LABELED_UNICAST)
7097 vty_frame(vty, "ipv6 labeled-unicast");
7098 else if (safi == SAFI_MULTICAST)
7099 vty_frame(vty, "ipv6 multicast");
7100 else if (safi == SAFI_MPLS_VPN)
7101 vty_frame(vty, "ipv6 vpn");
7102 else if (safi == SAFI_ENCAP)
7103 vty_frame(vty, "ipv6 encap");
7104 } else if (afi == AFI_L2VPN) {
7105 if (safi == SAFI_EVPN)
7106 vty_frame(vty, "l2vpn evpn");
7107 }
7108 vty_frame(vty, "\n");
7109
7110 bgp_config_write_distance(vty, bgp, afi, safi);
7111
7112 bgp_config_write_network(vty, bgp, afi, safi);
7113
7114 bgp_config_write_redistribute(vty, bgp, afi, safi);
7115
7116 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group))
7117 bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi);
7118
7119 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7120 /* Skip dynamic neighbors. */
7121 if (peer_dynamic_neighbor(peer))
7122 continue;
7123
7124 /* Do not display doppelganger peers */
7125 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
7126 bgp_config_write_peer_af(vty, bgp, peer, afi, safi);
7127 }
7128
7129 bgp_config_write_maxpaths(vty, bgp, afi, safi);
7130 bgp_config_write_table_map(vty, bgp, afi, safi);
7131
7132 if (safi == SAFI_EVPN)
7133 bgp_config_write_evpn_info(vty, bgp, afi, safi);
7134
7135 if (CHECK_FLAG(bgp->af_flags[afi][safi],
7136 BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) {
7137
7138 vty_out(vty, " export vpn\n");
7139 }
7140
7141 vty_endframe(vty, " exit-address-family\n");
7142 }
7143
7144 int bgp_config_write(struct vty *vty)
7145 {
7146 int write = 0;
7147 struct bgp *bgp;
7148 struct peer_group *group;
7149 struct peer *peer;
7150 struct listnode *node, *nnode;
7151 struct listnode *mnode, *mnnode;
7152
7153 /* BGP Multiple instance. */
7154 if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE)) {
7155 vty_out(vty, "no bgp multiple-instance\n");
7156 write++;
7157 }
7158
7159 /* BGP Config type. */
7160 if (bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
7161 vty_out(vty, "bgp config-type cisco\n");
7162 write++;
7163 }
7164
7165 if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER)
7166 vty_out(vty, "bgp route-map delay-timer %u\n",
7167 bm->rmap_update_timer);
7168
7169 if (write)
7170 vty_out(vty, "!\n");
7171
7172 /* BGP configuration. */
7173 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
7174
7175 /* skip all auto created vrf as they dont have user config */
7176 if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
7177 continue;
7178
7179 /* Router bgp ASN */
7180 vty_out(vty, "router bgp %u", bgp->as);
7181
7182 if (bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE)) {
7183 if (bgp->name)
7184 vty_out(vty, " %s %s",
7185 (bgp->inst_type
7186 == BGP_INSTANCE_TYPE_VIEW)
7187 ? "view"
7188 : "vrf",
7189 bgp->name);
7190 }
7191 vty_out(vty, "\n");
7192
7193 /* No Synchronization */
7194 if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
7195 vty_out(vty, " no synchronization\n");
7196
7197 /* BGP fast-external-failover. */
7198 if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
7199 vty_out(vty, " no bgp fast-external-failover\n");
7200
7201 /* BGP router ID. */
7202 if (bgp->router_id_static.s_addr != 0)
7203 vty_out(vty, " bgp router-id %s\n",
7204 inet_ntoa(bgp->router_id_static));
7205
7206 /* BGP log-neighbor-changes. */
7207 if (!!bgp_flag_check(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)
7208 != DFLT_BGP_LOG_NEIGHBOR_CHANGES)
7209 vty_out(vty, " %sbgp log-neighbor-changes\n",
7210 bgp_flag_check(bgp,
7211 BGP_FLAG_LOG_NEIGHBOR_CHANGES)
7212 ? ""
7213 : "no ");
7214
7215 /* BGP configuration. */
7216 if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
7217 vty_out(vty, " bgp always-compare-med\n");
7218
7219 /* BGP default ipv4-unicast. */
7220 if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4))
7221 vty_out(vty, " no bgp default ipv4-unicast\n");
7222
7223 /* BGP default local-preference. */
7224 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
7225 vty_out(vty, " bgp default local-preference %u\n",
7226 bgp->default_local_pref);
7227
7228 /* BGP default show-hostname */
7229 if (!!bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
7230 != DFLT_BGP_SHOW_HOSTNAME)
7231 vty_out(vty, " %sbgp default show-hostname\n",
7232 bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME)
7233 ? ""
7234 : "no ");
7235
7236 /* BGP default subgroup-pkt-queue-max. */
7237 if (bgp->default_subgroup_pkt_queue_max
7238 != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
7239 vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
7240 bgp->default_subgroup_pkt_queue_max);
7241
7242 /* BGP default autoshutdown neighbors */
7243 if (bgp->autoshutdown)
7244 vty_out(vty, " bgp default shutdown\n");
7245
7246 /* BGP client-to-client reflection. */
7247 if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
7248 vty_out(vty, " no bgp client-to-client reflection\n");
7249
7250 /* BGP cluster ID. */
7251 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID))
7252 vty_out(vty, " bgp cluster-id %s\n",
7253 inet_ntoa(bgp->cluster_id));
7254
7255 /* Disable ebgp connected nexthop check */
7256 if (bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
7257 vty_out(vty,
7258 " bgp disable-ebgp-connected-route-check\n");
7259
7260 /* Confederation identifier*/
7261 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
7262 vty_out(vty, " bgp confederation identifier %i\n",
7263 bgp->confed_id);
7264
7265 /* Confederation peer */
7266 if (bgp->confed_peers_cnt > 0) {
7267 int i;
7268
7269 vty_out(vty, " bgp confederation peers");
7270
7271 for (i = 0; i < bgp->confed_peers_cnt; i++)
7272 vty_out(vty, " %u", bgp->confed_peers[i]);
7273
7274 vty_out(vty, "\n");
7275 }
7276
7277 /* BGP enforce-first-as. */
7278 if (bgp_flag_check(bgp, BGP_FLAG_ENFORCE_FIRST_AS))
7279 vty_out(vty, " bgp enforce-first-as\n");
7280
7281 /* BGP deterministic-med. */
7282 if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
7283 != DFLT_BGP_DETERMINISTIC_MED)
7284 vty_out(vty, " %sbgp deterministic-med\n",
7285 bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
7286 ? ""
7287 : "no ");
7288
7289 /* BGP update-delay. */
7290 bgp_config_write_update_delay(vty, bgp);
7291
7292 if (bgp->v_maxmed_onstartup
7293 != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) {
7294 vty_out(vty, " bgp max-med on-startup %u",
7295 bgp->v_maxmed_onstartup);
7296 if (bgp->maxmed_onstartup_value
7297 != BGP_MAXMED_VALUE_DEFAULT)
7298 vty_out(vty, " %u",
7299 bgp->maxmed_onstartup_value);
7300 vty_out(vty, "\n");
7301 }
7302 if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) {
7303 vty_out(vty, " bgp max-med administrative");
7304 if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT)
7305 vty_out(vty, " %u", bgp->maxmed_admin_value);
7306 vty_out(vty, "\n");
7307 }
7308
7309 /* write quanta */
7310 bgp_config_write_wpkt_quanta(vty, bgp);
7311 /* read quanta */
7312 bgp_config_write_rpkt_quanta(vty, bgp);
7313
7314 /* coalesce time */
7315 bgp_config_write_coalesce_time(vty, bgp);
7316
7317 /* BGP graceful-restart. */
7318 if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
7319 vty_out(vty,
7320 " bgp graceful-restart stalepath-time %u\n",
7321 bgp->stalepath_time);
7322 if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME)
7323 vty_out(vty, " bgp graceful-restart restart-time %u\n",
7324 bgp->restart_time);
7325 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_RESTART))
7326 vty_out(vty, " bgp graceful-restart\n");
7327
7328 /* BGP graceful-shutdown */
7329 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
7330 vty_out(vty, " bgp graceful-shutdown\n");
7331
7332 /* BGP graceful-restart Preserve State F bit. */
7333 if (bgp_flag_check(bgp, BGP_FLAG_GR_PRESERVE_FWD))
7334 vty_out(vty,
7335 " bgp graceful-restart preserve-fw-state\n");
7336
7337 /* BGP bestpath method. */
7338 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE))
7339 vty_out(vty, " bgp bestpath as-path ignore\n");
7340 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED))
7341 vty_out(vty, " bgp bestpath as-path confed\n");
7342
7343 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
7344 if (bgp_flag_check(bgp,
7345 BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
7346 vty_out(vty,
7347 " bgp bestpath as-path multipath-relax as-set\n");
7348 } else {
7349 vty_out(vty,
7350 " bgp bestpath as-path multipath-relax\n");
7351 }
7352 }
7353
7354 if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
7355 vty_out(vty,
7356 " bgp route-reflector allow-outbound-policy\n");
7357 }
7358 if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID))
7359 vty_out(vty, " bgp bestpath compare-routerid\n");
7360 if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)
7361 || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) {
7362 vty_out(vty, " bgp bestpath med");
7363 if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED))
7364 vty_out(vty, " confed");
7365 if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
7366 vty_out(vty, " missing-as-worst");
7367 vty_out(vty, "\n");
7368 }
7369
7370 /* BGP network import check. */
7371 if (!!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
7372 != DFLT_BGP_IMPORT_CHECK)
7373 vty_out(vty, " %sbgp network import-check\n",
7374 bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
7375 ? ""
7376 : "no ");
7377
7378 /* BGP flag dampening. */
7379 if (CHECK_FLAG(bgp->af_flags[AFI_IP][SAFI_UNICAST],
7380 BGP_CONFIG_DAMPENING))
7381 bgp_config_write_damp(vty);
7382
7383 /* BGP timers configuration. */
7384 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
7385 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
7386 vty_out(vty, " timers bgp %u %u\n",
7387 bgp->default_keepalive, bgp->default_holdtime);
7388
7389 /* peer-group */
7390 for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
7391 bgp_config_write_peer_global(vty, bgp, group->conf);
7392 }
7393
7394 /* Normal neighbor configuration. */
7395 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
7396 if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
7397 bgp_config_write_peer_global(vty, bgp, peer);
7398 }
7399
7400 /* listen range and limit for dynamic BGP neighbors */
7401 bgp_config_write_listen(vty, bgp);
7402
7403 /* No auto-summary */
7404 if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
7405 vty_out(vty, " no auto-summary\n");
7406
7407 bgp_vpn_policy_config_write(vty, bgp);
7408
7409 /* IPv4 unicast configuration. */
7410 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
7411
7412 /* IPv4 multicast configuration. */
7413 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MULTICAST);
7414
7415 /* IPv4 labeled-unicast configuration. */
7416 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_LABELED_UNICAST);
7417
7418 /* IPv4 VPN configuration. */
7419 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MPLS_VPN);
7420
7421 /* ENCAPv4 configuration. */
7422 bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP);
7423
7424 /* IPv6 unicast configuration. */
7425 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST);
7426
7427 /* IPv6 multicast configuration. */
7428 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MULTICAST);
7429
7430 /* IPv6 labeled-unicast configuration. */
7431 bgp_config_write_family(vty, bgp, AFI_IP6,
7432 SAFI_LABELED_UNICAST);
7433
7434 /* IPv6 VPN configuration. */
7435 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
7436
7437 /* ENCAPv6 configuration. */
7438 bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP);
7439
7440 /* EVPN configuration. */
7441 bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN);
7442
7443 #if ENABLE_BGP_VNC
7444 bgp_rfapi_cfg_write(vty, bgp);
7445 #endif
7446
7447 vty_out(vty, "!\n");
7448 }
7449 return 0;
7450 }
7451
7452 void bgp_master_init(struct thread_master *master)
7453 {
7454 qobj_init();
7455
7456 memset(&bgp_master, 0, sizeof(struct bgp_master));
7457
7458 bm = &bgp_master;
7459 bm->bgp = list_new();
7460 bm->listen_sockets = list_new();
7461 bm->port = BGP_PORT_DEFAULT;
7462 bm->master = master;
7463 bm->start_time = bgp_clock();
7464 bm->t_rmap_update = NULL;
7465 bm->rmap_update_timer = RMAP_DEFAULT_UPDATE_TIMER;
7466
7467 bgp_process_queue_init();
7468
7469 /* init the rd id space.
7470 assign 0th index in the bitfield,
7471 so that we start with id 1
7472 */
7473 bf_init(bm->rd_idspace, UINT16_MAX);
7474 bf_assign_zero_index(bm->rd_idspace);
7475
7476 /* Enable multiple instances by default. */
7477 bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE);
7478
7479 QOBJ_REG(bm, bgp_master);
7480 }
7481
7482 /*
7483 * Free up connected routes and interfaces for a BGP instance. Invoked upon
7484 * instance delete (non-default only) or BGP exit.
7485 */
7486 static void bgp_if_finish(struct bgp *bgp)
7487 {
7488 struct vrf *vrf = vrf_lookup_by_id(bgp->vrf_id);
7489 struct interface *ifp;
7490
7491 if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW || !vrf)
7492 return;
7493
7494 FOR_ALL_INTERFACES (vrf, ifp) {
7495 struct listnode *c_node, *c_nnode;
7496 struct connected *c;
7497
7498 for (ALL_LIST_ELEMENTS(ifp->connected, c_node, c_nnode, c))
7499 bgp_connected_delete(bgp, c);
7500 }
7501 }
7502
7503 extern void bgp_snmp_init(void);
7504
7505 static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
7506 {
7507 struct vrf *vrf = NULL;
7508 struct listnode *next;
7509 struct bgp *bgp;
7510
7511 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
7512 if (vrf->vrf_id != VRF_DEFAULT)
7513 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, vrf->name));
7514 }
7515
7516 for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
7517 if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
7518 continue;
7519
7520 vector_set(comps, XSTRDUP(MTYPE_COMPLETION, bgp->name));
7521 }
7522 }
7523
7524 static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = {
7525 {.tokenname = "VIEWVRFNAME", .completions = bgp_viewvrf_autocomplete},
7526 {.completions = NULL},
7527 };
7528
7529 static void bgp_pthreads_init()
7530 {
7531 frr_pthread_init();
7532
7533 struct frr_pthread_attr io = {
7534 .id = PTHREAD_IO,
7535 .start = frr_pthread_attr_default.start,
7536 .stop = frr_pthread_attr_default.stop,
7537 };
7538 struct frr_pthread_attr ka = {
7539 .id = PTHREAD_KEEPALIVES,
7540 .start = bgp_keepalives_start,
7541 .stop = bgp_keepalives_stop,
7542 };
7543 frr_pthread_new(&io, "BGP I/O thread");
7544 frr_pthread_new(&ka, "BGP Keepalives thread");
7545 }
7546
7547 void bgp_pthreads_run()
7548 {
7549 struct frr_pthread *io = frr_pthread_get(PTHREAD_IO);
7550 struct frr_pthread *ka = frr_pthread_get(PTHREAD_KEEPALIVES);
7551
7552 frr_pthread_run(io, NULL);
7553 frr_pthread_run(ka, NULL);
7554
7555 /* Wait until threads are ready. */
7556 frr_pthread_wait_running(io);
7557 frr_pthread_wait_running(ka);
7558 }
7559
7560 void bgp_pthreads_finish()
7561 {
7562 frr_pthread_stop_all();
7563 frr_pthread_finish();
7564 }
7565
7566 void bgp_init(void)
7567 {
7568
7569 /* allocates some vital data structures used by peer commands in
7570 * vty_init */
7571
7572 /* pre-init pthreads */
7573 bgp_pthreads_init();
7574
7575 /* Init zebra. */
7576 bgp_zebra_init(bm->master);
7577
7578 #if ENABLE_BGP_VNC
7579 vnc_zebra_init(bm->master);
7580 #endif
7581
7582 /* BGP VTY commands installation. */
7583 bgp_vty_init();
7584
7585 /* BGP inits. */
7586 bgp_attr_init();
7587 bgp_debug_init();
7588 bgp_dump_init();
7589 bgp_route_init();
7590 bgp_route_map_init();
7591 bgp_scan_vty_init();
7592 bgp_mplsvpn_init();
7593 #if ENABLE_BGP_VNC
7594 rfapi_init();
7595 #endif
7596 bgp_ethernetvpn_init();
7597
7598 /* Access list initialize. */
7599 access_list_init();
7600 access_list_add_hook(peer_distribute_update);
7601 access_list_delete_hook(peer_distribute_update);
7602
7603 /* Filter list initialize. */
7604 bgp_filter_init();
7605 as_list_add_hook(peer_aslist_add);
7606 as_list_delete_hook(peer_aslist_del);
7607
7608 /* Prefix list initialize.*/
7609 prefix_list_init();
7610 prefix_list_add_hook(peer_prefix_list_update);
7611 prefix_list_delete_hook(peer_prefix_list_update);
7612
7613 /* Community list initialize. */
7614 bgp_clist = community_list_init();
7615
7616 /* BFD init */
7617 bgp_bfd_init();
7618
7619 cmd_variable_handler_register(bgp_viewvrf_var_handlers);
7620 }
7621
7622 void bgp_terminate(void)
7623 {
7624 struct bgp *bgp;
7625 struct peer *peer;
7626 struct listnode *node, *nnode;
7627 struct listnode *mnode, *mnnode;
7628
7629 QOBJ_UNREG(bm);
7630
7631 /* Close the listener sockets first as this prevents peers from
7632 * attempting
7633 * to reconnect on receiving the peer unconfig message. In the presence
7634 * of a large number of peers this will ensure that no peer is left with
7635 * a dangling connection
7636 */
7637 /* reverse bgp_master_init */
7638 bgp_close();
7639
7640 if (bm->listen_sockets)
7641 list_delete_and_null(&bm->listen_sockets);
7642
7643 for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
7644 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
7645 if (peer->status == Established
7646 || peer->status == OpenSent
7647 || peer->status == OpenConfirm)
7648 bgp_notify_send(peer, BGP_NOTIFY_CEASE,
7649 BGP_NOTIFY_CEASE_PEER_UNCONFIG);
7650
7651 if (bm->process_main_queue)
7652 work_queue_free_and_null(&bm->process_main_queue);
7653
7654 if (bm->t_rmap_update)
7655 BGP_TIMER_OFF(bm->t_rmap_update);
7656 }