0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 01:31:55 +00:00

Merge branch 'master' into mq-filter-stack

This commit is contained in:
Maria Matejka 2019-07-10 11:27:08 +02:00
commit b2a4feeb4c
13 changed files with 134 additions and 82 deletions

View File

@ -2246,7 +2246,7 @@ using the following configuration parameters:
<tag><label id="bgp-dynamic-name">dynamic name "<m/text/"</tag> <tag><label id="bgp-dynamic-name">dynamic name "<m/text/"</tag>
Define common prefix of names used for new BGP instances spawned when Define common prefix of names used for new BGP instances spawned when
dynamic BGP behavior is active. Actual names also contain numberic dynamic BGP behavior is active. Actual names also contain numeric
index to distinguish individual instances. Default: "dynbgp". index to distinguish individual instances. Default: "dynbgp".
<tag><label id="bgp-dynamic-name">dynamic name digits <m/number/</tag> <tag><label id="bgp-dynamic-name">dynamic name digits <m/number/</tag>

View File

@ -631,6 +631,7 @@ int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath ne
static inline int nexthop_same(struct nexthop *x, struct nexthop *y) static inline int nexthop_same(struct nexthop *x, struct nexthop *y)
{ return (x == y) || nexthop__same(x, y); } { return (x == y) || nexthop__same(x, y); }
struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp); struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp);
struct nexthop *nexthop_sort(struct nexthop *x);
static inline void nexthop_link(struct rta *a, struct nexthop *from) static inline void nexthop_link(struct rta *a, struct nexthop *from)
{ memcpy(&a->nh, from, nexthop_size(from)); } { memcpy(&a->nh, from, nexthop_size(from)); }
void nexthop_insert(struct nexthop **n, struct nexthop *y); void nexthop_insert(struct nexthop **n, struct nexthop *y);

View File

@ -202,7 +202,7 @@ nexthop__same(struct nexthop *x, struct nexthop *y)
} }
static int static int
nexthop_compare_node(struct nexthop *x, struct nexthop *y) nexthop_compare_node(const struct nexthop *x, const struct nexthop *y)
{ {
int r; int r;
@ -320,6 +320,24 @@ nexthop_insert(struct nexthop **n, struct nexthop *x)
*n = x; *n = x;
} }
struct nexthop *
nexthop_sort(struct nexthop *x)
{
struct nexthop *s = NULL;
/* Simple insert-sort */
while (x)
{
struct nexthop *n = x;
x = n->next;
n->next = NULL;
nexthop_insert(&s, n);
}
return s;
}
int int
nexthop_is_sorted(struct nexthop *x) nexthop_is_sorted(struct nexthop *x)
{ {

View File

@ -880,6 +880,7 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
ifname, ifa->priority, new->priority); ifname, ifa->priority, new->priority);
ifa->priority = new->priority; ifa->priority = new->priority;
ospf_iface_sm(ifa, ISM_NEICH);
ospf_notify_link_lsa(ifa); ospf_notify_link_lsa(ifa);
} }

View File

