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 */