]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
ID Map: Introducing a maximum limit for the ID
authorMaria Matejka <mq@ucw.cz>
Tue, 9 Apr 2019 11:38:39 +0000 (13:38 +0200)
committerMaria Matejka <mq@ucw.cz>
Tue, 9 Apr 2019 11:40:13 +0000 (13:40 +0200)
filter/f-util.c
lib/idm.c
lib/idm.h
lib/tindex.c
nest/rt-attr.c
proto/ospf/ospf.c
proto/ospf/topology.c

index ee9490b46c30381ca7379965406c84647638a94a..7f17cd221a02284b31ee769425699e9c8322bcd1 100644 (file)
@@ -196,7 +196,7 @@ ca_lookup(pool *p, const char *name, int f_type)
 
   static int inited = 0;
   if (!inited) {
-    idm_init(&ca_idm, &root_pool, 8);
+    idm_init(&ca_idm, &root_pool, 8, EA_CUSTOM_BIT);
     HASH_INIT(ca_hash, &root_pool, CA_ORDER);
 
     ca_storage_max = 256;
@@ -212,7 +212,7 @@ ca_lookup(pool *p, const char *name, int f_type)
 
     uint id = idm_alloc(&ca_idm);
 
-    if (id >= EA_CUSTOM_BIT)
+    if (!id)
       cf_error("Too many custom attributes.");
 
     if (id >= ca_storage_max) {
index 66e311c6a885077bc43a1a23e01bc066ebff3b0d..94c7f11c42c651239f6486690db540c883b61471 100644 (file)
--- a/lib/idm.c
+++ b/lib/idm.c
 
 
 void
-idm_init(struct idm *m, pool *p, uint size)
+idm_init(struct idm *m, pool *p, u64 size, u64 max)
 {
   m->pos = 0;
   m->used = 1;
   m->size = size;
+  m->max = max;
   m->data = mb_allocz(p, m->size * sizeof(u32));
 
   /* ID 0 is reserved */
@@ -29,17 +30,17 @@ idm_init(struct idm *m, pool *p, uint size)
 
 static inline int u32_cto(uint x) { return ffs(~x) - 1; }
 
-u32
+u64
 idm_alloc(struct idm *m)
 {
-  uint i, j;
+  u64 i, j;
 
   for (i = m->pos; i < m->size; i++)
     if (m->data[i] != 0xffffffff)
       goto found;
 
-  /* If we are at least 7/8 full, expand */
-  if (m->used > (m->size * 28))
+  /* If we are at least 7/8 full, expand (if we are allowed to) */
+  if ((m->used * 32 < m->max) && (m->used > m->size * 28))
   {
     m->size *= 2;
     m->data = mb_realloc(m->data, m->size * sizeof(u32));
@@ -51,24 +52,26 @@ idm_alloc(struct idm *m)
     if (m->data[i] != 0xffffffff)
       goto found;
 
-  ASSERT(0);
+  return 0;
 
 found:
-  ASSERT(i < 0x8000000);
-
   m->pos = i;
   j = u32_cto(m->data[i]);
 
+  u64 id = 32 * i + j;
+
+  ASSERT(id < m->max);
+
   m->data[i] |= (1 << j);
   m->used++;
-  return 32 * i + j;
+  return id;
 }
 
 void
-idm_free(struct idm *m, u32 id)
+idm_free(struct idm *m, u64 id)
 {
-  uint i = id / 32;
-  uint j = id % 32;
+  u64 i = id / 32;
+  u64 j = id % 32;
 
   ASSERT((i < m->size) && (m->data[i] & (1 << j)));
   m->data[i] &= ~(1 << j);
index e3380cceae8dc4e32fe77146cc342a10efd6da30..c2ec6ab49bb77aa1d22898bab62db3b99f70467a 100644 (file)
--- a/lib/idm.h
+++ b/lib/idm.h
 struct idm
 {
   u32 *data;
-  u32 pos;
-  u32 used;
-  u32 size;
+  u64 pos;
+  u64 used;
+  u64 size;
+  u64 max;
 };
 
-void idm_init(struct idm *m, pool *p, uint size);
-u32 idm_alloc(struct idm *m);
-void idm_free(struct idm *m, u32 id);
+void idm_init(struct idm *m, pool *p, u64 size, u64 max);
+u64 idm_alloc(struct idm *m);
+void idm_free(struct idm *m, u64 id);
 
 #endif
index 934151a823dc1ca0b4778f3e2cbe90058f53873f..e49d3ce1f4f3b5b0edc07e65cfc95d8778297f72 100644 (file)
@@ -40,7 +40,7 @@ tindex_new(pool *p)
   ti->unit_size = TI_MIN_UNIT_SIZE;
   ti->address_size = TI_MIN_ADDRESS_SIZE;
   ti->index_data = mb_allocz(p, ti->unit_size * (1 << ti->address_size));
-  idm_init(&(ti->idm), p, (1 << ti->address_size));
+  idm_init(&(ti->idm), p, (1 << (ti->address_size - 5)), (1 << ti->address_size));
   u32 rootnode = idm_alloc(&(ti->idm));
   ASSERT(rootnode == 1);
   return ti;
index cc362cab03cd486d2f4c28277b0464a53257540c..dad968f92a4f404b8f1a9b17f1768f2d8a96fb0f 100644 (file)
@@ -111,7 +111,7 @@ rte_src_init(void)
 {
   rte_src_slab = sl_new(rta_pool, sizeof(struct rte_src));
 
-  idm_init(&src_ids, rta_pool, SRC_ID_INIT_SIZE);
+  idm_init(&src_ids, rta_pool, SRC_ID_INIT_SIZE, 1ULL << 32);
 
   HASH_INIT(src_hash, rta_pool, RSH_INIT_ORDER);
 }
@@ -137,6 +137,7 @@ rt_get_source(struct proto *p, u32 id)
   src->proto = p;
   src->private_id = id;
   src->global_id = idm_alloc(&src_ids);
+  ASSERT(src->global_id);
   src->uc = 0;
 
   HASH_INSERT2(src_hash, RSH, rta_pool, src);
index f3eabb47768e0e54d6407b0c3b9fcdb7c6ac184c..d4d3c01d5fe35e7e1f54b23d1aae201d7cfeae08 100644 (file)
@@ -257,7 +257,7 @@ ospf_start(struct proto *P)
   init_list(&(p->area_list));
   fib_init(&p->rtf, P->pool, ospf_get_af(p), sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
   if (ospf_is_v3(p))
-    idm_init(&p->idm, P->pool, 16);
+    idm_init(&p->idm, P->pool, 16, 1ULL << 32);
   p->areano = 0;
   p->gr = ospf_top_new(p, P->pool);
   s_init_list(&(p->lsal));
index 7d5deca01099ab747248405c842da27855a2b79a..554b50b52a349ce72b2fae5c86df3b3a82538137 100644 (file)
@@ -563,6 +563,7 @@ ort_to_lsaid(struct ospf_proto *p, ort *nf)
     if (!nf->lsa_id)
       nf->lsa_id = idm_alloc(&p->idm);
 
+    ASSERT(nf->lsa_id);
     return nf->lsa_id;
   }