Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ add_executable(ef-tests
test/test-alloc-free.cxx
test/test-mld-zero-width.cxx
test/test-rate-limit.cxx
test/test-rx-ign.cxx
)
target_compile_options(ef-tests PRIVATE ${EF_SANITIZE_FLAGS})

Expand Down
17 changes: 16 additions & 1 deletion src/ef-args.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,12 @@ void print_help() {
po(" rx: Specify a frame which is expected to be received. If no \n");
po(" frame is specified, then the expectation is that no\n");
po(" frames are received on the interface. Syntax:\n");
po(" rx <interface> [FRAME] | help\n");
po(" rx <interface> [ign] [FRAME] | help\n");
po(" With 'ign', matching frames are silently ignored (no RX-ERR)\n");
po(" and no error is reported if the frame never arrives (no NO-RX).\n");
po(" Frames longer than the pattern also match (trailing bytes are\n");
po(" ignored), so the pattern only needs to cover the fixed headers.\n");
po(" Useful for filtering known noise (IPv6 RA/RS, HSR supervision).\n");
po("\n");
po(" hex: Print a frame on stdout as a hex string. Syntax:\n");
po(" hex FRAME\n");
Expand Down Expand Up @@ -261,6 +266,12 @@ int argc_cmd(int argc, const char *argv[], cmd_t *c) {
;
}

if (c->type == CMD_TYPE_RX && i < argc &&
(strcmp(argv[i], "ign") == 0 || strcmp(argv[i], "ignore") == 0)) {
c->rx_ign = 1;
i += 1;
}

if (c->type == CMD_TYPE_TX) {
int rep_given = 0, kw;

Expand Down Expand Up @@ -349,6 +360,10 @@ int argc_cmd(int argc, const char *argv[], cmd_t *c) {

if (c->frame->has_mask)
c->frame_mask_buf = frame_mask_to_buf(c->frame);

c->frame_size_no_padding = 0;
for (int k = 0; k < c->frame->stack_size; ++k)
c->frame_size_no_padding += c->frame->stack[k]->size;
}

i += res;
Expand Down
62 changes: 50 additions & 12 deletions src/ef-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,16 @@ int pfds_process(cmd_socket_t *resources, int res_valid, struct pollfd *pfds,
}
}

// Try to match the frame agains expected frames
// Try to match against expected (non-ign) rx commands first
match = 0;
for (cmd_ptr = resources[i].cmd; cmd_ptr; cmd_ptr = cmd_ptr->next) {

if (!cmd_ptr->frame_buf)
continue;

if (cmd_ptr->rx_ign)
continue;

if (cmd_ptr->done)
continue;

Expand All @@ -472,20 +475,52 @@ int pfds_process(cmd_socket_t *resources, int res_valid, struct pollfd *pfds,
}
}

// If no regular match, try ign rx commands
if (!match) {
for (cmd_ptr = resources[i].cmd; cmd_ptr;
cmd_ptr = cmd_ptr->next) {
if (!cmd_ptr->frame_buf)
continue;

if (!cmd_ptr->rx_ign)
continue;

size_t hdr_len = cmd_ptr->frame_size_no_padding;
if (hdr_len == 0 || b->size < hdr_len)
continue;

size_t orig_b = b->size;
size_t orig_f = cmd_ptr->frame_buf->size;
b->size = hdr_len;
cmd_ptr->frame_buf->size = hdr_len;
int m = bequal_mask(b, cmd_ptr->frame_buf,
cmd_ptr->frame_mask_buf, 0);
cmd_ptr->frame_buf->size = orig_f;
b->size = orig_b;
if (m) {
match = 1;
// Don't mark done as ign absorbs multiple frames
break;
}
}
}

if (match) {
po("RX-OK %16s: ", cmd_ptr->arg0);
if (cmd_ptr->name) {
po("name %s", cmd_ptr->name);
} else {
print_hex_str(1, b->data, b->size);
if (cmd_ptr->frame_mask_buf) {
po("\nRX-OK MASK: ");
print_hex_str(1, cmd_ptr->frame_mask_buf->data,
cmd_ptr->frame_mask_buf->size);
po("\n");
if (!cmd_ptr->rx_ign) {
po("RX-OK %16s: ", cmd_ptr->arg0);
if (cmd_ptr->name) {
po("name %s", cmd_ptr->name);
} else {
print_hex_str(1, b->data, b->size);
if (cmd_ptr->frame_mask_buf) {
po("\nRX-OK MASK: ");
print_hex_str(1, cmd_ptr->frame_mask_buf->data,
cmd_ptr->frame_mask_buf->size);
po("\n");
}
}
po("\n");
}
po("\n");
} else {
resources[i].rx_err_cnt ++;
pe("RX-ERR %16s: ", resources[i].cmd->arg0);
Expand Down Expand Up @@ -838,6 +873,9 @@ int exec_cmds(int cnt, cmd_t *cmds) {
if (cmd_ptr->type != CMD_TYPE_RX)
continue;

if (cmd_ptr->rx_ign)
continue;

if (!cmd_ptr->frame_buf)
continue;

Expand Down
3 changes: 3 additions & 0 deletions src/ef.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ typedef struct cmd {
buf_t *frame_mask_buf;
int done;
int rep_explicit; // user passed 'rep N' (rate-without-rep is 0)
int rx_ign; // rx ignore: match silently, never fail
size_t frame_size_no_padding;
uint32_t repeat;

uint32_t rate_pps; // 0 = unlimited
Expand Down Expand Up @@ -389,6 +391,7 @@ void txring_close(cmd_t *c);
void print_hex_str(int fd, void *_d, int s);

int argc_frame(int argc, const char *argv[], frame_t *f);
int argc_cmd(int argc, const char *argv[], cmd_t *c);
void cmd_destruct(cmd_t *c);

void print_help();
Expand Down
Loading