Commit c37c1bd4 authored by Adam Wujek's avatar Adam Wujek 💬

[Feature: 1055] userspace/tools: add unrec command to rtu_stat

Add command to enable/disable dropping of frames which destination MAC
address does not match to present RTU rules.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent fb9f2499
......@@ -77,6 +77,14 @@ int rtudexp_learning_process(int operation, int enable, int port_mask)
return (ret < 0) ? ret : val;
}
int rtudexp_unrec(int operation, int enable, int port_mask)
{
int val, ret;
ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_unrec, &val,
operation, enable, port_mask);
return (ret < 0) ? ret : val;
}
int rtudexp_vlan_entry(int vid, int fid, const char *ch_mask, int drop,
int prio, int has_prio, int prio_override)
{
......@@ -150,6 +158,15 @@ void show_help(char *prgname)
" ports\n");
fprintf(stderr, " learning <enable|disable> mask <port_mask>: Enable/disable learning process\n"
" in RTU for ports given as a mask\n");
fprintf(stderr, " unrec: Status of dropping packets when destination MAC is not\n"
" matched\n");
fprintf(stderr, " unrec <enable|disable> [<port>]: Enable/disable dropping packets when\n"
" the destination MAC is not matched.\n"
" Apply setting on a given <port> or all ports\n"
" when <port> is not provided.\n");
fprintf(stderr, " unrec mask <enable|disable> <port_mask>: Enable/disable dropping packets when\n"
" the destination MAC is not matched.\n"
" Apply setting on ports given as a mask\n");
fprintf(stderr, " vlan <vid> <fid> <port_mask> [<drop>, <prio>, <has_prio>, <prio_override>]:\n"
" Add VLAN entry with vid, fid, mask and drop flag;\n"
" write mask=0x0 and drop=1 to remove the VLAN\n");
......@@ -655,6 +672,106 @@ int main(int argc, char **argv)
}
/* Don't do anything more */
return 0;
/* ****************** unrec <enable|disable> mask <port_mask> *********** */
} else if (argc >= 5
&& strcmp(argv[1], "unrec") == 0
&& strcmp(argv[3], "mask") == 0) {
if (!strcmp(argv[2], "enable"))
enable = RTU_UNREC_ENABLE;
else if (!strcmp(argv[2], "disable"))
enable = RTU_UNREC_DISABLE;
else {
fprintf(stderr, "rtu_stat: expected \"enable\""
" or \"disable\"\n");
exit(1);
}
mask = 0;
if (!strcmp(argv[4], "ALL")
|| !strcmp(argv[4], "all")) {
mask = (1 << (nports + 1)) - 1;
} else {
i = strtol(argv[4], NULL, 0);
/* interface number 1..18 */
if (0 < i && i <= ((1 << nports) - 1)) {
mask = i;
}
}
/* interface number 1..18, CPU is 19 */
if (mask == 0) {
printf("Wrong port mask 0x%s\n", argv[4]);
exit(1);
}
ret = rtudexp_unrec(RTU_SET_UNREC, /* oper */
enable, /* enable */
mask /* port_mask */
);
if (ret > 0)
printf("Update of unrec state change successful\n");
if (ret < 0) {
printf("Could not change unrec state 0x%x\n", ret);
exit(1);
}
/* Don't do anything more */
return 0;
/* ****************** unrec <enable|disable> [<port>] ******************* */
} else if (argc >= 3
&& strcmp(argv[1], "unrec") == 0) {
if (!strcmp(argv[2], "enable"))
enable = RTU_UNREC_ENABLE;
else if (!strcmp(argv[2], "disable"))
enable = RTU_UNREC_DISABLE;
else {
fprintf(stderr, "rtu_stat: expected \"enable\""
" or \"disable\"\n");
exit(1);
}
if (argc >= 4) { /* port defined */
i = strtol(argv[3], NULL, 0);
/* interface number 1..18*/
if (1 > i || i > nports) { /* 18 ports */
printf("Wrong port %s\n", argv[3]);
exit(1);
}
mask = 1 << (i - 1);
} else { /* port undefined, use as all */
mask = (1 << (nports)) - 1;
}
ret = rtudexp_unrec(RTU_SET_UNREC, /* oper */
enable, /* enable */
mask /* port_mask */
);
if (ret > 0)
printf("Update of unrec state change successful\n");
if (ret < 0) {
printf("Could not change unrec state 0x%x\n", ret);
exit(1);
}
/* Don't do anything more */
return 0;
/* ****************** unrec ************************************************ */
} else if (argc >= 2
&& strcmp(argv[1], "unrec") == 0) {
ret = rtudexp_unrec(RTU_GET_UNREC, /* oper */
0, /* enable */
(1 << nports) - 1 /* port_mask */
);
if (ret < 0) {
printf("Could not read unrec state 0x%x\n", ret);
exit(1);
}
printf("Dropping packets when the destination MAC is not "
"matched\n");
printf("-------------\n");
printf("Port | Drop\n");
printf("-------------\n");
for (i = 0; i < nports; i++) {
printf(" %2d %s\n", i + 1,
(ret & 1) ? "enabled" : "disabled");
ret >>= 1;
}
/* Don't do anything more */
return 0;
/* ****************** vlan <vid> <fid> <port_mask>
* [<drop>, <prio>, <has_prio>, <prio_override>] *** */
} else if (argc >= 5
......
......@@ -599,6 +599,19 @@ int rtu_set_unrecognised_behaviour_on_port(int port, int flag)
return 0;
}
/**
* \brief Gets the B_UNREC flag on indicated port.
* @param port port number (0 to 9)
* @return error code.
*/
int rtu_read_unrecognised_behaviour_on_port(int port)
{
if ((port < MIN_PORT) || (port > MAX_PORT))
return -EINVAL;
return read_pcr(port) & RTU_PCR_B_UNREC ? 1 : 0;
}
//---------------------------------------------
// Private Methods
//---------------------------------------------
......
......@@ -88,6 +88,7 @@ int rtu_pass_all_on_port(int port, int pass_all)
__attribute__ ((warn_unused_result));
int rtu_set_unrecognised_behaviour_on_port(int port, int flag)
__attribute__ ((warn_unused_result));
int rtu_read_unrecognised_behaviour_on_port(int port);
// IRQs
......
......@@ -214,6 +214,70 @@ int rtudexp_learning_process(const struct minipc_pd *pd, uint32_t * args,
return *p_ret;
}
int rtudexp_unrec(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
int oper;
int enable;
uint32_t port_mask;
int *p_ret = (int *)ret; /* force pointed to int type */
uint32_t unrec_mask = 0;
int i;
int local_ret;
oper = (int)args[0];
enable = (int)args[1];
port_mask = (int)args[2];
*p_ret = 0;
pr_debug("Request for unrec state\n");
if (1 > port_mask || port_mask > 0x3ffff) { /* 18 ports */
pr_error("Wrong port mask 0x%x\n", port_mask);
*p_ret = -1;
return *p_ret;
}
switch (oper) {
case RTU_GET_UNREC:
for (i = 0; i < 18; i++) {
if ((port_mask >> i) & 1) {
local_ret =
rtu_read_unrecognised_behaviour_on_port(i);
if (local_ret < 0) {
*p_ret = local_ret;
return *p_ret;
}
unrec_mask |= local_ret << i;
}
}
*p_ret = unrec_mask;
pr_debug("Unrec state mask 0x%x\n", unrec_mask);
break;
case RTU_SET_UNREC:
for (i = 0; i < 18; i++) {
if ((port_mask >> i) & 1) {
pr_debug("Request to change unrec "
"state for port %d (wri%d)\n",
i + 1, i + 1);
local_ret =
rtu_set_unrecognised_behaviour_on_port(
i,
enable);
if (local_ret < 0) {
*p_ret = local_ret;
return *p_ret;
}
(*p_ret)++;
}
}
break;
default:
pr_error("Wrong operation for unrec process %d\n", oper);
*p_ret = -1;
return *p_ret;
}
return *p_ret;
}
int rtudexp_vlan_entry(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
int vid, fid, mask, drop, prio, has_prio, prio_override;
......@@ -248,6 +312,7 @@ int rtud_init_exports()
MINIPC_EXP_FUNC(rtud_export_add_entry, rtudexp_add_entry);
MINIPC_EXP_FUNC(rtud_export_remove_entry, rtudexp_remove_entry);
MINIPC_EXP_FUNC(rtud_export_learning_process, rtudexp_learning_process);
MINIPC_EXP_FUNC(rtud_export_unrec, rtudexp_unrec);
MINIPC_EXP_FUNC(rtud_export_vlan_entry, rtudexp_vlan_entry);
return 0;
......
......@@ -36,6 +36,11 @@
#define RTU_SET_LEARNING 1
#define RTU_GET_LEARNING 2
#define RTU_UNREC_ENABLE 1
#define RTU_UNREC_DISABLE 0
#define RTU_SET_UNREC 1
#define RTU_GET_UNREC 2
/* Export of a function to set remove entry in rtu */
struct minipc_pd rtud_export_clear_entries = {
.name = "clear_entries",
......@@ -83,6 +88,19 @@ struct minipc_pd rtud_export_learning_process = {
},
};
/* Export of a function to get status or enable/disable of dropping packets when
* the destination MAC is not matched */
struct minipc_pd rtud_export_unrec = {
.name = "unrec",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* operation */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* enable/disable */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* port mask */
MINIPC_ARG_END,
},
};
/* Export of a function to add vlan entry in rtu */
struct minipc_pd rtud_export_vlan_entry = {
......
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