mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 15:41:54 +00:00
BGP: pending TX prefixes link netindex instead of copying net_addr
This helps with memory consumption, allows for removal of multiple slab/mblock ifs and prepares for easier feeds.
This commit is contained in:
parent
1eed19cadb
commit
ea9f64e0ec
@ -1680,7 +1680,7 @@ bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b)
|
|||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(b->prefixes);
|
struct bgp_prefix *px = HEAD(b->prefixes);
|
||||||
|
|
||||||
log(L_ERR "%s: - withdrawing %N", p->p.name, &px->net);
|
log(L_ERR "%s: - withdrawing %N", p->p.name, px->ni->addr);
|
||||||
rem_node(&px->buck_node);
|
rem_node(&px->buck_node);
|
||||||
add_tail(&wb->prefixes, &px->buck_node);
|
add_tail(&wb->prefixes, &px->buck_node);
|
||||||
}
|
}
|
||||||
@ -1691,9 +1691,9 @@ bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b)
|
|||||||
* Prefix hash table
|
* Prefix hash table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define PXH_KEY(px) px->net, px->path_id, px->hash
|
#define PXH_KEY(px) px->ni->index, px->path_id, px->hash
|
||||||
#define PXH_NEXT(px) px->next
|
#define PXH_NEXT(px) px->next
|
||||||
#define PXH_EQ(n1,i1,h1,n2,i2,h2) h1 == h2 && (add_path_tx ? (i1 == i2) : 1) && net_equal(n1, n2)
|
#define PXH_EQ(n1,i1,h1,n2,i2,h2) h1 == h2 && (add_path_tx ? (i1 == i2) : 1) && (n1 == n2)
|
||||||
#define PXH_FN(n,i,h) h
|
#define PXH_FN(n,i,h) h
|
||||||
|
|
||||||
#define PXH_REHASH bgp_pxh_rehash
|
#define PXH_REHASH bgp_pxh_rehash
|
||||||
@ -1706,19 +1706,17 @@ static void
|
|||||||
bgp_init_prefix_table(struct bgp_channel *c)
|
bgp_init_prefix_table(struct bgp_channel *c)
|
||||||
{
|
{
|
||||||
HASH_INIT(c->prefix_hash, c->pool, 8);
|
HASH_INIT(c->prefix_hash, c->pool, 8);
|
||||||
|
c->prefix_slab = sl_new(c->pool, sizeof(struct bgp_prefix));
|
||||||
uint alen = net_addr_length[c->c.net_type];
|
|
||||||
c->prefix_slab = alen ? sl_new(c->pool, sizeof(struct bgp_prefix) + alen) : NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bgp_prefix *
|
static struct bgp_prefix *
|
||||||
bgp_get_prefix(struct bgp_channel *c, const net_addr *net, struct rte_src *src, int add_path_tx)
|
bgp_get_prefix(struct bgp_channel *c, struct netindex *ni, struct rte_src *src, int add_path_tx)
|
||||||
{
|
{
|
||||||
u32 path_id = src->global_id;
|
u32 path_id = src->global_id;
|
||||||
u32 path_id_hash = add_path_tx ? path_id : 0;
|
u32 path_id_hash = add_path_tx ? path_id : 0;
|
||||||
/* We must use a different hash function than the rtable */
|
/* We must use a different hash function than the rtable */
|
||||||
u32 hash = u32_hash(net_hash(net) ^ u32_hash(path_id_hash));
|
u32 hash = u32_hash(u32_hash(ni->index) ^ u32_hash(path_id_hash));
|
||||||
struct bgp_prefix *px = HASH_FIND(c->prefix_hash, PXH, net, path_id_hash, hash);
|
struct bgp_prefix *px = HASH_FIND(c->prefix_hash, PXH, ni->index, path_id_hash, hash);
|
||||||
|
|
||||||
if (px)
|
if (px)
|
||||||
{
|
{
|
||||||
@ -1732,15 +1730,14 @@ bgp_get_prefix(struct bgp_channel *c, const net_addr *net, struct rte_src *src,
|
|||||||
return px;
|
return px;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->prefix_slab)
|
|
||||||
px = sl_alloc(c->prefix_slab);
|
px = sl_alloc(c->prefix_slab);
|
||||||
else
|
*px = (struct bgp_prefix) {
|
||||||
px = mb_alloc(c->pool, sizeof(struct bgp_prefix) + net->length);
|
.hash = hash,
|
||||||
|
.path_id = path_id,
|
||||||
|
.ni = ni,
|
||||||
|
};
|
||||||
|
|
||||||
*px = (struct bgp_prefix) { };
|
net_lock_index(c->c.table->netindex, ni);
|
||||||
px->hash = hash;
|
|
||||||
px->path_id = path_id;
|
|
||||||
net_copy(px->net, net);
|
|
||||||
rt_lock_source(src);
|
rt_lock_source(src);
|
||||||
|
|
||||||
HASH_INSERT2(c->prefix_hash, PXH, c->pool, px);
|
HASH_INSERT2(c->prefix_hash, PXH, c->pool, px);
|
||||||
@ -1757,7 +1754,7 @@ bgp_update_prefix(struct bgp_channel *c, struct bgp_prefix *px, struct bgp_bucke
|
|||||||
#define BPX_TRACE(what) do { \
|
#define BPX_TRACE(what) do { \
|
||||||
if (c->c.debug & D_ROUTES) log(L_TRACE "%s.%s < %s %N %uG %s", \
|
if (c->c.debug & D_ROUTES) log(L_TRACE "%s.%s < %s %N %uG %s", \
|
||||||
c->c.proto->name, c->c.name, what, \
|
c->c.proto->name, c->c.name, what, \
|
||||||
px->net, px->path_id, IS_WITHDRAW_BUCKET(b) ? "withdraw" : "update"); } while (0)
|
px->ni->addr, px->path_id, IS_WITHDRAW_BUCKET(b) ? "withdraw" : "update"); } while (0)
|
||||||
px->lastmod = current_time();
|
px->lastmod = current_time();
|
||||||
|
|
||||||
/* Already queued for the same bucket */
|
/* Already queued for the same bucket */
|
||||||
@ -1809,12 +1806,10 @@ bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px)
|
|||||||
{
|
{
|
||||||
HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px);
|
HASH_REMOVE2(c->prefix_hash, PXH, c->pool, px);
|
||||||
|
|
||||||
|
net_unlock_index(c->c.table->netindex, px->ni);
|
||||||
rt_unlock_source(rt_find_source_global(px->path_id));
|
rt_unlock_source(rt_find_source_global(px->path_id));
|
||||||
|
|
||||||
if (c->prefix_slab)
|
|
||||||
sl_free(px);
|
sl_free(px);
|
||||||
else
|
|
||||||
mb_free(px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2299,7 +2294,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, c
|
|||||||
path = old->src;
|
path = old->src;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bgp_update_prefix(c, bgp_get_prefix(c, n, path, c->add_path_tx), buck))
|
if (bgp_update_prefix(c, bgp_get_prefix(c, NET_TO_INDEX(n), path, c->add_path_tx), buck))
|
||||||
bgp_schedule_packet(p->conn, c, PKT_UPDATE);
|
bgp_schedule_packet(p->conn, c, PKT_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ struct bgp_prefix {
|
|||||||
btime lastmod; /* Last modification of this prefix */
|
btime lastmod; /* Last modification of this prefix */
|
||||||
u32 hash;
|
u32 hash;
|
||||||
u32 path_id;
|
u32 path_id;
|
||||||
net_addr net[0];
|
struct netindex *ni;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bgp_bucket {
|
struct bgp_bucket {
|
||||||
|
@ -1600,7 +1600,7 @@ bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(buck->prefixes);
|
struct bgp_prefix *px = HEAD(buck->prefixes);
|
||||||
struct net_addr_ip4 *net = (void *) px->net;
|
struct net_addr_ip4 *net = NET_PTR_IP4(&px->ni->addr[0]);
|
||||||
|
|
||||||
/* Encode path ID */
|
/* Encode path ID */
|
||||||
if (s->add_path)
|
if (s->add_path)
|
||||||
@ -1686,7 +1686,7 @@ bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(buck->prefixes);
|
struct bgp_prefix *px = HEAD(buck->prefixes);
|
||||||
struct net_addr_ip6 *net = (void *) px->net;
|
struct net_addr_ip6 *net = NET_PTR_IP6(&px->ni->addr[0]);
|
||||||
|
|
||||||
/* Encode path ID */
|
/* Encode path ID */
|
||||||
if (s->add_path)
|
if (s->add_path)
|
||||||
@ -1771,7 +1771,7 @@ bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(buck->prefixes);
|
struct bgp_prefix *px = HEAD(buck->prefixes);
|
||||||
struct net_addr_vpn4 *net = (void *) px->net;
|
struct net_addr_vpn4 *net = NET_PTR_VPN4(&px->ni->addr[0]);
|
||||||
|
|
||||||
/* Encode path ID */
|
/* Encode path ID */
|
||||||
if (s->add_path)
|
if (s->add_path)
|
||||||
@ -1869,7 +1869,7 @@ bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
while (!EMPTY_LIST(buck->prefixes) && (size >= BGP_NLRI_MAX))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(buck->prefixes);
|
struct bgp_prefix *px = HEAD(buck->prefixes);
|
||||||
struct net_addr_vpn6 *net = (void *) px->net;
|
struct net_addr_vpn6 *net = NET_PTR_VPN6(&px->ni->addr[0]);
|
||||||
|
|
||||||
/* Encode path ID */
|
/* Encode path ID */
|
||||||
if (s->add_path)
|
if (s->add_path)
|
||||||
@ -1967,7 +1967,7 @@ bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
|
while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(buck->prefixes);
|
struct bgp_prefix *px = HEAD(buck->prefixes);
|
||||||
struct net_addr_flow4 *net = (void *) px->net;
|
struct net_addr_flow4 *net = NET_PTR_FLOW4(&px->ni->addr[0]);
|
||||||
uint flen = net->length - sizeof(net_addr_flow4);
|
uint flen = net->length - sizeof(net_addr_flow4);
|
||||||
|
|
||||||
/* Encode path ID */
|
/* Encode path ID */
|
||||||
@ -2055,7 +2055,7 @@ bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *
|
|||||||
while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
|
while (!EMPTY_LIST(buck->prefixes) && (size >= 4))
|
||||||
{
|
{
|
||||||
struct bgp_prefix *px = HEAD(buck->prefixes);
|
struct bgp_prefix *px = HEAD(buck->prefixes);
|
||||||
struct net_addr_flow6 *net = (void *) px->net;
|
struct net_addr_flow6 *net = NET_PTR_FLOW6(&px->ni->addr[0]);
|
||||||
uint flen = net->length - sizeof(net_addr_flow6);
|
uint flen = net->length - sizeof(net_addr_flow6);
|
||||||
|
|
||||||
/* Encode path ID */
|
/* Encode path ID */
|
||||||
|
Loading…
Reference in New Issue
Block a user