Commit 81f711b8 authored by Alessandro Rubini's avatar Alessandro Rubini

Add frame dropping support; use it in arch-unix

This adds frame dropping as a fault-injection mechanism. It activates
it for arch-unix in the same commit, because I tested it.

Not documented yet.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent ae9871e7
......@@ -7,10 +7,12 @@ CFLAGS += -Itools
OBJ-y += $A/unix-startup.o \
$A/main-loop.o \
$A/unix-io.o \
$A/unix-conf.o \
lib/cmdline.o \
lib/conf.o \
lib/libc-functions.o \
lib/dump-funcs.o \
lib/drop.o \
lib/div64.o
# The user can set TIME=, but we pick unix time by default
......
/*
* Copyright (C) 2014 CERN (www.cern.ch)
* Author: Alessandro Rubini
*
* Released according to GNU LGPL, version 2.1 or any later
*/
#include <ppsi/ppsi.h>
static int f_rxdrop(int lineno, struct pp_globals *ppg, union pp_cfg_arg *arg)
{
ppg->rxdrop = arg->i;
return 0;
}
static int f_txdrop(int lineno, struct pp_globals *ppg, union pp_cfg_arg *arg)
{
ppg->txdrop = arg->i;
return 0;
}
struct pp_argline pp_arch_arglines[] = {
{ f_rxdrop, "rx-drop", ARG_INT},
{ f_txdrop, "tx-drop", ARG_INT},
{}
};
......@@ -17,6 +17,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/timex.h>
#include <ppsi/ppsi.h>
......@@ -34,6 +35,7 @@ int main(int argc, char **argv)
{
struct pp_globals *ppg;
struct pp_instance *ppi;
unsigned long seed;
struct timex t;
int i;
......@@ -103,6 +105,11 @@ int main(int argc, char **argv)
pp_init_globals(ppg, &__pp_default_rt_opts);
seed = time(NULL);
if (getenv("PPSI_DROP_SEED"))
seed = atoi(getenv("PPSI_DROP_SEED"));
ppsi_drop_init(ppg, seed);
unix_main_loop(ppg);
return 0; /* never reached */
}
......@@ -12,6 +12,7 @@ OBJ-y += $A/wrs-startup.o \
lib/conf.o \
lib/libc-functions.o \
lib/dump-funcs.o \
lib/drop.o \
lib/div64.o
# The user can set TIME=, but wrs is default
......
......@@ -213,6 +213,8 @@ struct pp_globals {
int max_links;
struct pp_globals_cfg cfg;
int rxdrop, txdrop; /* fault injection, per thousand */
void *arch_data; /* if arch needs it */
/* FIXME Here include all is common to many interfaces */
};
......
......@@ -389,4 +389,9 @@ extern pp_action pp_initializing, pp_faulty, pp_disabled, pp_listening,
/* The engine */
extern int pp_state_machine(struct pp_instance *ppi, uint8_t *packet, int plen);
/* Frame-drop support -- rx before tx, alphabetically */
extern void ppsi_drop_init(struct pp_globals *ppg, unsigned long seed);
extern int ppsi_drop_rx(void);
extern int ppsi_drop_tx(void);
#endif /* __PPSI_PPSI_H__ */
/*
* Copyright (C) 2014 CERN (www.cern.ch)
* Authors: Alessandro Rubini
*
* Released according to the GNU LGPL, version 2.1 or any later version.
*/
#include <ppsi/ppsi.h>
/* Always rx before tx (alphabetic) */
struct ppsi_drop {
unsigned long rxrand, txrand;
int rxrate, txrate;
};
static struct ppsi_drop d;
static inline unsigned long drop_this(unsigned long *p, int rate)
{
/* hash the value, according to the TYPE_0 rule of glibc */
*p = ((*p * 1103515245) + 12345) & 0x7fffffff;
return (*p % 1000) < rate;
}
void ppsi_drop_init(struct pp_globals *ppg, unsigned long seed)
{
/* lazily, avoid passing globals every time */
d.rxrand = seed;
d.txrand = seed + 1;
d.rxrate = ppg->rxdrop;
d.txrate = ppg->txdrop;
}
int ppsi_drop_rx(void)
{
if (d.rxrate)
return drop_this(&d.rxrand, d.rxrate);
return 0;
}
int ppsi_drop_tx(void)
{
if (d.txrate)
return drop_this(&d.txrand, d.txrate);
return 0;
}
......@@ -87,6 +87,12 @@ static int unix_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
*/
ppi->t_ops->get(ppi, t);
}
if (ppsi_drop_rx()) {
pp_diag(ppi, frames, 1, "Drop received frame\n");
return -2;
}
/* This is not really hw... */
pp_diag(ppi, time, 2, "recv stamp: %i.%09i (%s)\n",
(int)t->seconds, (int)t->nanoseconds, tv ? "kernel" : "user");
......@@ -132,6 +138,14 @@ static int unix_net_send(struct pp_instance *ppi, void *pkt, int len,
struct ethhdr *hdr = pkt;
int ret;
/* To fake a network frame loss, set the timestamp and do not send */
if (ppsi_drop_tx()) {
if (t)
ppi->t_ops->get(ppi, t);
pp_diag(ppi, frames, 1, "Drop sent frame\n");
return len;
}
if (ppi->ethernet_mode) {
hdr->h_proto = htons(ETH_P_1588);
......@@ -358,6 +372,7 @@ static int unix_net_init(struct pp_instance *ppi)
if (unix_open_ch(ppi, ppi->iface_name, i))
return -1;
}
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment