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