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