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