Commit e9af8b78 authored by Alessandro Rubini's avatar Alessandro Rubini Committed by Adam Wujek

arch-wrpc: add fault-injection tool

Currently it only exports the rxdrop/txdrop feature.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent c62a6257
......@@ -197,3 +197,11 @@ config OPTIMIZATION
int
default 0 if DISABLE_OPTIMIZATION
default 2
config WRPC_FAULTS
bool "Add the fault injection mechanism and shell command for wrpc"
depends on ARCH_WRPC
help
This adds a "fault" shell command, with subcommands.
The same mechanisms are available in the wr switch, through
the configuration file.
......@@ -23,8 +23,11 @@ OBJ-y += \
$A/wrpc-calibration.o \
$A/wrc_ptp_ppsi.o \
lib/dump-funcs.o \
lib/drop.o \
lib/div64.o
OBJ-$(CONFIG_WRPC_FAULTS) += $A/faults.o
# We only support "wrpc" time operations
TIME := wrpc
include time-wrpc/Makefile
......
/*
* Copyright (C) 2017 GSI (www.gsi.de)
* Author: Alessandro Rubini
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <ppsi/ppsi.h>
#include "wrpc.h"
#include <errno.h>
#include "shell.h"
#include "syscon.h"
extern struct pp_instance ppi_static;
static int cmd_fault(const char *args[])
{
struct pp_globals *ppg = ppi_static.glbs;
if (args[0] && !strcmp(args[0], "drop")) {
if (args[1])
fromdec(args[1], &ppg->rxdrop);
if (args[2])
fromdec(args[2], &ppg->txdrop);
ppsi_drop_init(ppg, timer_get_tics());
pp_printf("dropping %i/1000 rx, %i/1000 tx\n",
ppg->rxdrop, ppg->txdrop);
return 0;
}
pp_printf("Use: \"fault drop [<rxdrop> <txdrop>]\" (0..999)\n");
return -EINVAL;
}
DEFINE_WRC_COMMAND(fault) = {
.name = "fault",
.exec = cmd_fault,
};
......@@ -57,6 +57,8 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
struct wr_sockaddr addr;
sock = ppi->ch[PP_NP_EVT].custom;
got = ptpd_netif_recvfrom(sock, &addr, pkt, len, &wr_ts);
if (got <= 0)
return got;
if (t) {
t->secs = wr_ts.sec;
......@@ -69,17 +71,21 @@ static int wrpc_net_recv(struct pp_instance *ppi, void *pkt, int len,
/* wrpc-sw may pass this in USER_CFLAGS, to remove footprint */
#ifndef CONFIG_NO_PTPDUMP
/* The header is separate, so dump payload only */
if (got > 0 && pp_diag_allow(ppi, frames, 2))
if (pp_diag_allow(ppi, frames, 2))
dump_payloadpkt("recv: ", pkt, got, t);
#endif
if (ppsi_drop_rx()) {
pp_diag(ppi, frames, 1, "Drop received frame\n");
return -2;
}
return got;
}
static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
int msgtype)
{
int snt;
int snt, drop;
struct wrpc_socket *sock;
struct wr_timestamp wr_ts;
struct wr_sockaddr addr;
......@@ -90,10 +96,21 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
[PP_P2P_MECH] = PP_PDELAY_MACADDRESS,
};
/*
* To fake a packet loss, we must corrupt the frame; we need
* to transmit it for real, if we want to get back our
* hardware stamp. Thus, remember if we drop, and use this info.
*/
drop = ppsi_drop_tx();
sock = ppi->ch[PP_NP_EVT].custom;
addr.ethertype = htons(ETH_P_1588);
memcpy(&addr.mac, macaddr[is_pdelay], sizeof(mac_addr_t));
if (drop) {
addr.ethertype = 1;
addr.mac[0] = 0x22; /* pfilter uses mac; drop for nodes too */
}
snt = ptpd_netif_sendto(sock, &addr, pkt, len, &wr_ts);
......@@ -107,6 +124,11 @@ static int wrpc_net_send(struct pp_instance *ppi, void *pkt, int len,
__func__, snt, (long)t->secs,
(long)(t->scaled_nsecs >> 16));
}
if (drop) {
pp_diag(ppi, frames, 1, "Drop sent frame\n");
return -2;
}
/* wrpc-sw may pass this in USER_CFLAGS, to remove footprint */
#ifndef CONFIG_NO_PTPDUMP
/* The header is separate, so dump payload only */
......
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