@ -246,18 +246,33 @@ void
ospf_stop_gr_recovery(struct ospf_proto *p) ospf_stop_gr_recovery(struct ospf_proto *p)
{ {
p->gr_recovery = 0; p->gr_recovery = 0;
p->gr_cleanup = 1;
p->gr_timeout = 0; p->gr_timeout = 0;
channel_graceful_restart_unlock(p->p.main_channel);
/* Reorigination of router/network LSAs is already scheduled */ /* Reorigination of router/network LSAs is already scheduled */
ospf_mark_lsadb(p);
/* /* Rest is done in ospf_cleanup_gr_recovery() */
* NOTE: We should move channel_graceful_restart_unlock() to the end of }
* ospf_disp() in order to have local LSA reorigination / LSAdb cleanup /
* routing table recomputation before official end of GR. It does not matter static void
* when we are single-threaded. ospf_cleanup_gr_recovery(struct ospf_proto *p)
*/ {
struct top_hash_entry *en;
/* Flush dirty LSAa except external ones, these will be handled by feed */
WALK_SLIST(en, p->lsal)
if (en->gr_dirty)
{
if ((en->lsa_type == LSA_T_EXT) || (en->lsa_type == LSA_T_NSSA))
en->mode = LSA_M_EXPORT;
else
ospf_flush_lsa(p, en);
}
/* End graceful restart on channel, will also schedule feed */
channel_graceful_restart_unlock(p->p.main_channel);
p->gr_cleanup = 0;
} }
static int static int
@ -361,6 +376,8 @@ ospf_init(struct proto_config *CF)
P->ifa_notify = cf->ospf2 ? ospf_ifa_notify2 : ospf_ifa_notify3; P->ifa_notify = cf->ospf2 ? ospf_ifa_notify2 : ospf_ifa_notify3;
P->preexport = ospf_preexport; P->preexport = ospf_preexport;
P->reload_routes = ospf_reload_routes; P->reload_routes = ospf_reload_routes;
P->feed_begin = ospf_feed_begin;
P->feed_end = ospf_feed_end;
P->make_tmp_attrs = ospf_make_tmp_attrs; P->make_tmp_attrs = ospf_make_tmp_attrs;
P->store_tmp_attrs = ospf_store_tmp_attrs; P->store_tmp_attrs = ospf_store_tmp_attrs;
P->rte_better = ospf_rte_better; P->rte_better = ospf_rte_better;
@ -436,6 +453,7 @@ ospf_disp(timer * timer)
{ {
struct ospf_proto *p = timer->data; struct ospf_proto *p = timer->data;
/* Check for end of graceful restart */
if (p->gr_recovery) if (p->gr_recovery)
ospf_update_gr_recovery(p); ospf_update_gr_recovery(p);
@ -448,6 +466,10 @@ ospf_disp(timer * timer)
/* Calculate routing table */ /* Calculate routing table */
if (p->calcrt) if (p->calcrt)
ospf_rt_spf(p); ospf_rt_spf(p);
/* Cleanup after graceful restart */
if (p->gr_cleanup)
ospf_cleanup_gr_recovery(p);
} }

View File

@ -223,7 +223,8 @@ struct ospf_proto
int areano; /* Number of area I belong to */ int areano; /* Number of area I belong to */
int padj; /* Number of neighbors in Exchange or Loading state */ int padj; /* Number of neighbors in Exchange or Loading state */
int gr_count; /* Number of neighbors in graceful restart state */ int gr_count; /* Number of neighbors in graceful restart state */
int gr_recovery; /* Graceful restart recovery is active */ u8 gr_recovery; /* Graceful restart recovery is active */
u8 gr_cleanup; /* GR cleanup scheduled */
btime gr_timeout; /* The end time of grace restart recovery */ btime gr_timeout; /* The end time of grace restart recovery */
struct fib rtf; /* Routing table */ struct fib rtf; /* Routing table */
struct idm idm; /* OSPFv3 LSA ID map */ struct idm idm; /* OSPFv3 LSA ID map */

View File

@ -1640,7 +1640,7 @@ ospf_rt_reset(struct ospf_proto *p)
en->lb = IPA_NONE; en->lb = IPA_NONE;
if (en->mode == LSA_M_RTCALC) if (en->mode == LSA_M_RTCALC)
en->mode = LSA_M_STALE; en->mode = LSA_M_RTCALC_STALE;
} }
WALK_LIST(oa, p->area_list) WALK_LIST(oa, p->area_list)
@ -2117,7 +2117,7 @@ again2:
/* Cleanup stale LSAs */ /* Cleanup stale LSAs */
WALK_SLIST(en, p->lsal) WALK_SLIST(en, p->lsal)
if (en->mode == LSA_M_STALE) if (en->mode == LSA_M_RTCALC_STALE)
ospf_flush_lsa(p, en); ospf_flush_lsa(p, en);
} }

View File

