void
bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b)
{
+ if (b->bmp)
+ return;
+
struct bgp_proto *p = (void *) c->c.proto;
struct bgp_bucket *wb = bgp_get_withdraw_bucket(c);
void
bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px)
{
+ /* BMP hack */
+ if (
+ !NODE_VALID(px->buck_node.prev) &&
+ !NODE_VALID(px->buck_node.next) &&
+ !SKIP_BACK(struct bgp_bucket, prefixes.head, px->buck_node.prev)->bmp
+ )
+ return;
+
rem_node(&px->buck_node);
HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px);
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
- if (!s->sham)
- bgp_free_prefix(s->channel, px);
- else
- rem_node(&px->buck_node);
+ bgp_free_prefix(s->channel, px);
}
return pos - buf;
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
- if (!s->sham)
- bgp_free_prefix(s->channel, px);
- else
- rem_node(&px->buck_node);
+ bgp_free_prefix(s->channel, px);
}
return pos - buf;
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
- if (!s->sham)
- bgp_free_prefix(s->channel, px);
- else
- rem_node(&px->buck_node);
+ bgp_free_prefix(s->channel, px);
}
return pos - buf;
memcpy(pos, &a, b);
ADVANCE(pos, size, b);
- if (!s->sham)
- bgp_free_prefix(s->channel, px);
- else
- rem_node(&px->buck_node);
+ bgp_free_prefix(s->channel, px);
}
return pos - buf;
memcpy(pos, net->data, flen);
ADVANCE(pos, size, flen);
- if (!s->sham)
- bgp_free_prefix(s->channel, px);
- else
- rem_node(&px->buck_node);
+ bgp_free_prefix(s->channel, px);
}
return pos - buf;
memcpy(pos, net->data, flen);
ADVANCE(pos, size, flen);
- if (!s->sham)
- bgp_free_prefix(s->channel, px);
- else
- rem_node(&px->buck_node);
+ bgp_free_prefix(s->channel, px);
}
return pos - buf;
if (la < 0)
{
/* Attribute list too long */
- if (!s->sham)
- bgp_withdraw_bucket(s->channel, buck);
+ bgp_withdraw_bucket(s->channel, buck);
return NULL;
}
if (la < 0)
{
/* Attribute list too long */
- if (!s->sham)
- bgp_withdraw_bucket(s->channel, buck);
+ bgp_withdraw_bucket(s->channel, buck);
return NULL;
}
byte *res = NULL;
/* FIXME: must be a bit shorter */
- struct lp_state tmpp;
- lp_save(tmp_linpool, &tmpp);
-
struct bgp_caps *peer = p->conn->remote_caps;
const struct bgp_af_caps *rem = bgp_find_af_caps(peer, c->afi);
.as4_session = 1,
.add_path = c->add_path_rx,
.mpls = c->desc->mpls,
- .sham = 1,
};
if (!update)
bgp_create_mp_reach(&s, buck, buf, end);
}
- lp_restore(tmp_linpool, &tmpp);
-
return res;
}
uint bucket_size = sizeof(struct bgp_bucket) + ea_size;
uint prefix_size = sizeof(struct bgp_prefix) + n->length;
- /* Sham bucket */
- struct bgp_bucket *b = alloca(bucket_size);
- *b = (struct bgp_bucket) { };
+ struct lp_state tmpp;
+ lp_save(tmp_linpool, &tmpp);
+
+ /* Temporary bucket */
+ struct bgp_bucket *b = tmp_allocz(bucket_size);
+ b->bmp = 1;
init_list(&b->prefixes);
if (attrs)
memcpy(b->eattrs, attrs, ea_size);
- /* Sham prefix */
- struct bgp_prefix *px = alloca(prefix_size);
- *px = (struct bgp_prefix) { };
+ /* Temporary prefix */
+ struct bgp_prefix *px = tmp_allocz(prefix_size);
px->path_id = src->private_id;
net_copy(px->net, n);
add_tail(&b->prefixes, &px->buck_node);
if (end)
bgp_bmp_prepare_bgp_hdr(buf, end - buf, PKT_UPDATE);
+ lp_restore(tmp_linpool, &tmpp);
+
return end;
}