summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Maria Matejka <mq@ucw.cz>2017-12-13 10:29:10 +0100
committerJan Maria Matejka <mq@ucw.cz>2017-12-13 10:29:10 +0100
commitcb21c5ffa92494b1a4bf110605509de3326b6c3d (patch)
treebd1c37b57c1d1aa45efecf4868ddf7d3ff27c489
parent71c51aa4ab0daa3490f9a488f505eb25102c4705 (diff)
parent1e11918c8c56e3505193f4e6426c1a34aaae3941 (diff)
Merge branch 'int-new' of gitlab.labs.nic.cz:labs/bird into int-new
-rw-r--r--.gitlab-ci.yml38
-rw-r--r--lib/flowspec_test.c4
-rw-r--r--lib/mempool.c69
-rw-r--r--lib/net.h4
-rw-r--r--lib/resource.h7
-rw-r--r--sysdep/bsd/krt-sock.Y4
-rw-r--r--sysdep/bsd/krt-sock.c10
-rw-r--r--sysdep/bsd/krt-sys.h2
8 files changed, 81 insertions, 57 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 05989484..482c5004 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -243,107 +243,73 @@ docker_ubuntu-16_04-amd64:
- MAKE=make
- which gmake 2>/dev/null >/dev/null && MAKE=gmake
- $MAKE
- # Run tests if they are available (eg. don't fail if "check" isn't a valid make target)
- - $MAKE check || [ "$?" = 2 ]
+ # Run tests if they are available
+ - $MAKE check
build-debian-7-amd64:
- variables:
- IPV6: "no"
<<: *debian-7-amd64_env
<<: *build_job
build-debian-8-amd64:
- variables:
- IPV6: "no"
<<: *debian-8-amd64_env
<<: *build_job
build-debian-9-amd64:
- variables:
- IPV6: "no"
<<: *debian-9-amd64_env
<<: *build_job
build-debian-testing-amd64:
- variables:
- IPV6: "no"
<<: *debian-testing-amd64_env
<<: *build_job
build-fedora-25-amd64:
- variables:
- IPV6: "no"
<<: *fedora-25-amd64_env
<<: *build_job
build-fedora-26-amd64:
- variables:
- IPV6: "no"
<<: *fedora-26-amd64_env
<<: *build_job
build-centos-6-amd64:
- variables:
- IPV6: "no"
<<: *centos-6-amd64_env
<<: *build_job
build-centos-7-amd64:
- variables:
- IPV6: "no"
<<: *centos-7-amd64_env
<<: *build_job
build-opensuse-42_3-amd64:
- variables:
- IPV6: "no"
<<: *opensuse-42_3-amd64_env
<<: *build_job
build-ubuntu-14_04-amd64:
- variables:
- IPV6: "no"
<<: *ubuntu-14_04-amd64_env
<<: *build_job
build-ubuntu-16_04-amd64:
- variables:
- IPV6: "no"
<<: *ubuntu-16_04-amd64_env
<<: *build_job
build-debian-7-i386:
- variables:
- IPV6: "no"
<<: *debian-7-i386_env
<<: *build_job
build-debian-8-i386:
- variables:
- IPV6: "no"
<<: *debian-8-i386_env
<<: *build_job
build-debian-9-i386:
- variables:
- IPV6: "no"
<<: *debian-9-i386_env
<<: *build_job
build-debian-testing-i386:
- variables:
- IPV6: "no"
<<: *debian-testing-i386_env
<<: *build_job
build-freebsd-11-amd64:
- variables:
- IPV6: "no"
<<: *freebsd-11-amd64_env
<<: *build_job
build-freebsd-11-i386:
- variables:
- IPV6: "no"
<<: *freebsd-11-i386_env
<<: *build_job
diff --git a/lib/flowspec_test.c b/lib/flowspec_test.c
index 69bc279d..dd71dc7b 100644
--- a/lib/flowspec_test.c
+++ b/lib/flowspec_test.c
@@ -70,8 +70,8 @@ t_first_part(void)
net_addr_flow4 *f;
NET_ADDR_FLOW4_(f, ip4_build(10,0,0,1), 24, ((byte[]) { 0x00, 0x00, 0xab }));
- const byte const *under240 = &f->data[1];
- const byte const *above240 = &f->data[2];
+ const byte *under240 = &f->data[1];
+ const byte *above240 = &f->data[2];
/* Case 0x00 0x00 */
bt_assert(flow4_first_part(f) == NULL);
diff --git a/lib/mempool.c b/lib/mempool.c
index 3cf9c2d3..5a8f2a69 100644
--- a/lib/mempool.c
+++ b/lib/mempool.c
@@ -11,7 +11,7 @@
*
* Linear memory pools are collections of memory blocks which
* support very fast allocation of new blocks, but are able to free only
- * the whole collection at once.
+ * the whole collection at once (or in stack order).
*
* Example: Each configuration is described by a complex system of structures,
* linked lists and function trees which are all allocated from a single linear
@@ -37,7 +37,7 @@ const int lp_chunk_size = sizeof(struct lp_chunk);
struct linpool {
resource r;
byte *ptr, *end;
- struct lp_chunk *first, *current, **plast; /* Normal (reusable) chunks */
+ struct lp_chunk *first, *current; /* Normal (reusable) chunks */
struct lp_chunk *first_large; /* Large chunks */
uint chunk_size, threshold, total, total_large;
};
@@ -69,7 +69,6 @@ linpool
*lp_new(pool *p, uint blk)
{
linpool *m = ralloc(p, &lp_class);
- m->plast = &m->first;
m->chunk_size = blk;
m->threshold = 3*blk/4;
return m;
@@ -114,22 +113,25 @@ lp_alloc(linpool *m, uint size)
}
else
{
- if (m->current)
+ if (m->current && m->current->next)
{
/* Still have free chunks from previous incarnation (before lp_flush()) */
- c = m->current;
- m->current = c->next;
+ c = m->current->next;
}
else
{
/* Need to allocate a new chunk */
c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
m->total += m->chunk_size;
- *m->plast = c;
- m->plast = &c->next;
c->next = NULL;
c->size = m->chunk_size;
+
+ if (m->current)
+ m->current->next = c;
+ else
+ m->first = c;
}
+ m->current = c;
m->ptr = c->data + size;
m->end = c->data + m->chunk_size;
}
@@ -190,9 +192,11 @@ lp_flush(linpool *m)
{
struct lp_chunk *c;
- /* Relink all normal chunks to free list and free all large chunks */
- m->ptr = m->end = NULL;
- m->current = m->first;
+ /* Move ptr to the first chunk and free all large chunks */
+ m->current = c = m->first;
+ m->ptr = c ? c->data : NULL;
+ m->end = c ? c->data + m->chunk_size : NULL;
+
while (c = m->first_large)
{
m->first_large = c->next;
@@ -201,6 +205,49 @@ lp_flush(linpool *m)
m->total_large = 0;
}
+/**
+ * lp_save - save the state of a linear memory pool
+ * @m: linear memory pool
+ * @p: state buffer
+ *
+ * This function saves the state of a linear memory pool. Saved state can be
+ * used later to restore the pool (to free memory allocated since).
+ */
+void
+lp_save(linpool *m, lp_state *p)
+{
+ p->current = m->current;
+ p->large = m->first_large;
+ p->ptr = m->ptr;
+}
+
+/**
+ * lp_restore - restore the state of a linear memory pool
+ * @m: linear memory pool
+ * @p: saved state
+ *
+ * This function restores the state of a linear memory pool, freeing all memory
+ * allocated since the state was saved. Note that the function cannot un-free
+ * the memory, therefore the function also invalidates other states that were
+ * saved between (on the same pool).
+ */
+void
+lp_restore(linpool *m, lp_state *p)
+{
+ struct lp_chunk *c;
+
+ /* Move ptr to the saved pos and free all newer large chunks */
+ m->current = c = p->current;
+ m->ptr = p->ptr;
+ m->end = c ? c->data + m->chunk_size : NULL;
+
+ while ((c = m->first_large) && (c != p->large))
+ {
+ m->first_large = c->next;
+ xfree(c);
+ }
+}
+
static void
lp_free(resource *r)
{
diff --git a/lib/net.h b/lib/net.h
index 4b2077ae..69f00641 100644
--- a/lib/net.h
+++ b/lib/net.h
@@ -358,10 +358,10 @@ static inline int net_zero_roa6(const net_addr_roa6 *a)
{ return !a->pxlen && ip6_zero(a->prefix) && !a->max_pxlen && !a->asn; }
static inline int net_zero_flow4(const net_addr_flow4 *a)
-{ return !a->pxlen && ip4_zero(a->prefix) && !a->data; }
+{ return !a->pxlen && ip4_zero(a->prefix) && (a->length == sizeof(net_addr_flow4)); }
static inline int net_zero_flow6(const net_addr_flow6 *a)
-{ return !a->pxlen && ip6_zero(a->prefix) && !a->data; }
+{ return !a->pxlen && ip6_zero(a->prefix) && (a->length == sizeof(net_addr_flow6)); }
static inline int net_zero_mpls(const net_addr_mpls *a)
{ return !a->label; }
diff --git a/lib/resource.h b/lib/resource.h
index 761c6adc..d9d4bb8f 100644
--- a/lib/resource.h
+++ b/lib/resource.h
@@ -59,11 +59,18 @@ void mb_free(void *);
typedef struct linpool linpool;
+typedef struct lp_state {
+ void *current, *large;
+ byte *ptr;
+} lp_state;
+
linpool *lp_new(pool *, unsigned blk);
void *lp_alloc(linpool *, unsigned size); /* Aligned */
void *lp_allocu(linpool *, unsigned size); /* Unaligned */
void *lp_allocz(linpool *, unsigned size); /* With clear */
void lp_flush(linpool *); /* Free everything, but leave linpool */
+void lp_save(linpool *m, lp_state *p); /* Save state */
+void lp_restore(linpool *m, lp_state *p); /* Restore state */
extern const int lp_chunk_size;
#define LP_GAS 1024
diff --git a/sysdep/bsd/krt-sock.Y b/sysdep/bsd/krt-sock.Y
index 0218f188..81422c79 100644
--- a/sysdep/bsd/krt-sock.Y
+++ b/sysdep/bsd/krt-sock.Y
@@ -20,8 +20,8 @@ kern_sys_item:
KERNEL TABLE expr {
if ($3 && (krt_max_tables == 1))
cf_error("Multiple kernel routing tables not supported");
- if ($3 < 0 || $3 >= krt_max_tables)
- cf_error("Kernel table id must be in range 0-%d", krt_max_tables - 1);
+ if ($3 >= krt_max_tables)
+ cf_error("Kernel table id must be in range 0-%u", krt_max_tables - 1);
THIS_KRT->sys.table_id = $3;
}
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index 604cd510..0a52cfbd 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -74,11 +74,11 @@ const int rt_default_ecmp = 0;
/* Dynamic max number of tables */
-int krt_max_tables;
+uint krt_max_tables;
#ifdef KRT_USE_SYSCTL_NET_FIBS
-static int
+static uint
krt_get_max_tables(void)
{
int fibs;
@@ -90,7 +90,11 @@ krt_get_max_tables(void)
return 1;
}
- return MIN(fibs, KRT_MAX_TABLES);
+ /* Should not happen */
+ if (fibs < 1)
+ return 1;
+
+ return (uint) MIN(fibs, KRT_MAX_TABLES);
}
#else
diff --git a/sysdep/bsd/krt-sys.h b/sysdep/bsd/krt-sys.h
index ed667e80..aa6cc72e 100644
--- a/sysdep/bsd/krt-sys.h
+++ b/sysdep/bsd/krt-sys.h
@@ -31,7 +31,7 @@ static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_c
/* Kernel routes */
-extern int krt_max_tables;
+extern uint krt_max_tables;
struct krt_params {
int table_id; /* Kernel table ID we sync with */