@ -71,6 +71,7 @@ ospf_install_lsa(struct ospf_proto *p, struct ospf_lsa_header *lsa, u32 type, u3
en->lsa = *lsa; en->lsa = *lsa;
en->init_age = en->lsa.age; en->init_age = en->lsa.age;
en->inst_time = current_time(); en->inst_time = current_time();
en->gr_dirty = p->gr_recovery && (lsa->rt == p->router_id);
/* /*
* We do not set en->mode. It is either default LSA_M_BASIC, or in a special * We do not set en->mode. It is either default LSA_M_BASIC, or in a special
@ -246,7 +247,7 @@ ospf_do_originate_lsa(struct ospf_proto *p, struct top_hash_entry *en, void *lsa
en->lsa.age = 0; en->lsa.age = 0;
en->init_age = 0; en->init_age = 0;
en->inst_time = current_time(); en->inst_time = current_time();
en->dirty = 0; en->gr_dirty = 0;
lsa_generate_checksum(&en->lsa, en->lsa_body); lsa_generate_checksum(&en->lsa, en->lsa_body);
OSPF_TRACE(D_EVENTS, "Originating LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x", OSPF_TRACE(D_EVENTS, "Originating LSA: Type: %04x, Id: %R, Rt: %R, Seq: %08x",
@ -280,11 +281,15 @@ ospf_do_originate_lsa(struct ospf_proto *p, struct top_hash_entry *en, void *lsa
struct top_hash_entry * struct top_hash_entry *
ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa) ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa)
{ {
struct top_hash_entry *en; struct top_hash_entry *en = NULL;
void *lsa_body = p->lsab; void *lsa_body = p->lsab;
u16 lsa_blen = p->lsab_used; u16 lsa_blen = p->lsab_used;
u16 lsa_length = sizeof(struct ospf_lsa_header) + lsa_blen; u16 lsa_length = sizeof(struct ospf_lsa_header) + lsa_blen;
/* RFC 3623 2 (1) - do not originate topology LSAs during graceful restart */
if (p->gr_recovery && (LSA_FUNCTION(lsa->type) <= LSA_FUNCTION(LSA_T_NSSA)))
goto drop;
/* For OSPFv2 Opaque LSAs, LS ID consists of Opaque Type and Opaque ID */ /* For OSPFv2 Opaque LSAs, LS ID consists of Opaque Type and Opaque ID */
if (ospf_is_v2(p) && lsa_is_opaque(lsa->type)) if (ospf_is_v2(p) && lsa_is_opaque(lsa->type))
lsa->id |= (u32) lsa_get_opaque_type(lsa->type) << 24; lsa->id |= (u32) lsa_get_opaque_type(lsa->type) << 24;
@ -329,7 +334,7 @@ ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa)
(lsa_length == en->lsa.length) && (lsa_length == en->lsa.length) &&
!memcmp(lsa_body, en->lsa_body, lsa_blen) && !memcmp(lsa_body, en->lsa_body, lsa_blen) &&
(!ospf_is_v2(p) || (lsa->opts == lsa_get_options(&en->lsa))) && (!ospf_is_v2(p) || (lsa->opts == lsa_get_options(&en->lsa))) &&
!en->dirty) !en->gr_dirty)
goto drop; goto drop;
lsa_body = lsab_flush(p); lsa_body = lsab_flush(p);
@ -422,6 +427,7 @@ void
ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en) ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en)
{ {
en->nf = NULL; en->nf = NULL;
en->gr_dirty = 0;
if (en->next_lsa_body) if (en->next_lsa_body)
{ {
@ -520,12 +526,6 @@ ospf_update_lsadb(struct ospf_proto *p)
continue; continue;
} }
if (en->dirty)
{
ospf_flush_lsa(p, en);
continue;
}
if ((en->lsa.rt == p->router_id) && (real_age >= LSREFRESHTIME)) if ((en->lsa.rt == p->router_id) && (real_age >= LSREFRESHTIME))
{ {
ospf_refresh_lsa(p, en); ospf_refresh_lsa(p, en);
@ -543,14 +543,27 @@ ospf_update_lsadb(struct ospf_proto *p)
} }
void void
ospf_mark_lsadb(struct ospf_proto *p) ospf_feed_begin(struct channel *C, int initial UNUSED)
{ {
struct ospf_proto *p = (struct ospf_proto *) C->proto;
struct top_hash_entry *en; struct top_hash_entry *en;
/* Mark all local LSAs as dirty */ /* Mark all external LSAs as stale */
WALK_SLIST(en, p->lsal) WALK_SLIST(en, p->lsal)
if (en->lsa.rt == p->router_id) if (en->mode == LSA_M_EXPORT)
en->dirty = 1; en->mode = LSA_M_EXPORT_STALE;
}
void
ospf_feed_end(struct channel *C)
{
struct ospf_proto *p = (struct ospf_proto *) C->proto;
struct top_hash_entry *en;
/* Flush stale LSAs */
WALK_SLIST(en, p->lsal)
if (en->mode == LSA_M_EXPORT_STALE)
ospf_flush_lsa(p, en);
} }
static u32 static u32

View File

@ -33,7 +33,7 @@ struct top_hash_entry
u32 lb_id; /* Interface ID of link back iface (for bcast or NBMA networks) */ u32 lb_id; /* Interface ID of link back iface (for bcast or NBMA networks) */
u32 dist; /* Distance from the root */ u32 dist; /* Distance from the root */
int ret_count; /* Number of retransmission lists referencing the entry */ int ret_count; /* Number of retransmission lists referencing the entry */
u8 dirty; /* Will be flushed during next LSAdb update unless reoriginated*/ u8 gr_dirty; /* Local LSA received during GR, will be removed unless reoriginated */
u8 color; u8 color;
#define OUTSPF 0 #define OUTSPF 0
#define CANDIDATE 1 #define CANDIDATE 1
@ -118,7 +118,8 @@ struct top_hash_entry
#define LSA_M_BASIC 0 #define LSA_M_BASIC 0
#define LSA_M_EXPORT 1 #define LSA_M_EXPORT 1
#define LSA_M_RTCALC 2 #define LSA_M_RTCALC 2
#define LSA_M_STALE 3 #define LSA_M_EXPORT_STALE 3
#define LSA_M_RTCALC_STALE 4
/* /*
* LSA entry modes: * LSA entry modes:
@ -128,9 +129,13 @@ struct top_hash_entry
* routing table calculation is scheduled. This is also the mode used for LSAs * routing table calculation is scheduled. This is also the mode used for LSAs
* received from neighbors. Example: Router-LSAs, Network-LSAs. * received from neighbors. Example: Router-LSAs, Network-LSAs.
* *
* LSA_M_EXPORT - like LSA_M_BASIC, but the routing table calculation does not * LSA_M_EXPORT - The LSA is originated using ospf_originate_lsa() as a
* depend on the LSA. Therefore, the calculation is not scheduled when the LSA * consequence of route export to the OSPF instance. It has to be reoriginated
* is changed. Example: AS-external-LSAs for exported routes. * during each channel feed, otherwise it is flushed automatically at the end of
* the feed. May be originated and flushed asynchronously. Also, routing table
* calculation does not depend on the LSA. Therefore, the routing table
* calculation is not scheduled when the LSA is changed. Example:
* AS-external-LSAs for exported routes.
* *
* LSA_M_RTCALC - The LSA has to be requested using ospf_originate_lsa() during * LSA_M_RTCALC - The LSA has to be requested using ospf_originate_lsa() during
* each routing table calculation, otherwise it is flushed automatically at the * each routing table calculation, otherwise it is flushed automatically at the
@ -138,8 +143,11 @@ struct top_hash_entry
* source for it. Therefore, the calculation is not scheduled when the LSA is * source for it. Therefore, the calculation is not scheduled when the LSA is
* changed. Example: Summary-LSAs. * changed. Example: Summary-LSAs.
* *
* LSA_M_STALE - Temporary state for LSA_M_RTCALC that is not requested during * LSA_M_EXPORT_STALE - Temporary state for LSA_M_EXPORT that is not requested
* the current routing table calculation. * during current external route feed.
*
* LSA_M_RTCALC_STALE - Temporary state for LSA_M_RTCALC that is not requested
* during current routing table calculation.
* *
* *
* Note that we do not schedule the routing table calculation when the age of * Note that we do not schedule the routing table calculation when the age of
@ -181,7 +189,8 @@ struct top_hash_entry * ospf_originate_lsa(struct ospf_proto *p, struct ospf_new
void ospf_advance_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body); void ospf_advance_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_lsa_header *lsa, u32 type, u32 domain, void *body);
void ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en); void ospf_flush_lsa(struct ospf_proto *p, struct top_hash_entry *en);
void ospf_update_lsadb(struct ospf_proto *p); void ospf_update_lsadb(struct ospf_proto *p);
void ospf_mark_lsadb(struct ospf_proto *p); void ospf_feed_begin(struct channel *C, int initial);
void ospf_feed_end(struct channel *C);
static inline void ospf_flush2_lsa(struct ospf_proto *p, struct top_hash_entry **en) static inline void ospf_flush2_lsa(struct ospf_proto *p, struct top_hash_entry **en)
{ if (*en) { ospf_flush_lsa(p, *en); *en = NULL; } } { if (*en) { ospf_flush_lsa(p, *en); *en = NULL; } }

View File

@ -725,6 +725,10 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
nh = RTNH_NEXT(nh); nh = RTNH_NEXT(nh);
} }
/* Ensure nexthops are sorted to satisfy nest invariant */
if (!nexthop_is_sorted(first))
first = nexthop_sort(first);
return first; return first;
} }
@ -1393,10 +1397,10 @@ krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old)
} }
static int static int
nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint priority, uint krt_type) nl_mergable_route(struct nl_parse_state *s, net *net, struct krt_proto *p, uint priority, uint krt_type, uint rtm_family)
{ {
/* Route merging must be active */ /* Route merging is used for IPv6 scans */
if (!s->merge) if (!s->scan || (rtm_family != AF_INET6))
return 0; return 0;
/* Saved and new route must have same network, proto/table, and priority */ /* Saved and new route must have same network, proto/table, and priority */
@ -1433,12 +1437,11 @@ nl_announce_route(struct nl_parse_state *s)
} }
static inline void static inline void
nl_parse_begin(struct nl_parse_state *s, int scan, int merge) nl_parse_begin(struct nl_parse_state *s, int scan)
{ {
memset(s, 0, sizeof (struct nl_parse_state)); memset(s, 0, sizeof (struct nl_parse_state));
s->pool = nl_linpool; s->pool = nl_linpool;
s->scan = scan; s->scan = scan;
s->merge = merge;
} }
static inline void static inline void
@ -1581,7 +1584,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
net *net = net_get(p->p.main_channel->table, n); net *net = net_get(p->p.main_channel->table, n);
if (s->net && !nl_mergable_route(s, net, p, priority, i->rtm_type)) if (s->net && !nl_mergable_route(s, net, p, priority, i->rtm_type, i->rtm_family))
nl_announce_route(s); nl_announce_route(s);
rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE); rta *ra = lp_allocz(s->pool, RTA_MAX_SIZE);
@ -1817,34 +1820,14 @@ krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NUL
struct nlmsghdr *h; struct nlmsghdr *h;
struct nl_parse_state s; struct nl_parse_state s;
nl_parse_begin(&s, 1, 0); nl_parse_begin(&s, 1);
nl_request_dump(AF_INET, RTM_GETROUTE); nl_request_dump(AF_UNSPEC, RTM_GETROUTE);
while (h = nl_get_scan()) while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE) if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
nl_parse_route(&s, h); nl_parse_route(&s, h);
else else
log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type); log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
nl_parse_end(&s); nl_parse_end(&s);
nl_parse_begin(&s, 1, 1);
nl_request_dump(AF_INET6, RTM_GETROUTE);
while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
nl_parse_route(&s, h);
else
log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
nl_parse_end(&s);
#ifdef HAVE_MPLS_KERNEL
nl_parse_begin(&s, 1, 1);
nl_request_dump(AF_MPLS, RTM_GETROUTE);
while (h = nl_get_scan())
if (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)
nl_parse_route(&s, h);
else
log(L_DEBUG "nl_scan_fire: Unknown packet received (type=%d)", h->nlmsg_type);
nl_parse_end(&s);
#endif
} }
/* /*
@ -1864,7 +1847,7 @@ nl_async_msg(struct nlmsghdr *h)
case RTM_NEWROUTE: case RTM_NEWROUTE:
case RTM_DELROUTE: case RTM_DELROUTE:
DBG("KRT: Received async route notification (%d)\n", h->nlmsg_type); DBG("KRT: Received async route notification (%d)\n", h->nlmsg_type);
nl_parse_begin(&s, 0, 0); nl_parse_begin(&s, 0);
nl_parse_route(&s, h); nl_parse_route(&s, h);
nl_parse_end(&s); nl_parse_end(&s);
break; break;

View File

@ -309,14 +309,23 @@ die(const char *msg, ...)
void void
debug(const char *msg, ...) debug(const char *msg, ...)
{ {
#define MAX_DEBUG_BUFSIZE 65536
va_list args; va_list args;
char buf[1024]; static uint bufsize = 4096;
static char *buf = NULL;
if (!buf)
buf = mb_alloc(&root_pool, bufsize);
va_start(args, msg); va_start(args, msg);
if (dbgf) if (dbgf)
{ {
if (bvsnprintf(buf, sizeof(buf), msg, args) < 0) while (bvsnprintf(buf, bufsize, msg, args) < 0)
bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n"); if (bufsize >= MAX_DEBUG_BUFSIZE)
bug("Extremely long debug output, split it.");
else
buf = mb_realloc(buf, (bufsize *= 2));
fputs(buf, dbgf); fputs(buf, dbgf);
} }
va_end(args); va_end(args);

View File

@ -44,23 +44,17 @@ int bt_result; /* Overall program run result */
int bt_suite_result; /* One suit result */ int bt_suite_result; /* One suit result */
char bt_out_fmt_buf[1024]; /* Temporary memory buffer for output of testing function */ char bt_out_fmt_buf[1024]; /* Temporary memory buffer for output of testing function */
long int u64 bt_random_state[] = {
bt_random(void) 0x80241f302bd4d95d, 0xd10ba2e910f772b, 0xea188c9046f507c5, 0x4c4c581f04e6da05,
{ 0x53d9772877c1b647, 0xab8ce3eb466de6c5, 0xad02844c8a8e865f, 0xe8cc78080295065d
/* Seeded in bt_init() */ };
long int rand_low, rand_high;
rand_low = random();
rand_high = random();
return (rand_low & 0xffff) | ((rand_high & 0xffff) << 16);
}
void void
bt_init(int argc, char *argv[]) bt_init(int argc, char *argv[])
{ {
int c; int c;
srandom(BT_RANDOM_SEED); initstate(BT_RANDOM_SEED, (char *) bt_random_state, sizeof(bt_random_state));
bt_verbose = 0; bt_verbose = 0;
bt_filename = argv[0]; bt_filename = argv[0];

View File

@ -33,7 +33,8 @@ extern const char *bt_test_id;
void bt_init(int argc, char *argv[]); void bt_init(int argc, char *argv[]);
int bt_exit_value(void); int bt_exit_value(void);
int bt_test_suite_base(int (*test_fn)(const void *), const char *test_id, const void *test_fn_argument, int forked, int timeout, const char *dsc, ...); int bt_test_suite_base(int (*test_fn)(const void *), const char *test_id, const void *test_fn_argument, int forked, int timeout, const char *dsc, ...);
long int bt_random(void); static inline u64 bt_random(void)
{ return ((u64) random() & 0xffffffff) | ((u64) random() << 32); }
void bt_log_suite_result(int result, const char *fmt, ...); void bt_log_suite_result(int result, const char *fmt, ...);
void bt_log_suite_case_result(int result, const char *fmt, ...); void bt_log_suite_case_result(int result, const char *fmt, ...);
@ -41,7 +42,7 @@ void bt_log_suite_case_result(int result, const char *fmt, ...);
#define BT_TIMEOUT 5 /* Default timeout in seconds */ #define BT_TIMEOUT 5 /* Default timeout in seconds */
#define BT_FORKING 1 /* Forking is enabled in default */ #define BT_FORKING 1 /* Forking is enabled in default */
#define BT_RANDOM_SEED 982451653 #define BT_RANDOM_SEED 0x5097d2bb
#define BT_BUFFER_SIZE 10000 #define BT_BUFFER_SIZE 10000