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