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

[Feature: 1262] userspace/wrsw_rtud: support of removing rtu entries

wrsw_rtud:
--remove "force" param for minipc call rtudexp_clear_entries
--pass port mask instead of port number for minipc call rtudexp_add_entry

rtu_stat:
--add a possibility to add RTU rules for a given port mask
--add a possibility to remove single RTU rule
--add a possibility to remove RTU rule for a given port mask
--add verifying of MAC address
--improve help
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent 63d762f1
......@@ -1632,6 +1632,7 @@ the processes (excluding the @sc{rt} subsystem).
@item rtud::clear_entries
@itemx rtud::add_entry
@itemx rtud::remove_entry
Called by @i{rtu_stat} when performing actions.
......
This diff is collapsed.
......@@ -551,6 +551,52 @@ static void rtu_fd_age_update(void)
}
static int is_unicast(uint32_t port_mask)
{
return port_mask && !(port_mask & (port_mask - 1));
}
int rtu_fd_remove_entry(uint8_t *mac, uint32_t port_mask, int type)
{
int i; /* loop index */
int j; /* bucket loop index */
struct rtu_filtering_entry *ent; /* pointer to scan tables */
int removed_entries = 0;
if (!port_mask)
pr_error("Empty port mask for MAC %s\n", mac_to_string(mac));
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_BEGIN);
pr_debug("Looking for an entry with mask=0x%x MAC: %s type %s\n",
port_mask, mac_to_string(mac),
rtu_type_to_str(type));
for (i = HTAB_ENTRIES; i-- > 0;) {
for (j = RTU_BUCKETS; j-- > 0;) {
ent = &rtu_htab[i][j];
if (ent->valid
&& (ent->dynamic == type)
&& !memcmp(ent->mac, mac, ETH_ALEN)
&& (ent->port_mask_dst == port_mask)) {
/* entry is _only_ for this port */
hw_request(HW_REMOVE_REQ, ent->addr,
ent);
pr_info("Cleaning %s entry for mask=0x%x MAC: "
"%s type %s\n",
is_unicast(port_mask) ?
"unicast" : "multicast",
ent->port_mask_dst,
mac_to_string(ent->mac),
rtu_type_to_str(type));
removed_entries++;
}
}
}
/* commit changes */
rtu_fd_commit();
wrs_shm_write(rtu_port_shmem, WRS_SHM_WRITE_END);
return removed_entries;
}
void rtu_fd_clear_entries_for_port(int dest_port)
{
int i; // loop index
......
......@@ -58,6 +58,7 @@ int rtu_fd_set_aging_time(unsigned long t) __attribute__ ((warn_unused_result));
void rtu_fd_set_hash_poly(uint16_t poly);
void rtu_fd_flush(void);
void rtu_fd_clear_entries_for_port(int dest_port);
int rtu_fd_remove_entry(uint8_t *mac, uint32_t port_mask, int type);
void rtu_fd_create_vlan_entry(int vid, uint32_t port_mask, uint8_t fid,
uint8_t prio, int has_prio, int prio_override,
......
......@@ -50,13 +50,25 @@ static struct minipc_ch *rtud_ch;
int rtudexp_clear_entries(const struct minipc_pd *pd,
uint32_t * args, void *ret)
{
int iface_num = (int)args[0];
int *p_ret = (int *)ret; //force pointed to int type
pr_debug("Removing dynamic entries on interface %d (wri%d)\n",
iface_num + 1, iface_num + 1);
rtu_fd_clear_entries_for_port(iface_num);
int port = (int)args[0];
int type = (int)args[1];
int *p_ret = (int *)ret; /* force pointed to int type */
if (0 > port || port > 18) { /* 18 ports + CPU */
pr_error("Wrong port mask 0x%x\n", port);
*p_ret = -1;
return *p_ret;
}
if (rtu_check_type(type)) {
pr_error("Unknown type %d\n", type);
*p_ret = -1;
return *p_ret;
}
pr_debug("Removing %s entries on interface %d (wri%d)\n",
rtu_type_to_str(type),
port + 1, port + 1);
rtu_fd_clear_entries_for_port(port, type);
*p_ret = 0;
return *p_ret;
}
......@@ -64,28 +76,78 @@ int rtudexp_clear_entries(const struct minipc_pd *pd,
int rtudexp_add_entry(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
uint8_t mac_tmp[ETH_ALEN] = { 0 };
char *mac;
uint32_t port_mask;
int type;
int *p_ret = (int *)ret; /* force pointed to int type */
char *strEHA;
int port, mode;
int *p_ret = (int *)ret; //force pointed to int type
strEHA = (char *)args;
mac = (char *)args;
args = minipc_get_next_arg(args, pd->args[0]);
port = (int)args[0];
mode = (int)args[1];
//pr_info("iface=%s, port=%d, dynamic=%d\n",strEHA,port,mode);
port_mask = (int)args[0];
type = (int)args[1];
if (mac_verify(mac)) {
pr_error("%s is an invalid MAC format (XX:XX:XX:XX:XX:XX)\n",
mac);
*p_ret = -1;
return *p_ret;
}
mac_from_str(mac_tmp, mac);
if (rtu_check_type(type)) {
pr_error("Unknown type %d\n", type);
*p_ret = -1;
return *p_ret;
}
if (1 > port_mask || port_mask > 0x7ffff) { /* 18 ports + CPU */
pr_error("Wrong port mask 0x%x\n", port_mask);
*p_ret = -1;
return *p_ret;
}
pr_debug("Request to add an entry with port mask 0x%x, MAC: %s, "
"type:%s\n", port_mask, mac_to_string(mac_tmp),
rtu_type_to_str(type));
*p_ret = rtu_fd_create_entry(mac_tmp, 0, port_mask, type,
OVERRIDE_EXISTING);
return *p_ret;
}
if (mac_from_str(mac_tmp, strEHA) != ETH_ALEN)
pr_error(
"%s is an invalid MAC format (XX:XX:XX:XX:XX:XX)\n",
strEHA);
int rtudexp_remove_entry(const struct minipc_pd *pd, uint32_t * args, void *ret)
{
uint8_t mac_tmp[ETH_ALEN] = { 0 };
char *mac;
uint32_t port_mask;
int type;
int *p_ret = (int *)ret; /*force pointed to int type */
pr_info("Create entry for (MAC=%s) port %x (wri%d), mode:%s\n",
mac_to_string(mac_tmp), 1 << port, port + 1,
mode == RTU_ENTRY_TYPE_DYNAMIC ? "DYNAMIC" : "STATIC");
*p_ret =
rtu_fd_create_entry(mac_tmp, 0, 1 << port, mode, OVERRIDE_EXISTING);
mac = (char *)args;
args = minipc_get_next_arg(args, pd->args[0]);
port_mask = (int)args[0];
type = (int)args[1];
if (mac_verify(mac)) {
pr_error("%s is an invalid MAC format (XX:XX:XX:XX:XX:XX)\n",
mac);
*p_ret = -1;
return *p_ret;
}
mac_from_str(mac_tmp, mac);
if (rtu_check_type(type)) {
pr_error("Unknown type %d\n", type);
*p_ret = -1;
return *p_ret;
}
if (1 > port_mask || port_mask > 0x7ffff) { /* 18 ports + CPU */
pr_error("Wrong port mask 0x%x\n", port_mask);
*p_ret = -1;
return *p_ret;
}
pr_debug("Request to remove an entry with port mask 0x%x, MAC: %s, "
"type %s\n", port_mask, mac_to_string(mac_tmp),
rtu_type_to_str(type));
*p_ret = rtu_fd_remove_entry(mac_tmp, port_mask, type);
pr_debug("Removed %d entries\n", *p_ret);
return *p_ret;
}
......@@ -121,6 +183,7 @@ int rtud_init_exports()
MINIPC_EXP_FUNC(rtud_export_clear_entries, rtudexp_clear_entries);
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_vlan_entry, rtudexp_vlan_entry);
return 0;
......
......@@ -36,8 +36,7 @@ struct minipc_pd rtud_export_clear_entries = {
.name = "clear_entries",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* port */
MINIPC_ARG_END,
},
};
......@@ -47,9 +46,21 @@ struct minipc_pd rtud_export_add_entry = {
.name = "add_entry",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *), /* MAC */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* port mask */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* type */
MINIPC_ARG_END,
},
};
/* Export of a function to remove entry in rtu */
struct minipc_pd rtud_export_remove_entry = {
.name = "remove_entry",
.retval = MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int),
.args = {
MINIPC_ARG_ENCODE(MINIPC_ATYPE_STRING, char *), /* MAC */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* port mask */
MINIPC_ARG_ENCODE(MINIPC_ATYPE_INT, int), /* type */
MINIPC_ARG_END,
},
};
......
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