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