]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_updgrp.c
Merge pull request #11909 from opensourcerouting/fix/a_couple_nits
[mirror_frr.git] / bgpd / bgp_updgrp.c
1 /**
2 * bgp_updgrp.c: BGP update group structures
3 *
4 * @copyright Copyright (C) 2014 Cumulus Networks, Inc.
5 *
6 * @author Avneesh Sachdev <avneesh@sproute.net>
7 * @author Rajesh Varadarajan <rajesh@sproute.net>
8 * @author Pradosh Mohapatra <pradosh@sproute.net>
9 *
10 * This file is part of GNU Zebra.
11 *
12 * GNU Zebra is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2, or (at your option) any
15 * later version.
16 *
17 * GNU Zebra is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; see the file COPYING; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #include <zebra.h>
28
29 #include "prefix.h"
30 #include "thread.h"
31 #include "buffer.h"
32 #include "stream.h"
33 #include "command.h"
34 #include "sockunion.h"
35 #include "network.h"
36 #include "memory.h"
37 #include "filter.h"
38 #include "routemap.h"
39 #include "log.h"
40 #include "plist.h"
41 #include "linklist.h"
42 #include "workqueue.h"
43 #include "hash.h"
44 #include "jhash.h"
45 #include "queue.h"
46
47 #include "bgpd/bgpd.h"
48 #include "bgpd/bgp_table.h"
49 #include "bgpd/bgp_debug.h"
50 #include "bgpd/bgp_errors.h"
51 #include "bgpd/bgp_fsm.h"
52 #include "bgpd/bgp_addpath.h"
53 #include "bgpd/bgp_advertise.h"
54 #include "bgpd/bgp_packet.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_route.h"
57 #include "bgpd/bgp_filter.h"
58 #include "bgpd/bgp_io.h"
59
60 /********************
61 * PRIVATE FUNCTIONS
62 ********************/
63
64 /**
65 * assign a unique ID to update group and subgroup. Mostly for display/
66 * debugging purposes. It's a 64-bit space - used leisurely without a
67 * worry about its wrapping and about filling gaps. While at it, timestamp
68 * the creation.
69 */
70 static void update_group_checkin(struct update_group *updgrp)
71 {
72 updgrp->id = ++bm->updgrp_idspace;
73 updgrp->uptime = monotime(NULL);
74 }
75
76 static void update_subgroup_checkin(struct update_subgroup *subgrp,
77 struct update_group *updgrp)
78 {
79 subgrp->id = ++bm->subgrp_idspace;
80 subgrp->uptime = monotime(NULL);
81 }
82
83 static void sync_init(struct update_subgroup *subgrp,
84 struct update_group *updgrp)
85 {
86 struct peer *peer = UPDGRP_PEER(updgrp);
87
88 subgrp->sync =
89 XCALLOC(MTYPE_BGP_SYNCHRONISE, sizeof(struct bgp_synchronize));
90 bgp_adv_fifo_init(&subgrp->sync->update);
91 bgp_adv_fifo_init(&subgrp->sync->withdraw);
92 bgp_adv_fifo_init(&subgrp->sync->withdraw_low);
93 subgrp->hash =
94 hash_create(bgp_advertise_attr_hash_key,
95 bgp_advertise_attr_hash_cmp, "BGP SubGroup Hash");
96
97 /* We use a larger buffer for subgrp->work in the event that:
98 * - We RX a BGP_UPDATE where the attributes alone are just
99 * under 4096 or 65535 (if Extended Message capability negotiated).
100 * - The user configures an outbound route-map that does many as-path
101 * prepends or adds many communities. At most they can have
102 * CMD_ARGC_MAX
103 * args in a route-map so there is a finite limit on how large they
104 * can
105 * make the attributes.
106 *
107 * Having a buffer with BGP_MAX_PACKET_SIZE_OVERFLOW allows us to avoid
108 * bounds
109 * checking for every single attribute as we construct an UPDATE.
110 */
111 subgrp->work = stream_new(peer->max_packet_size
112 + BGP_MAX_PACKET_SIZE_OVERFLOW);
113 subgrp->scratch = stream_new(peer->max_packet_size);
114 }
115
116 static void sync_delete(struct update_subgroup *subgrp)
117 {
118 XFREE(MTYPE_BGP_SYNCHRONISE, subgrp->sync);
119 if (subgrp->hash) {
120 hash_clean(subgrp->hash,
121 (void (*)(void *))bgp_advertise_attr_free);
122 hash_free(subgrp->hash);
123 }
124 subgrp->hash = NULL;
125 if (subgrp->work)
126 stream_free(subgrp->work);
127 subgrp->work = NULL;
128 if (subgrp->scratch)
129 stream_free(subgrp->scratch);
130 subgrp->scratch = NULL;
131 }
132
133 /**
134 * conf_copy
135 *
136 * copy only those fields that are relevant to update group match
137 */
138 static void conf_copy(struct peer *dst, struct peer *src, afi_t afi,
139 safi_t safi)
140 {
141 struct bgp_filter *srcfilter;
142 struct bgp_filter *dstfilter;
143
144 srcfilter = &src->filter[afi][safi];
145 dstfilter = &dst->filter[afi][safi];
146
147 dst->bgp = src->bgp;
148 dst->sort = src->sort;
149 dst->as = src->as;
150 dst->v_routeadv = src->v_routeadv;
151 dst->flags = src->flags;
152 dst->af_flags[afi][safi] = src->af_flags[afi][safi];
153 dst->pmax_out[afi][safi] = src->pmax_out[afi][safi];
154 dst->max_packet_size = src->max_packet_size;
155 XFREE(MTYPE_BGP_PEER_HOST, dst->host);
156
157 dst->host = XSTRDUP(MTYPE_BGP_PEER_HOST, src->host);
158 dst->cap = src->cap;
159 dst->af_cap[afi][safi] = src->af_cap[afi][safi];
160 dst->afc_nego[afi][safi] = src->afc_nego[afi][safi];
161 dst->orf_plist[afi][safi] = src->orf_plist[afi][safi];
162 dst->addpath_type[afi][safi] = src->addpath_type[afi][safi];
163 dst->local_as = src->local_as;
164 dst->change_local_as = src->change_local_as;
165 dst->shared_network = src->shared_network;
166 dst->local_role = src->local_role;
167
168 if (src->soo[afi][safi]) {
169 ecommunity_free(&dst->soo[afi][safi]);
170 dst->soo[afi][safi] = ecommunity_dup(src->soo[afi][safi]);
171 }
172
173 memcpy(&(dst->nexthop), &(src->nexthop), sizeof(struct bgp_nexthop));
174
175 dst->group = src->group;
176
177 if (src->default_rmap[afi][safi].name) {
178 dst->default_rmap[afi][safi].name =
179 XSTRDUP(MTYPE_ROUTE_MAP_NAME,
180 src->default_rmap[afi][safi].name);
181 dst->default_rmap[afi][safi].map =
182 src->default_rmap[afi][safi].map;
183 }
184
185 if (DISTRIBUTE_OUT_NAME(srcfilter)) {
186 DISTRIBUTE_OUT_NAME(dstfilter) = XSTRDUP(
187 MTYPE_BGP_FILTER_NAME, DISTRIBUTE_OUT_NAME(srcfilter));
188 DISTRIBUTE_OUT(dstfilter) = DISTRIBUTE_OUT(srcfilter);
189 }
190
191 if (PREFIX_LIST_OUT_NAME(srcfilter)) {
192 PREFIX_LIST_OUT_NAME(dstfilter) = XSTRDUP(
193 MTYPE_BGP_FILTER_NAME, PREFIX_LIST_OUT_NAME(srcfilter));
194 PREFIX_LIST_OUT(dstfilter) = PREFIX_LIST_OUT(srcfilter);
195 }
196
197 if (FILTER_LIST_OUT_NAME(srcfilter)) {
198 FILTER_LIST_OUT_NAME(dstfilter) = XSTRDUP(
199 MTYPE_BGP_FILTER_NAME, FILTER_LIST_OUT_NAME(srcfilter));
200 FILTER_LIST_OUT(dstfilter) = FILTER_LIST_OUT(srcfilter);
201 }
202
203 if (ROUTE_MAP_OUT_NAME(srcfilter)) {
204 ROUTE_MAP_OUT_NAME(dstfilter) = XSTRDUP(
205 MTYPE_BGP_FILTER_NAME, ROUTE_MAP_OUT_NAME(srcfilter));
206 ROUTE_MAP_OUT(dstfilter) = ROUTE_MAP_OUT(srcfilter);
207 }
208
209 if (UNSUPPRESS_MAP_NAME(srcfilter)) {
210 UNSUPPRESS_MAP_NAME(dstfilter) = XSTRDUP(
211 MTYPE_BGP_FILTER_NAME, UNSUPPRESS_MAP_NAME(srcfilter));
212 UNSUPPRESS_MAP(dstfilter) = UNSUPPRESS_MAP(srcfilter);
213 }
214
215 if (ADVERTISE_MAP_NAME(srcfilter)) {
216 ADVERTISE_MAP_NAME(dstfilter) = XSTRDUP(
217 MTYPE_BGP_FILTER_NAME, ADVERTISE_MAP_NAME(srcfilter));
218 ADVERTISE_MAP(dstfilter) = ADVERTISE_MAP(srcfilter);
219 ADVERTISE_CONDITION(dstfilter) = ADVERTISE_CONDITION(srcfilter);
220 }
221
222 if (CONDITION_MAP_NAME(srcfilter)) {
223 CONDITION_MAP_NAME(dstfilter) = XSTRDUP(
224 MTYPE_BGP_FILTER_NAME, CONDITION_MAP_NAME(srcfilter));
225 CONDITION_MAP(dstfilter) = CONDITION_MAP(srcfilter);
226 }
227
228 dstfilter->advmap.update_type = srcfilter->advmap.update_type;
229 }
230
231 /**
232 * since we did a bunch of XSTRDUP's in conf_copy, time to free them up
233 */
234 static void conf_release(struct peer *src, afi_t afi, safi_t safi)
235 {
236 struct bgp_filter *srcfilter;
237
238 srcfilter = &src->filter[afi][safi];
239
240 XFREE(MTYPE_ROUTE_MAP_NAME, src->default_rmap[afi][safi].name);
241
242 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->dlist[FILTER_OUT].name);
243
244 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->plist[FILTER_OUT].name);
245
246 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->aslist[FILTER_OUT].name);
247
248 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->map[RMAP_OUT].name);
249
250 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->usmap.name);
251
252 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.aname);
253
254 XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.cname);
255
256 XFREE(MTYPE_BGP_PEER_HOST, src->host);
257 }
258
259 static void peer2_updgrp_copy(struct update_group *updgrp, struct peer_af *paf)
260 {
261 struct peer *src;
262 struct peer *dst;
263
264 if (!updgrp || !paf)
265 return;
266
267 src = paf->peer;
268 dst = updgrp->conf;
269 if (!src || !dst)
270 return;
271
272 updgrp->afi = paf->afi;
273 updgrp->safi = paf->safi;
274 updgrp->afid = paf->afid;
275 updgrp->bgp = src->bgp;
276
277 conf_copy(dst, src, paf->afi, paf->safi);
278 }
279
280 /**
281 * auxiliary functions to maintain the hash table.
282 * - updgrp_hash_alloc - to create a new entry, passed to hash_get
283 * - updgrp_hash_key_make - makes the key for update group search
284 * - updgrp_hash_cmp - compare two update groups.
285 */
286 static void *updgrp_hash_alloc(void *p)
287 {
288 struct update_group *updgrp;
289 const struct update_group *in;
290
291 in = (const struct update_group *)p;
292 updgrp = XCALLOC(MTYPE_BGP_UPDGRP, sizeof(struct update_group));
293 memcpy(updgrp, in, sizeof(struct update_group));
294 updgrp->conf = XCALLOC(MTYPE_BGP_PEER, sizeof(struct peer));
295 conf_copy(updgrp->conf, in->conf, in->afi, in->safi);
296 return updgrp;
297 }
298
299 /**
300 * The hash value for a peer is computed from the following variables:
301 * v = f(
302 * 1. IBGP (1) or EBGP (2)
303 * 2. FLAGS based on configuration:
304 * LOCAL_AS_NO_PREPEND
305 * LOCAL_AS_REPLACE_AS
306 * 3. AF_FLAGS based on configuration:
307 * Refer to definition in bgp_updgrp.h
308 * 4. (AF-independent) Capability flags:
309 * AS4_RCV capability
310 * 5. (AF-dependent) Capability flags:
311 * ORF_PREFIX_SM_RCV (peer can send prefix ORF)
312 * 6. MRAI
313 * 7. peer-group name
314 * 8. Outbound route-map name (neighbor route-map <> out)
315 * 9. Outbound distribute-list name (neighbor distribute-list <> out)
316 * 10. Outbound prefix-list name (neighbor prefix-list <> out)
317 * 11. Outbound as-list name (neighbor filter-list <> out)
318 * 12. Unsuppress map name (neighbor unsuppress-map <>)
319 * 13. default rmap name (neighbor default-originate route-map <>)
320 * 14. encoding both global and link-local nexthop?
321 * 15. If peer is configured to be a lonesoul, peer ip address
322 * 16. Local-as should match, if configured.
323 * 17. maximum-prefix-out
324 * 18. Local-role should also match, if configured.
325 * )
326 */
327 static unsigned int updgrp_hash_key_make(const void *p)
328 {
329 const struct update_group *updgrp;
330 const struct peer *peer;
331 const struct bgp_filter *filter;
332 uint32_t flags;
333 uint32_t key;
334 afi_t afi;
335 safi_t safi;
336
337 #define SEED1 999331
338 #define SEED2 2147483647
339
340 updgrp = p;
341 peer = updgrp->conf;
342 afi = updgrp->afi;
343 safi = updgrp->safi;
344 flags = peer->af_flags[afi][safi];
345 filter = &peer->filter[afi][safi];
346
347 key = 0;
348
349 key = jhash_1word(peer->sort, key); /* EBGP or IBGP */
350 key = jhash_1word((peer->flags & PEER_UPDGRP_FLAGS), key);
351 key = jhash_1word((flags & PEER_UPDGRP_AF_FLAGS), key);
352 key = jhash_1word((uint32_t)peer->addpath_type[afi][safi], key);
353 key = jhash_1word((peer->cap & PEER_UPDGRP_CAP_FLAGS), key);
354 key = jhash_1word((peer->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS),
355 key);
356 key = jhash_1word(peer->v_routeadv, key);
357 key = jhash_1word(peer->change_local_as, key);
358 key = jhash_1word(peer->max_packet_size, key);
359 key = jhash_1word(peer->pmax_out[afi][safi], key);
360
361 if (peer->group)
362 key = jhash_1word(jhash(peer->group->name,
363 strlen(peer->group->name), SEED1),
364 key);
365
366 if (filter->map[RMAP_OUT].name)
367 key = jhash_1word(jhash(filter->map[RMAP_OUT].name,
368 strlen(filter->map[RMAP_OUT].name),
369 SEED1),
370 key);
371
372 if (filter->dlist[FILTER_OUT].name)
373 key = jhash_1word(jhash(filter->dlist[FILTER_OUT].name,
374 strlen(filter->dlist[FILTER_OUT].name),
375 SEED1),
376 key);
377
378 if (filter->plist[FILTER_OUT].name)
379 key = jhash_1word(jhash(filter->plist[FILTER_OUT].name,
380 strlen(filter->plist[FILTER_OUT].name),
381 SEED1),
382 key);
383
384 if (filter->aslist[FILTER_OUT].name)
385 key = jhash_1word(jhash(filter->aslist[FILTER_OUT].name,
386 strlen(filter->aslist[FILTER_OUT].name),
387 SEED1),
388 key);
389
390 if (filter->usmap.name)
391 key = jhash_1word(jhash(filter->usmap.name,
392 strlen(filter->usmap.name), SEED1),
393 key);
394
395 if (filter->advmap.aname)
396 key = jhash_1word(jhash(filter->advmap.aname,
397 strlen(filter->advmap.aname), SEED1),
398 key);
399
400 if (filter->advmap.update_type)
401 key = jhash_1word(filter->advmap.update_type, key);
402
403 if (peer->default_rmap[afi][safi].name)
404 key = jhash_1word(
405 jhash(peer->default_rmap[afi][safi].name,
406 strlen(peer->default_rmap[afi][safi].name),
407 SEED1),
408 key);
409
410 /* If peer is on a shared network and is exchanging IPv6 prefixes,
411 * it needs to include link-local address. That's different from
412 * non-shared-network peers (nexthop encoded with 32 bytes vs 16
413 * bytes). We create different update groups to take care of that.
414 */
415 key = jhash_1word(
416 (peer->shared_network && peer_afi_active_nego(peer, AFI_IP6)),
417 key);
418 /*
419 * There are certain peers that must get their own update-group:
420 * - lonesoul peers
421 * - peers that negotiated ORF
422 * - maximum-prefix-out is set
423 */
424 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)
425 || CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
426 || CHECK_FLAG(peer->af_cap[afi][safi],
427 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)
428 || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT))
429 key = jhash_1word(jhash(peer->host, strlen(peer->host), SEED2),
430 key);
431 /*
432 * Multiple sessions with the same neighbor should get their own
433 * update-group if they have different roles.
434 */
435 key = jhash_1word(peer->local_role, key);
436
437 if (peer->soo[afi][safi]) {
438 char *soo_str = ecommunity_str(peer->soo[afi][safi]);
439
440 key = jhash_1word(jhash(soo_str, strlen(soo_str), SEED1), key);
441 }
442
443 if (bgp_debug_neighbor_events(peer)) {
444 zlog_debug(
445 "%pBP Update Group Hash: sort: %d UpdGrpFlags: %ju UpdGrpAFFlags: %ju",
446 peer, peer->sort,
447 (intmax_t)CHECK_FLAG(peer->flags, PEER_UPDGRP_FLAGS),
448 (intmax_t)CHECK_FLAG(flags, PEER_UPDGRP_AF_FLAGS));
449 zlog_debug(
450 "%pBP Update Group Hash: addpath: %u UpdGrpCapFlag: %u UpdGrpCapAFFlag: %u route_adv: %u change local as: %u",
451 peer, (uint32_t)peer->addpath_type[afi][safi],
452 CHECK_FLAG(peer->cap, PEER_UPDGRP_CAP_FLAGS),
453 CHECK_FLAG(peer->af_cap[afi][safi],
454 PEER_UPDGRP_AF_CAP_FLAGS),
455 peer->v_routeadv, peer->change_local_as);
456 zlog_debug(
457 "%pBP Update Group Hash: max packet size: %u pmax_out: %u Peer Group: %s rmap out: %s",
458 peer, peer->max_packet_size, peer->pmax_out[afi][safi],
459 peer->group ? peer->group->name : "(NONE)",
460 ROUTE_MAP_OUT_NAME(filter) ? ROUTE_MAP_OUT_NAME(filter)
461 : "(NONE)");
462 zlog_debug(
463 "%pBP Update Group Hash: dlist out: %s plist out: %s aslist out: %s usmap out: %s advmap: %s",
464 peer,
465 DISTRIBUTE_OUT_NAME(filter)
466 ? DISTRIBUTE_OUT_NAME(filter)
467 : "(NONE)",
468 PREFIX_LIST_OUT_NAME(filter)
469 ? PREFIX_LIST_OUT_NAME(filter)
470 : "(NONE)",
471 FILTER_LIST_OUT_NAME(filter)
472 ? FILTER_LIST_OUT_NAME(filter)
473 : "(NONE)",
474 UNSUPPRESS_MAP_NAME(filter)
475 ? UNSUPPRESS_MAP_NAME(filter)
476 : "(NONE)",
477 ADVERTISE_MAP_NAME(filter) ? ADVERTISE_MAP_NAME(filter)
478 : "(NONE)");
479 zlog_debug(
480 "%pBP Update Group Hash: default rmap: %s shared network and afi active network: %d",
481 peer,
482 peer->default_rmap[afi][safi].name
483 ? peer->default_rmap[afi][safi].name
484 : "(NONE)",
485 peer->shared_network &&
486 peer_afi_active_nego(peer, AFI_IP6));
487 zlog_debug(
488 "%pBP Update Group Hash: Lonesoul: %d ORF prefix: %u ORF old: %u max prefix out: %ju",
489 peer, !!CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL),
490 CHECK_FLAG(peer->af_cap[afi][safi],
491 PEER_CAP_ORF_PREFIX_SM_RCV),
492 CHECK_FLAG(peer->af_cap[afi][safi],
493 PEER_CAP_ORF_PREFIX_SM_OLD_RCV),
494 (intmax_t)CHECK_FLAG(peer->af_flags[afi][safi],
495 PEER_FLAG_MAX_PREFIX_OUT));
496 zlog_debug("%pBP Update Group Hash key: %u", peer, key);
497 }
498 return key;
499 }
500
501 static bool updgrp_hash_cmp(const void *p1, const void *p2)
502 {
503 const struct update_group *grp1;
504 const struct update_group *grp2;
505 const struct peer *pe1;
506 const struct peer *pe2;
507 uint32_t flags1;
508 uint32_t flags2;
509 const struct bgp_filter *fl1;
510 const struct bgp_filter *fl2;
511 afi_t afi;
512 safi_t safi;
513
514 if (!p1 || !p2)
515 return false;
516
517 grp1 = p1;
518 grp2 = p2;
519 pe1 = grp1->conf;
520 pe2 = grp2->conf;
521 afi = grp1->afi;
522 safi = grp1->safi;
523 flags1 = pe1->af_flags[afi][safi];
524 flags2 = pe2->af_flags[afi][safi];
525 fl1 = &pe1->filter[afi][safi];
526 fl2 = &pe2->filter[afi][safi];
527
528 /* put EBGP and IBGP peers in different update groups */
529 if (pe1->sort != pe2->sort)
530 return false;
531
532 /* check peer flags */
533 if ((pe1->flags & PEER_UPDGRP_FLAGS)
534 != (pe2->flags & PEER_UPDGRP_FLAGS))
535 return false;
536
537 /* If there is 'local-as' configured, it should match. */
538 if (pe1->change_local_as != pe2->change_local_as)
539 return false;
540
541 if (pe1->pmax_out[afi][safi] != pe2->pmax_out[afi][safi])
542 return false;
543
544 /* flags like route reflector client */
545 if ((flags1 & PEER_UPDGRP_AF_FLAGS) != (flags2 & PEER_UPDGRP_AF_FLAGS))
546 return false;
547
548 if (pe1->addpath_type[afi][safi] != pe2->addpath_type[afi][safi])
549 return false;
550
551 if ((pe1->cap & PEER_UPDGRP_CAP_FLAGS)
552 != (pe2->cap & PEER_UPDGRP_CAP_FLAGS))
553 return false;
554
555 if ((pe1->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS)
556 != (pe2->af_cap[afi][safi] & PEER_UPDGRP_AF_CAP_FLAGS))
557 return false;
558
559 if (pe1->v_routeadv != pe2->v_routeadv)
560 return false;
561
562 if (pe1->group != pe2->group)
563 return false;
564
565 /* Roles can affect filtering */
566 if (pe1->local_role != pe2->local_role)
567 return false;
568
569 /* route-map names should be the same */
570 if ((fl1->map[RMAP_OUT].name && !fl2->map[RMAP_OUT].name)
571 || (!fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name)
572 || (fl1->map[RMAP_OUT].name && fl2->map[RMAP_OUT].name
573 && strcmp(fl1->map[RMAP_OUT].name, fl2->map[RMAP_OUT].name)))
574 return false;
575
576 if ((fl1->dlist[FILTER_OUT].name && !fl2->dlist[FILTER_OUT].name)
577 || (!fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name)
578 || (fl1->dlist[FILTER_OUT].name && fl2->dlist[FILTER_OUT].name
579 && strcmp(fl1->dlist[FILTER_OUT].name,
580 fl2->dlist[FILTER_OUT].name)))
581 return false;
582
583 if ((fl1->plist[FILTER_OUT].name && !fl2->plist[FILTER_OUT].name)
584 || (!fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name)
585 || (fl1->plist[FILTER_OUT].name && fl2->plist[FILTER_OUT].name
586 && strcmp(fl1->plist[FILTER_OUT].name,
587 fl2->plist[FILTER_OUT].name)))
588 return false;
589
590 if ((fl1->aslist[FILTER_OUT].name && !fl2->aslist[FILTER_OUT].name)
591 || (!fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name)
592 || (fl1->aslist[FILTER_OUT].name && fl2->aslist[FILTER_OUT].name
593 && strcmp(fl1->aslist[FILTER_OUT].name,
594 fl2->aslist[FILTER_OUT].name)))
595 return false;
596
597 if ((fl1->usmap.name && !fl2->usmap.name)
598 || (!fl1->usmap.name && fl2->usmap.name)
599 || (fl1->usmap.name && fl2->usmap.name
600 && strcmp(fl1->usmap.name, fl2->usmap.name)))
601 return false;
602
603 if ((fl1->advmap.aname && !fl2->advmap.aname)
604 || (!fl1->advmap.aname && fl2->advmap.aname)
605 || (fl1->advmap.aname && fl2->advmap.aname
606 && strcmp(fl1->advmap.aname, fl2->advmap.aname)))
607 return false;
608
609 if (fl1->advmap.update_type != fl2->advmap.update_type)
610 return false;
611
612 if ((pe1->default_rmap[afi][safi].name
613 && !pe2->default_rmap[afi][safi].name)
614 || (!pe1->default_rmap[afi][safi].name
615 && pe2->default_rmap[afi][safi].name)
616 || (pe1->default_rmap[afi][safi].name
617 && pe2->default_rmap[afi][safi].name
618 && strcmp(pe1->default_rmap[afi][safi].name,
619 pe2->default_rmap[afi][safi].name)))
620 return false;
621
622 if ((afi == AFI_IP6) && (pe1->shared_network != pe2->shared_network))
623 return false;
624
625 if ((CHECK_FLAG(pe1->flags, PEER_FLAG_LONESOUL)
626 || CHECK_FLAG(pe1->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
627 || CHECK_FLAG(pe1->af_cap[afi][safi],
628 PEER_CAP_ORF_PREFIX_SM_OLD_RCV))
629 && !sockunion_same(&pe1->su, &pe2->su))
630 return false;
631
632 return true;
633 }
634
635 static void peer_lonesoul_or_not(struct peer *peer, int set)
636 {
637 /* no change in status? */
638 if (set == (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL) > 0))
639 return;
640
641 if (set)
642 SET_FLAG(peer->flags, PEER_FLAG_LONESOUL);
643 else
644 UNSET_FLAG(peer->flags, PEER_FLAG_LONESOUL);
645
646 update_group_adjust_peer_afs(peer);
647 }
648
649 /*
650 * subgroup_total_packets_enqueued
651 *
652 * Returns the total number of packets enqueued to a subgroup.
653 */
654 static unsigned int
655 subgroup_total_packets_enqueued(struct update_subgroup *subgrp)
656 {
657 struct bpacket *pkt;
658
659 pkt = bpacket_queue_last(SUBGRP_PKTQ(subgrp));
660
661 return pkt->ver - 1;
662 }
663
664 static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
665 {
666 struct updwalk_context *ctx = arg;
667 struct vty *vty;
668 struct update_subgroup *subgrp;
669 struct peer_af *paf;
670 struct bgp_filter *filter;
671 struct peer *peer = UPDGRP_PEER(updgrp);
672 int match = 0;
673
674 if (!ctx)
675 return CMD_SUCCESS;
676
677 if (ctx->subgrp_id) {
678 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
679 if (ctx->subgrp_id && (ctx->subgrp_id != subgrp->id))
680 continue;
681 else {
682 match = 1;
683 break;
684 }
685 }
686 } else {
687 match = 1;
688 }
689
690 if (!match) {
691 /* Since this routine is invoked from a walk, we cannot signal
692 * any */
693 /* error here, can only return. */
694 return CMD_SUCCESS;
695 }
696
697 vty = ctx->vty;
698
699 vty_out(vty, "Update-group %" PRIu64 ":\n", updgrp->id);
700 vty_out(vty, " Created: %s", timestamp_string(updgrp->uptime));
701 filter = &updgrp->conf->filter[updgrp->afi][updgrp->safi];
702 if (filter->map[RMAP_OUT].name)
703 vty_out(vty, " Outgoing route map: %s\n",
704 filter->map[RMAP_OUT].name);
705 vty_out(vty, " MRAI value (seconds): %d\n", updgrp->conf->v_routeadv);
706 if (updgrp->conf->change_local_as)
707 vty_out(vty, " Local AS %u%s%s\n",
708 updgrp->conf->change_local_as,
709 CHECK_FLAG(updgrp->conf->flags,
710 PEER_FLAG_LOCAL_AS_NO_PREPEND)
711 ? " no-prepend"
712 : "",
713 CHECK_FLAG(updgrp->conf->flags,
714 PEER_FLAG_LOCAL_AS_REPLACE_AS)
715 ? " replace-as"
716 : "");
717
718 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
719 if (ctx->subgrp_id && (ctx->subgrp_id != subgrp->id))
720 continue;
721 vty_out(vty, "\n");
722 vty_out(vty, " Update-subgroup %" PRIu64 ":\n", subgrp->id);
723 vty_out(vty, " Created: %s",
724 timestamp_string(subgrp->uptime));
725
726 if (subgrp->split_from.update_group_id
727 || subgrp->split_from.subgroup_id) {
728 vty_out(vty, " Split from group id: %" PRIu64 "\n",
729 subgrp->split_from.update_group_id);
730 vty_out(vty,
731 " Split from subgroup id: %" PRIu64 "\n",
732 subgrp->split_from.subgroup_id);
733 }
734
735 vty_out(vty, " Join events: %u\n", subgrp->join_events);
736 vty_out(vty, " Prune events: %u\n", subgrp->prune_events);
737 vty_out(vty, " Merge events: %u\n", subgrp->merge_events);
738 vty_out(vty, " Split events: %u\n", subgrp->split_events);
739 vty_out(vty, " Update group switch events: %u\n",
740 subgrp->updgrp_switch_events);
741 vty_out(vty, " Peer refreshes combined: %u\n",
742 subgrp->peer_refreshes_combined);
743 vty_out(vty, " Merge checks triggered: %u\n",
744 subgrp->merge_checks_triggered);
745 vty_out(vty, " Coalesce Time: %u%s\n",
746 (UPDGRP_INST(subgrp->update_group))->coalesce_time,
747 subgrp->t_coalesce ? "(Running)" : "");
748 vty_out(vty, " Version: %" PRIu64 "\n", subgrp->version);
749 vty_out(vty, " Packet queue length: %d\n",
750 bpacket_queue_length(SUBGRP_PKTQ(subgrp)));
751 vty_out(vty, " Total packets enqueued: %u\n",
752 subgroup_total_packets_enqueued(subgrp));
753 vty_out(vty, " Packet queue high watermark: %d\n",
754 bpacket_queue_hwm_length(SUBGRP_PKTQ(subgrp)));
755 vty_out(vty, " Adj-out list count: %u\n", subgrp->adj_count);
756 vty_out(vty, " Advertise list: %s\n",
757 advertise_list_is_empty(subgrp) ? "empty"
758 : "not empty");
759 vty_out(vty, " Flags: %s\n",
760 CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH)
761 ? "R"
762 : "");
763 if (peer)
764 vty_out(vty, " Max packet size: %d\n",
765 peer->max_packet_size);
766 if (subgrp->peer_count > 0) {
767 vty_out(vty, " Peers:\n");
768 SUBGRP_FOREACH_PEER (subgrp, paf)
769 vty_out(vty, " - %s\n", paf->peer->host);
770 }
771 }
772 return UPDWALK_CONTINUE;
773 }
774
775 /*
776 * Helper function to show the packet queue for each subgroup of update group.
777 * Will be constrained to a particular subgroup id if id !=0
778 */
779 static int updgrp_show_packet_queue_walkcb(struct update_group *updgrp,
780 void *arg)
781 {
782 struct updwalk_context *ctx = arg;
783 struct update_subgroup *subgrp;
784 struct vty *vty;
785
786 vty = ctx->vty;
787 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
788 if (ctx->subgrp_id && (ctx->subgrp_id != subgrp->id))
789 continue;
790 vty_out(vty, "update group %" PRIu64 ", subgroup %" PRIu64 "\n",
791 updgrp->id, subgrp->id);
792 bpacket_queue_show_vty(SUBGRP_PKTQ(subgrp), vty);
793 }
794 return UPDWALK_CONTINUE;
795 }
796
797 /*
798 * Show the packet queue for each subgroup of update group. Will be
799 * constrained to a particular subgroup id if id !=0
800 */
801 void update_group_show_packet_queue(struct bgp *bgp, afi_t afi, safi_t safi,
802 struct vty *vty, uint64_t id)
803 {
804 struct updwalk_context ctx;
805
806 memset(&ctx, 0, sizeof(ctx));
807 ctx.vty = vty;
808 ctx.subgrp_id = id;
809 ctx.flags = 0;
810 update_group_af_walk(bgp, afi, safi, updgrp_show_packet_queue_walkcb,
811 &ctx);
812 }
813
814 static struct update_group *update_group_find(struct peer_af *paf)
815 {
816 struct update_group *updgrp;
817 struct update_group tmp;
818 struct peer tmp_conf;
819
820 if (!peer_established(PAF_PEER(paf)))
821 return NULL;
822
823 memset(&tmp, 0, sizeof(tmp));
824 memset(&tmp_conf, 0, sizeof(tmp_conf));
825 tmp.conf = &tmp_conf;
826 peer2_updgrp_copy(&tmp, paf);
827
828 updgrp = hash_lookup(paf->peer->bgp->update_groups[paf->afid], &tmp);
829 conf_release(&tmp_conf, paf->afi, paf->safi);
830 return updgrp;
831 }
832
833 static struct update_group *update_group_create(struct peer_af *paf)
834 {
835 struct update_group *updgrp;
836 struct update_group tmp;
837 struct peer tmp_conf;
838
839 memset(&tmp, 0, sizeof(tmp));
840 memset(&tmp_conf, 0, sizeof(tmp_conf));
841 tmp.conf = &tmp_conf;
842 peer2_updgrp_copy(&tmp, paf);
843
844 updgrp = hash_get(paf->peer->bgp->update_groups[paf->afid], &tmp,
845 updgrp_hash_alloc);
846 update_group_checkin(updgrp);
847
848 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
849 zlog_debug("create update group %" PRIu64, updgrp->id);
850
851 UPDGRP_GLOBAL_STAT(updgrp, updgrps_created) += 1;
852
853 conf_release(&tmp_conf, paf->afi, paf->safi);
854 return updgrp;
855 }
856
857 static void update_group_delete(struct update_group *updgrp)
858 {
859 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
860 zlog_debug("delete update group %" PRIu64, updgrp->id);
861
862 UPDGRP_GLOBAL_STAT(updgrp, updgrps_deleted) += 1;
863
864 hash_release(updgrp->bgp->update_groups[updgrp->afid], updgrp);
865 conf_release(updgrp->conf, updgrp->afi, updgrp->safi);
866
867 XFREE(MTYPE_BGP_PEER_HOST, updgrp->conf->host);
868
869 XFREE(MTYPE_BGP_PEER_IFNAME, updgrp->conf->ifname);
870
871 XFREE(MTYPE_BGP_PEER, updgrp->conf);
872 XFREE(MTYPE_BGP_UPDGRP, updgrp);
873 }
874
875 static void update_group_add_subgroup(struct update_group *updgrp,
876 struct update_subgroup *subgrp)
877 {
878 if (!updgrp || !subgrp)
879 return;
880
881 LIST_INSERT_HEAD(&(updgrp->subgrps), subgrp, updgrp_train);
882 subgrp->update_group = updgrp;
883 }
884
885 static void update_group_remove_subgroup(struct update_group *updgrp,
886 struct update_subgroup *subgrp)
887 {
888 if (!updgrp || !subgrp)
889 return;
890
891 LIST_REMOVE(subgrp, updgrp_train);
892 subgrp->update_group = NULL;
893 if (LIST_EMPTY(&(updgrp->subgrps)))
894 update_group_delete(updgrp);
895 }
896
897 static struct update_subgroup *
898 update_subgroup_create(struct update_group *updgrp)
899 {
900 struct update_subgroup *subgrp;
901
902 subgrp = XCALLOC(MTYPE_BGP_UPD_SUBGRP, sizeof(struct update_subgroup));
903 update_subgroup_checkin(subgrp, updgrp);
904 subgrp->v_coalesce = (UPDGRP_INST(updgrp))->coalesce_time;
905 sync_init(subgrp, updgrp);
906 bpacket_queue_init(SUBGRP_PKTQ(subgrp));
907 bpacket_queue_add(SUBGRP_PKTQ(subgrp), NULL, NULL);
908 TAILQ_INIT(&(subgrp->adjq));
909 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
910 zlog_debug("create subgroup u%" PRIu64 ":s%" PRIu64, updgrp->id,
911 subgrp->id);
912
913 update_group_add_subgroup(updgrp, subgrp);
914
915 UPDGRP_INCR_STAT(updgrp, subgrps_created);
916
917 return subgrp;
918 }
919
920 static void update_subgroup_delete(struct update_subgroup *subgrp)
921 {
922 if (!subgrp)
923 return;
924
925 if (subgrp->update_group)
926 UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted);
927
928 THREAD_OFF(subgrp->t_merge_check);
929 THREAD_OFF(subgrp->t_coalesce);
930
931 bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp));
932 subgroup_clear_table(subgrp);
933
934 sync_delete(subgrp);
935
936 if (BGP_DEBUG(update_groups, UPDATE_GROUPS) && subgrp->update_group)
937 zlog_debug("delete subgroup u%" PRIu64 ":s%" PRIu64,
938 subgrp->update_group->id, subgrp->id);
939
940 update_group_remove_subgroup(subgrp->update_group, subgrp);
941
942 XFREE(MTYPE_BGP_UPD_SUBGRP, subgrp);
943 }
944
945 void update_subgroup_inherit_info(struct update_subgroup *to,
946 struct update_subgroup *from)
947 {
948 if (!to || !from)
949 return;
950
951 to->sflags = from->sflags;
952 }
953
954 /*
955 * update_subgroup_check_delete
956 *
957 * Delete a subgroup if it is ready to be deleted.
958 *
959 * Returns true if the subgroup was deleted.
960 */
961 static bool update_subgroup_check_delete(struct update_subgroup *subgrp)
962 {
963 if (!subgrp)
964 return false;
965
966 if (!LIST_EMPTY(&(subgrp->peers)))
967 return false;
968
969 update_subgroup_delete(subgrp);
970
971 return true;
972 }
973
974 /*
975 * update_subgroup_add_peer
976 *
977 * @param send_enqueued_packets If true all currently enqueued packets will
978 * also be sent to the peer.
979 */
980 static void update_subgroup_add_peer(struct update_subgroup *subgrp,
981 struct peer_af *paf,
982 int send_enqueued_pkts)
983 {
984 struct bpacket *pkt;
985
986 if (!subgrp || !paf)
987 return;
988
989 LIST_INSERT_HEAD(&(subgrp->peers), paf, subgrp_train);
990 paf->subgroup = subgrp;
991 subgrp->peer_count++;
992
993 if (bgp_debug_peer_updout_enabled(paf->peer->host)) {
994 UPDGRP_PEER_DBG_EN(subgrp->update_group);
995 }
996
997 SUBGRP_INCR_STAT(subgrp, join_events);
998
999 if (send_enqueued_pkts) {
1000 pkt = bpacket_queue_first(SUBGRP_PKTQ(subgrp));
1001 } else {
1002
1003 /*
1004 * Hang the peer off of the last, placeholder, packet in the
1005 * queue. This means it won't see any of the packets that are
1006 * currently the queue.
1007 */
1008 pkt = bpacket_queue_last(SUBGRP_PKTQ(subgrp));
1009 assert(pkt->buffer == NULL);
1010 }
1011
1012 bpacket_add_peer(pkt, paf);
1013
1014 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1015 zlog_debug("peer %s added to subgroup s%" PRIu64,
1016 paf->peer->host, subgrp->id);
1017 }
1018
1019 /*
1020 * update_subgroup_remove_peer_internal
1021 *
1022 * Internal function that removes a peer from a subgroup, but does not
1023 * delete the subgroup. A call to this function must almost always be
1024 * followed by a call to update_subgroup_check_delete().
1025 *
1026 * @see update_subgroup_remove_peer
1027 */
1028 static void update_subgroup_remove_peer_internal(struct update_subgroup *subgrp,
1029 struct peer_af *paf)
1030 {
1031 assert(subgrp && paf && subgrp->update_group);
1032
1033 if (bgp_debug_peer_updout_enabled(paf->peer->host)) {
1034 UPDGRP_PEER_DBG_DIS(subgrp->update_group);
1035 }
1036
1037 bpacket_queue_remove_peer(paf);
1038 LIST_REMOVE(paf, subgrp_train);
1039 paf->subgroup = NULL;
1040 subgrp->peer_count--;
1041
1042 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1043 zlog_debug("peer %s deleted from subgroup s%"
1044 PRIu64 " peer cnt %d",
1045 paf->peer->host, subgrp->id, subgrp->peer_count);
1046 SUBGRP_INCR_STAT(subgrp, prune_events);
1047 }
1048
1049 /*
1050 * update_subgroup_remove_peer
1051 */
1052 void update_subgroup_remove_peer(struct update_subgroup *subgrp,
1053 struct peer_af *paf)
1054 {
1055 if (!subgrp || !paf)
1056 return;
1057
1058 update_subgroup_remove_peer_internal(subgrp, paf);
1059
1060 if (update_subgroup_check_delete(subgrp))
1061 return;
1062
1063 /*
1064 * The deletion of the peer may have caused some packets to be
1065 * deleted from the subgroup packet queue. Check if the subgroup can
1066 * be merged now.
1067 */
1068 update_subgroup_check_merge(subgrp, "removed peer from subgroup");
1069 }
1070
1071 static struct update_subgroup *update_subgroup_find(struct update_group *updgrp,
1072 struct peer_af *paf)
1073 {
1074 struct update_subgroup *subgrp = NULL;
1075 uint64_t version;
1076
1077 if (paf->subgroup) {
1078 assert(0);
1079 return NULL;
1080 } else
1081 version = 0;
1082
1083 if (!peer_established(PAF_PEER(paf)))
1084 return NULL;
1085
1086 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
1087 if (subgrp->version != version
1088 || CHECK_FLAG(subgrp->sflags,
1089 SUBGRP_STATUS_DEFAULT_ORIGINATE))
1090 continue;
1091
1092 /*
1093 * The version number is not meaningful on a subgroup that needs
1094 * a refresh.
1095 */
1096 if (update_subgroup_needs_refresh(subgrp))
1097 continue;
1098
1099 break;
1100 }
1101
1102 return subgrp;
1103 }
1104
1105 /*
1106 * update_subgroup_ready_for_merge
1107 *
1108 * Returns true if this subgroup is in a state that allows it to be
1109 * merged into another subgroup.
1110 */
1111 static bool update_subgroup_ready_for_merge(struct update_subgroup *subgrp)
1112 {
1113
1114 /*
1115 * Not ready if there are any encoded packets waiting to be written
1116 * out to peers.
1117 */
1118 if (!bpacket_queue_is_empty(SUBGRP_PKTQ(subgrp)))
1119 return false;
1120
1121 /*
1122 * Not ready if there enqueued updates waiting to be encoded.
1123 */
1124 if (!advertise_list_is_empty(subgrp))
1125 return false;
1126
1127 /*
1128 * Don't attempt to merge a subgroup that needs a refresh. For one,
1129 * we can't determine if the adj_out of such a group matches that of
1130 * another group.
1131 */
1132 if (update_subgroup_needs_refresh(subgrp))
1133 return false;
1134
1135 return true;
1136 }
1137
1138 /*
1139 * update_subgrp_can_merge_into
1140 *
1141 * Returns true if the first subgroup can merge into the second
1142 * subgroup.
1143 */
1144 static int update_subgroup_can_merge_into(struct update_subgroup *subgrp,
1145 struct update_subgroup *target)
1146 {
1147
1148 if (subgrp == target)
1149 return 0;
1150
1151 /*
1152 * Both must have processed the BRIB to the same point in order to
1153 * be merged.
1154 */
1155 if (subgrp->version != target->version)
1156 return 0;
1157
1158 if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)
1159 != CHECK_FLAG(target->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
1160 return 0;
1161
1162 if (subgrp->adj_count != target->adj_count)
1163 return 0;
1164
1165 return update_subgroup_ready_for_merge(target);
1166 }
1167
1168 /*
1169 * update_subgroup_merge
1170 *
1171 * Merge the first subgroup into the second one.
1172 */
1173 static void update_subgroup_merge(struct update_subgroup *subgrp,
1174 struct update_subgroup *target,
1175 const char *reason)
1176 {
1177 struct peer_af *paf;
1178 int result;
1179 int peer_count;
1180
1181 assert(subgrp->adj_count == target->adj_count);
1182
1183 peer_count = subgrp->peer_count;
1184
1185 while (1) {
1186 paf = LIST_FIRST(&subgrp->peers);
1187 if (!paf)
1188 break;
1189
1190 update_subgroup_remove_peer_internal(subgrp, paf);
1191
1192 /*
1193 * Add the peer to the target subgroup, while making sure that
1194 * any currently enqueued packets won't be sent to it. Enqueued
1195 * packets could, for example, result in an unnecessary withdraw
1196 * followed by an advertise.
1197 */
1198 update_subgroup_add_peer(target, paf, 0);
1199 }
1200
1201 SUBGRP_INCR_STAT(target, merge_events);
1202
1203 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1204 zlog_debug("u%" PRIu64 ":s%" PRIu64" (%d peers) merged into u%" PRIu64 ":s%" PRIu64", trigger: %s",
1205 subgrp->update_group->id, subgrp->id, peer_count,
1206 target->update_group->id, target->id,
1207 reason ? reason : "unknown");
1208
1209 result = update_subgroup_check_delete(subgrp);
1210 assert(result);
1211 }
1212
1213 /*
1214 * update_subgroup_check_merge
1215 *
1216 * Merge this subgroup into another subgroup if possible.
1217 *
1218 * Returns true if the subgroup has been merged. The subgroup pointer
1219 * should not be accessed in this case.
1220 */
1221 bool update_subgroup_check_merge(struct update_subgroup *subgrp,
1222 const char *reason)
1223 {
1224 struct update_subgroup *target;
1225
1226 if (!update_subgroup_ready_for_merge(subgrp))
1227 return false;
1228
1229 /*
1230 * Look for a subgroup to merge into.
1231 */
1232 UPDGRP_FOREACH_SUBGRP (subgrp->update_group, target) {
1233 if (update_subgroup_can_merge_into(subgrp, target))
1234 break;
1235 }
1236
1237 if (!target)
1238 return false;
1239
1240 update_subgroup_merge(subgrp, target, reason);
1241 return true;
1242 }
1243
1244 /*
1245 * update_subgroup_merge_check_thread_cb
1246 */
1247 static void update_subgroup_merge_check_thread_cb(struct thread *thread)
1248 {
1249 struct update_subgroup *subgrp;
1250
1251 subgrp = THREAD_ARG(thread);
1252
1253 subgrp->t_merge_check = NULL;
1254
1255 update_subgroup_check_merge(subgrp, "triggered merge check");
1256 }
1257
1258 /*
1259 * update_subgroup_trigger_merge_check
1260 *
1261 * Triggers a call to update_subgroup_check_merge() on a clean context.
1262 *
1263 * @param force If true, the merge check will be triggered even if the
1264 * subgroup doesn't currently look ready for a merge.
1265 *
1266 * Returns true if a merge check will be performed shortly.
1267 */
1268 bool update_subgroup_trigger_merge_check(struct update_subgroup *subgrp,
1269 int force)
1270 {
1271 if (subgrp->t_merge_check)
1272 return true;
1273
1274 if (!force && !update_subgroup_ready_for_merge(subgrp))
1275 return false;
1276
1277 subgrp->t_merge_check = NULL;
1278 thread_add_timer_msec(bm->master, update_subgroup_merge_check_thread_cb,
1279 subgrp, 0, &subgrp->t_merge_check);
1280
1281 SUBGRP_INCR_STAT(subgrp, merge_checks_triggered);
1282
1283 return true;
1284 }
1285
1286 /*
1287 * update_subgroup_copy_adj_out
1288 *
1289 * Helper function that clones the adj out (state about advertised
1290 * routes) from one subgroup to another. It assumes that the adj out
1291 * of the target subgroup is empty.
1292 */
1293 static void update_subgroup_copy_adj_out(struct update_subgroup *source,
1294 struct update_subgroup *dest)
1295 {
1296 struct bgp_adj_out *aout, *aout_copy;
1297
1298 SUBGRP_FOREACH_ADJ (source, aout) {
1299 /*
1300 * Copy the adj out.
1301 */
1302 aout_copy = bgp_adj_out_alloc(dest, aout->dest,
1303 aout->addpath_tx_id);
1304 aout_copy->attr =
1305 aout->attr ? bgp_attr_intern(aout->attr) : NULL;
1306 }
1307
1308 dest->scount = source->scount;
1309 }
1310
1311 /*
1312 * update_subgroup_copy_packets
1313 *
1314 * Copy packets after and including the given packet to the subgroup
1315 * 'dest'.
1316 *
1317 * Returns the number of packets copied.
1318 */
1319 static int update_subgroup_copy_packets(struct update_subgroup *dest,
1320 struct bpacket *pkt)
1321 {
1322 int count;
1323
1324 count = 0;
1325 while (pkt && pkt->buffer) {
1326 bpacket_queue_add(SUBGRP_PKTQ(dest), stream_dup(pkt->buffer),
1327 &pkt->arr);
1328 count++;
1329 pkt = bpacket_next(pkt);
1330 }
1331
1332 return count;
1333 }
1334
1335 static bool updgrp_prefix_list_update(struct update_group *updgrp,
1336 const char *name)
1337 {
1338 struct peer *peer;
1339 struct bgp_filter *filter;
1340
1341 peer = UPDGRP_PEER(updgrp);
1342 filter = &peer->filter[UPDGRP_AFI(updgrp)][UPDGRP_SAFI(updgrp)];
1343
1344 if (PREFIX_LIST_OUT_NAME(filter)
1345 && (strcmp(name, PREFIX_LIST_OUT_NAME(filter)) == 0)) {
1346 PREFIX_LIST_OUT(filter) = prefix_list_lookup(
1347 UPDGRP_AFI(updgrp), PREFIX_LIST_OUT_NAME(filter));
1348 return true;
1349 }
1350 return false;
1351 }
1352
1353 static bool updgrp_filter_list_update(struct update_group *updgrp,
1354 const char *name)
1355 {
1356 struct peer *peer;
1357 struct bgp_filter *filter;
1358
1359 peer = UPDGRP_PEER(updgrp);
1360 filter = &peer->filter[UPDGRP_AFI(updgrp)][UPDGRP_SAFI(updgrp)];
1361
1362 if (FILTER_LIST_OUT_NAME(filter)
1363 && (strcmp(name, FILTER_LIST_OUT_NAME(filter)) == 0)) {
1364 FILTER_LIST_OUT(filter) =
1365 as_list_lookup(FILTER_LIST_OUT_NAME(filter));
1366 return true;
1367 }
1368 return false;
1369 }
1370
1371 static bool updgrp_distribute_list_update(struct update_group *updgrp,
1372 const char *name)
1373 {
1374 struct peer *peer;
1375 struct bgp_filter *filter;
1376
1377 peer = UPDGRP_PEER(updgrp);
1378 filter = &peer->filter[UPDGRP_AFI(updgrp)][UPDGRP_SAFI(updgrp)];
1379
1380 if (DISTRIBUTE_OUT_NAME(filter)
1381 && (strcmp(name, DISTRIBUTE_OUT_NAME(filter)) == 0)) {
1382 DISTRIBUTE_OUT(filter) = access_list_lookup(
1383 UPDGRP_AFI(updgrp), DISTRIBUTE_OUT_NAME(filter));
1384 return true;
1385 }
1386 return false;
1387 }
1388
1389 static int updgrp_route_map_update(struct update_group *updgrp,
1390 const char *name, int *def_rmap_changed)
1391 {
1392 struct peer *peer;
1393 struct bgp_filter *filter;
1394 int changed = 0;
1395 afi_t afi;
1396 safi_t safi;
1397
1398 peer = UPDGRP_PEER(updgrp);
1399 afi = UPDGRP_AFI(updgrp);
1400 safi = UPDGRP_SAFI(updgrp);
1401 filter = &peer->filter[afi][safi];
1402
1403 if (ROUTE_MAP_OUT_NAME(filter)
1404 && (strcmp(name, ROUTE_MAP_OUT_NAME(filter)) == 0)) {
1405 ROUTE_MAP_OUT(filter) = route_map_lookup_by_name(name);
1406
1407 changed = 1;
1408 }
1409
1410 if (UNSUPPRESS_MAP_NAME(filter)
1411 && (strcmp(name, UNSUPPRESS_MAP_NAME(filter)) == 0)) {
1412 UNSUPPRESS_MAP(filter) = route_map_lookup_by_name(name);
1413 changed = 1;
1414 }
1415
1416 /* process default-originate route-map */
1417 if (peer->default_rmap[afi][safi].name
1418 && (strcmp(name, peer->default_rmap[afi][safi].name) == 0)) {
1419 peer->default_rmap[afi][safi].map =
1420 route_map_lookup_by_name(name);
1421 if (def_rmap_changed)
1422 *def_rmap_changed = 1;
1423 }
1424 return changed;
1425 }
1426
1427 /*
1428 * hash iteration callback function to process a policy change for an
1429 * update group. Check if the changed policy matches the updgrp's
1430 * outbound route-map or unsuppress-map or default-originate map or
1431 * filter-list or prefix-list or distribute-list.
1432 * Trigger update generation accordingly.
1433 */
1434 static int updgrp_policy_update_walkcb(struct update_group *updgrp, void *arg)
1435 {
1436 struct updwalk_context *ctx = arg;
1437 struct update_subgroup *subgrp;
1438 int changed = 0;
1439 int def_changed = 0;
1440
1441 if (!updgrp || !ctx || !ctx->policy_name)
1442 return UPDWALK_CONTINUE;
1443
1444 switch (ctx->policy_type) {
1445 case BGP_POLICY_ROUTE_MAP:
1446 changed = updgrp_route_map_update(updgrp, ctx->policy_name,
1447 &def_changed);
1448 break;
1449 case BGP_POLICY_FILTER_LIST:
1450 changed = updgrp_filter_list_update(updgrp, ctx->policy_name);
1451 break;
1452 case BGP_POLICY_PREFIX_LIST:
1453 changed = updgrp_prefix_list_update(updgrp, ctx->policy_name);
1454 break;
1455 case BGP_POLICY_DISTRIBUTE_LIST:
1456 changed =
1457 updgrp_distribute_list_update(updgrp, ctx->policy_name);
1458 break;
1459 default:
1460 break;
1461 }
1462
1463 /* If not doing route update, return after updating "config" */
1464 if (!ctx->policy_route_update)
1465 return UPDWALK_CONTINUE;
1466
1467 /* If nothing has changed, return after updating "config" */
1468 if (!changed && !def_changed)
1469 return UPDWALK_CONTINUE;
1470
1471 /*
1472 * If something has changed, at the beginning of a route-map
1473 * modification
1474 * event, mark each subgroup's needs-refresh bit. For one, it signals to
1475 * whoever that the subgroup needs a refresh. Second, it prevents
1476 * premature
1477 * merge of this subgroup with another before a complete (outbound)
1478 * refresh.
1479 */
1480 if (ctx->policy_event_start_flag) {
1481 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
1482 update_subgroup_set_needs_refresh(subgrp, 1);
1483 }
1484 return UPDWALK_CONTINUE;
1485 }
1486
1487 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
1488 /* Avoid supressing duplicate routes later
1489 * when processing in subgroup_announce_table().
1490 */
1491 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
1492
1493 if (changed) {
1494 if (bgp_debug_update(NULL, NULL, updgrp, 0))
1495 zlog_debug(
1496 "u%" PRIu64 ":s%" PRIu64" announcing routes upon policy %s (type %d) change",
1497 updgrp->id, subgrp->id,
1498 ctx->policy_name, ctx->policy_type);
1499 subgroup_announce_route(subgrp);
1500 }
1501 if (def_changed) {
1502 if (bgp_debug_update(NULL, NULL, updgrp, 0))
1503 zlog_debug(
1504 "u%" PRIu64 ":s%" PRIu64" announcing default upon default routemap %s change",
1505 updgrp->id, subgrp->id,
1506 ctx->policy_name);
1507 if (route_map_lookup_by_name(ctx->policy_name)) {
1508 /*
1509 * When there is change in routemap, this flow
1510 * is triggered. the routemap is still present
1511 * in lib, hence its a update flow. The flag
1512 * needs to be unset.
1513 */
1514 UNSET_FLAG(subgrp->sflags,
1515 SUBGRP_STATUS_DEFAULT_ORIGINATE);
1516 subgroup_default_originate(subgrp, 0);
1517 } else {
1518 /*
1519 * This is a explicit withdraw, since the
1520 * routemap is not present in routemap lib. need
1521 * to pass 1 for withdraw arg.
1522 */
1523 subgroup_default_originate(subgrp, 1);
1524 }
1525 }
1526 update_subgroup_set_needs_refresh(subgrp, 0);
1527 }
1528 return UPDWALK_CONTINUE;
1529 }
1530
1531 static int update_group_walkcb(struct hash_bucket *bucket, void *arg)
1532 {
1533 struct update_group *updgrp = bucket->data;
1534 struct updwalk_context *wctx = arg;
1535 int ret = (*wctx->cb)(updgrp, wctx->context);
1536 return ret;
1537 }
1538
1539 static int update_group_periodic_merge_walkcb(struct update_group *updgrp,
1540 void *arg)
1541 {
1542 struct update_subgroup *subgrp;
1543 struct update_subgroup *tmp_subgrp;
1544 const char *reason = arg;
1545
1546 UPDGRP_FOREACH_SUBGRP_SAFE (updgrp, subgrp, tmp_subgrp)
1547 update_subgroup_check_merge(subgrp, reason);
1548 return UPDWALK_CONTINUE;
1549 }
1550
1551 /********************
1552 * PUBLIC FUNCTIONS
1553 ********************/
1554
1555 /*
1556 * trigger function when a policy (route-map/filter-list/prefix-list/
1557 * distribute-list etc.) content changes. Go through all the
1558 * update groups and process the change.
1559 *
1560 * bgp: the bgp instance
1561 * ptype: the type of policy that got modified, see bgpd.h
1562 * pname: name of the policy
1563 * route_update: flag to control if an automatic update generation should
1564 * occur
1565 * start_event: flag that indicates if it's the beginning of the change.
1566 * Esp. when the user is changing the content interactively
1567 * over multiple statements. Useful to set dirty flag on
1568 * update groups.
1569 */
1570 void update_group_policy_update(struct bgp *bgp, enum bgp_policy_type ptype,
1571 const char *pname, bool route_update,
1572 int start_event)
1573 {
1574 struct updwalk_context ctx;
1575
1576 memset(&ctx, 0, sizeof(ctx));
1577 ctx.policy_type = ptype;
1578 ctx.policy_name = pname;
1579 ctx.policy_route_update = route_update;
1580 ctx.policy_event_start_flag = start_event;
1581 ctx.flags = 0;
1582
1583 update_group_walk(bgp, updgrp_policy_update_walkcb, &ctx);
1584 }
1585
1586 /*
1587 * update_subgroup_split_peer
1588 *
1589 * Ensure that the given peer is in a subgroup of its own in the
1590 * specified update group.
1591 */
1592 void update_subgroup_split_peer(struct peer_af *paf,
1593 struct update_group *updgrp)
1594 {
1595 struct update_subgroup *old_subgrp, *subgrp;
1596 uint64_t old_id;
1597
1598
1599 old_subgrp = paf->subgroup;
1600
1601 if (!updgrp)
1602 updgrp = old_subgrp->update_group;
1603
1604 /*
1605 * If the peer is alone in its subgroup, reuse the existing
1606 * subgroup.
1607 */
1608 if (old_subgrp->peer_count == 1) {
1609 if (updgrp == old_subgrp->update_group)
1610 return;
1611
1612 subgrp = old_subgrp;
1613 old_id = old_subgrp->update_group->id;
1614
1615 if (bgp_debug_peer_updout_enabled(paf->peer->host)) {
1616 UPDGRP_PEER_DBG_DIS(old_subgrp->update_group);
1617 }
1618
1619 update_group_remove_subgroup(old_subgrp->update_group,
1620 old_subgrp);
1621 update_group_add_subgroup(updgrp, subgrp);
1622
1623 if (bgp_debug_peer_updout_enabled(paf->peer->host)) {
1624 UPDGRP_PEER_DBG_EN(updgrp);
1625 }
1626 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1627 zlog_debug("u%" PRIu64 ":s%" PRIu64" peer %s moved to u%" PRIu64 ":s%" PRIu64,
1628 old_id, subgrp->id, paf->peer->host,
1629 updgrp->id, subgrp->id);
1630
1631 /*
1632 * The state of the subgroup (adj_out, advs, packet queue etc)
1633 * is consistent internally, but may not be identical to other
1634 * subgroups in the new update group even if the version number
1635 * matches up. Make sure a full refresh is done before the
1636 * subgroup is merged with another.
1637 */
1638 update_subgroup_set_needs_refresh(subgrp, 1);
1639
1640 SUBGRP_INCR_STAT(subgrp, updgrp_switch_events);
1641 return;
1642 }
1643
1644 /*
1645 * Create a new subgroup under the specified update group, and copy
1646 * over relevant state to it.
1647 */
1648 subgrp = update_subgroup_create(updgrp);
1649 update_subgroup_inherit_info(subgrp, old_subgrp);
1650
1651 subgrp->split_from.update_group_id = old_subgrp->update_group->id;
1652 subgrp->split_from.subgroup_id = old_subgrp->id;
1653
1654 /*
1655 * Copy out relevant state from the old subgroup.
1656 */
1657 update_subgroup_copy_adj_out(paf->subgroup, subgrp);
1658 update_subgroup_copy_packets(subgrp, paf->next_pkt_to_send);
1659
1660 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1661 zlog_debug("u%" PRIu64 ":s%" PRIu64" peer %s split and moved into u%" PRIu64":s%" PRIu64,
1662 paf->subgroup->update_group->id, paf->subgroup->id,
1663 paf->peer->host, updgrp->id, subgrp->id);
1664
1665 SUBGRP_INCR_STAT(paf->subgroup, split_events);
1666
1667 /*
1668 * Since queued advs were left behind, this new subgroup needs a
1669 * refresh.
1670 */
1671 update_subgroup_set_needs_refresh(subgrp, 1);
1672
1673 /*
1674 * Remove peer from old subgroup, and add it to the new one.
1675 */
1676 update_subgroup_remove_peer(paf->subgroup, paf);
1677
1678 update_subgroup_add_peer(subgrp, paf, 1);
1679 }
1680
1681 void update_bgp_group_init(struct bgp *bgp)
1682 {
1683 int afid;
1684
1685 AF_FOREACH (afid)
1686 bgp->update_groups[afid] =
1687 hash_create(updgrp_hash_key_make, updgrp_hash_cmp,
1688 "BGP Update Group Hash");
1689 }
1690
1691 void update_bgp_group_free(struct bgp *bgp)
1692 {
1693 int afid;
1694
1695 AF_FOREACH (afid) {
1696 if (bgp->update_groups[afid]) {
1697 hash_free(bgp->update_groups[afid]);
1698 bgp->update_groups[afid] = NULL;
1699 }
1700 }
1701 }
1702
1703 void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty,
1704 uint64_t subgrp_id)
1705 {
1706 struct updwalk_context ctx;
1707 memset(&ctx, 0, sizeof(ctx));
1708 ctx.vty = vty;
1709 ctx.subgrp_id = subgrp_id;
1710
1711 update_group_af_walk(bgp, afi, safi, update_group_show_walkcb, &ctx);
1712 }
1713
1714 /*
1715 * update_group_show_stats
1716 *
1717 * Show global statistics about update groups.
1718 */
1719 void update_group_show_stats(struct bgp *bgp, struct vty *vty)
1720 {
1721 vty_out(vty, "Update groups created: %u\n",
1722 bgp->update_group_stats.updgrps_created);
1723 vty_out(vty, "Update groups deleted: %u\n",
1724 bgp->update_group_stats.updgrps_deleted);
1725 vty_out(vty, "Update subgroups created: %u\n",
1726 bgp->update_group_stats.subgrps_created);
1727 vty_out(vty, "Update subgroups deleted: %u\n",
1728 bgp->update_group_stats.subgrps_deleted);
1729 vty_out(vty, "Join events: %u\n", bgp->update_group_stats.join_events);
1730 vty_out(vty, "Prune events: %u\n",
1731 bgp->update_group_stats.prune_events);
1732 vty_out(vty, "Merge events: %u\n",
1733 bgp->update_group_stats.merge_events);
1734 vty_out(vty, "Split events: %u\n",
1735 bgp->update_group_stats.split_events);
1736 vty_out(vty, "Update group switch events: %u\n",
1737 bgp->update_group_stats.updgrp_switch_events);
1738 vty_out(vty, "Peer route refreshes combined: %u\n",
1739 bgp->update_group_stats.peer_refreshes_combined);
1740 vty_out(vty, "Merge checks triggered: %u\n",
1741 bgp->update_group_stats.merge_checks_triggered);
1742 }
1743
1744 /*
1745 * update_group_adjust_peer
1746 */
1747 void update_group_adjust_peer(struct peer_af *paf)
1748 {
1749 struct update_group *updgrp;
1750 struct update_subgroup *subgrp, *old_subgrp;
1751 struct peer *peer;
1752
1753 if (!paf)
1754 return;
1755
1756 peer = PAF_PEER(paf);
1757 if (!peer_established(peer)) {
1758 return;
1759 }
1760
1761 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) {
1762 return;
1763 }
1764
1765 if (!peer->afc_nego[paf->afi][paf->safi]) {
1766 return;
1767 }
1768
1769 updgrp = update_group_find(paf);
1770 if (!updgrp) {
1771 updgrp = update_group_create(paf);
1772 if (!updgrp) {
1773 flog_err(EC_BGP_UPDGRP_CREATE,
1774 "couldn't create update group for peer %s",
1775 paf->peer->host);
1776 return;
1777 }
1778 }
1779
1780 old_subgrp = paf->subgroup;
1781
1782 if (old_subgrp) {
1783
1784 /*
1785 * If the update group of the peer is unchanged, the peer can
1786 * stay
1787 * in its existing subgroup and we're done.
1788 */
1789 if (old_subgrp->update_group == updgrp)
1790 return;
1791
1792 /*
1793 * The peer is switching between update groups. Put it in its
1794 * own subgroup under the new update group.
1795 */
1796 update_subgroup_split_peer(paf, updgrp);
1797 return;
1798 }
1799
1800 subgrp = update_subgroup_find(updgrp, paf);
1801 if (!subgrp) {
1802 subgrp = update_subgroup_create(updgrp);
1803 if (!subgrp)
1804 return;
1805 }
1806
1807 update_subgroup_add_peer(subgrp, paf, 1);
1808 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
1809 zlog_debug("u%" PRIu64 ":s%" PRIu64 " add peer %s", updgrp->id,
1810 subgrp->id, paf->peer->host);
1811
1812 return;
1813 }
1814
1815 int update_group_adjust_soloness(struct peer *peer, int set)
1816 {
1817 struct peer_group *group;
1818 struct listnode *node, *nnode;
1819
1820 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
1821 peer_lonesoul_or_not(peer, set);
1822 if (peer_established(peer))
1823 bgp_announce_route_all(peer);
1824 } else {
1825 group = peer->group;
1826 for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
1827 peer_lonesoul_or_not(peer, set);
1828 if (peer_established(peer))
1829 bgp_announce_route_all(peer);
1830 }
1831 }
1832 return 0;
1833 }
1834
1835 /*
1836 * update_subgroup_rib
1837 */
1838 struct bgp_table *update_subgroup_rib(struct update_subgroup *subgrp)
1839 {
1840 struct bgp *bgp;
1841
1842 bgp = SUBGRP_INST(subgrp);
1843 if (!bgp)
1844 return NULL;
1845
1846 return bgp->rib[SUBGRP_AFI(subgrp)][SUBGRP_SAFI(subgrp)];
1847 }
1848
1849 void update_group_af_walk(struct bgp *bgp, afi_t afi, safi_t safi,
1850 updgrp_walkcb cb, void *ctx)
1851 {
1852 struct updwalk_context wctx;
1853 int afid;
1854
1855 if (!bgp)
1856 return;
1857 afid = afindex(afi, safi);
1858 if (afid >= BGP_AF_MAX)
1859 return;
1860
1861 memset(&wctx, 0, sizeof(wctx));
1862 wctx.cb = cb;
1863 wctx.context = ctx;
1864
1865 if (bgp->update_groups[afid])
1866 hash_walk(bgp->update_groups[afid], update_group_walkcb, &wctx);
1867 }
1868
1869 void update_group_walk(struct bgp *bgp, updgrp_walkcb cb, void *ctx)
1870 {
1871 afi_t afi;
1872 safi_t safi;
1873
1874 FOREACH_AFI_SAFI (afi, safi) {
1875 update_group_af_walk(bgp, afi, safi, cb, ctx);
1876 }
1877 }
1878
1879 void update_group_periodic_merge(struct bgp *bgp)
1880 {
1881 char reason[] = "periodic merge check";
1882
1883 update_group_walk(bgp, update_group_periodic_merge_walkcb,
1884 (void *)reason);
1885 }
1886
1887 static int
1888 update_group_default_originate_route_map_walkcb(struct update_group *updgrp,
1889 void *arg)
1890 {
1891 struct update_subgroup *subgrp;
1892 struct peer *peer;
1893 afi_t afi;
1894 safi_t safi;
1895
1896 UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
1897 peer = SUBGRP_PEER(subgrp);
1898 afi = SUBGRP_AFI(subgrp);
1899 safi = SUBGRP_SAFI(subgrp);
1900
1901 if (peer->default_rmap[afi][safi].name) {
1902 /*
1903 * When there is change in routemap this flow will
1904 * be triggered. We need to unset the Flag to ensure
1905 * the update flow gets triggered.
1906 */
1907 UNSET_FLAG(subgrp->sflags,
1908 SUBGRP_STATUS_DEFAULT_ORIGINATE);
1909 subgroup_default_originate(subgrp, 0);
1910 }
1911 }
1912
1913 return UPDWALK_CONTINUE;
1914 }
1915
1916 void update_group_refresh_default_originate_route_map(struct thread *thread)
1917 {
1918 struct bgp *bgp;
1919 char reason[] = "refresh default-originate route-map";
1920
1921 bgp = THREAD_ARG(thread);
1922 update_group_walk(bgp, update_group_default_originate_route_map_walkcb,
1923 reason);
1924 THREAD_OFF(bgp->t_rmap_def_originate_eval);
1925 bgp_unlock(bgp);
1926 }
1927
1928 /*
1929 * peer_af_announce_route
1930 *
1931 * Refreshes routes out to a peer_af immediately.
1932 *
1933 * If the combine parameter is true, then this function will try to
1934 * gather other peers in the subgroup for which a route announcement
1935 * is pending and efficently announce routes to all of them.
1936 *
1937 * For now, the 'combine' option has an effect only if all peers in
1938 * the subgroup have a route announcement pending.
1939 */
1940 void peer_af_announce_route(struct peer_af *paf, int combine)
1941 {
1942 struct update_subgroup *subgrp;
1943 struct peer_af *cur_paf;
1944 int all_pending;
1945
1946 subgrp = paf->subgroup;
1947 all_pending = 0;
1948
1949 if (combine) {
1950 /*
1951 * If there are other peers in the old subgroup that also need
1952 * routes to be announced, pull them into the peer's new
1953 * subgroup.
1954 * Combine route announcement with other peers if possible.
1955 *
1956 * For now, we combine only if all peers in the subgroup have an
1957 * announcement pending.
1958 */
1959 all_pending = 1;
1960
1961 SUBGRP_FOREACH_PEER (subgrp, cur_paf) {
1962 if (cur_paf == paf)
1963 continue;
1964
1965 if (cur_paf->t_announce_route)
1966 continue;
1967
1968 all_pending = 0;
1969 break;
1970 }
1971 }
1972 /*
1973 * Announce to the peer alone if we were not asked to combine peers,
1974 * or if some peers don't have a route annoucement pending.
1975 */
1976 if (!combine || !all_pending) {
1977 update_subgroup_split_peer(paf, NULL);
1978 subgrp = paf->subgroup;
1979
1980 assert(subgrp && subgrp->update_group);
1981 if (bgp_debug_update(paf->peer, NULL, subgrp->update_group, 0))
1982 zlog_debug("u%" PRIu64 ":s%" PRIu64" %s announcing routes",
1983 subgrp->update_group->id, subgrp->id,
1984 paf->peer->host);
1985
1986 subgroup_announce_route(paf->subgroup);
1987 return;
1988 }
1989
1990 /*
1991 * We will announce routes the entire subgroup.
1992 *
1993 * First stop refresh timers on all the other peers.
1994 */
1995 SUBGRP_FOREACH_PEER (subgrp, cur_paf) {
1996 if (cur_paf == paf)
1997 continue;
1998
1999 bgp_stop_announce_route_timer(cur_paf);
2000 }
2001
2002 if (bgp_debug_update(paf->peer, NULL, subgrp->update_group, 0))
2003 zlog_debug("u%" PRIu64 ":s%" PRIu64" announcing routes to %s, combined into %d peers",
2004 subgrp->update_group->id, subgrp->id,
2005 paf->peer->host, subgrp->peer_count);
2006
2007 subgroup_announce_route(subgrp);
2008
2009 SUBGRP_INCR_STAT_BY(subgrp, peer_refreshes_combined,
2010 subgrp->peer_count - 1);
2011 }
2012
2013 void subgroup_trigger_write(struct update_subgroup *subgrp)
2014 {
2015 struct peer_af *paf;
2016
2017 /*
2018 * For each peer in the subgroup, schedule a job to pull packets from
2019 * the subgroup output queue into their own output queue. This action
2020 * will trigger a write job on the I/O thread.
2021 */
2022 SUBGRP_FOREACH_PEER (subgrp, paf)
2023 if (peer_established(paf->peer))
2024 thread_add_timer_msec(
2025 bm->master, bgp_generate_updgrp_packets,
2026 paf->peer, 0,
2027 &paf->peer->t_generate_updgrp_packets);
2028 }
2029
2030 int update_group_clear_update_dbg(struct update_group *updgrp, void *arg)
2031 {
2032 UPDGRP_PEER_DBG_OFF(updgrp);
2033 return UPDWALK_CONTINUE;
2034 }
2035
2036 /* Return true if we should addpath encode NLRI to this peer */
2037 bool bgp_addpath_encode_tx(struct peer *peer, afi_t afi, safi_t safi)
2038 {
2039 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV)
2040 && CHECK_FLAG(peer->af_cap[afi][safi],
2041 PEER_CAP_ADDPATH_AF_RX_RCV));
2042 }
2043
2044 bool bgp_check_selected(struct bgp_path_info *bpi, struct peer *peer,
2045 bool addpath_capable, afi_t afi, safi_t safi)
2046 {
2047 return (CHECK_FLAG(bpi->flags, BGP_PATH_SELECTED) ||
2048 (addpath_capable &&
2049 bgp_addpath_tx_path(peer->addpath_type[afi][safi], bpi)));
2050 }