diff --git a/doc/wrs-developer-manual.in b/doc/wrs-developer-manual.in index 8923e9d5a012ec74ffa3aa49a3bdbdba073bb355..8389f892d967b3612aca9870dc70431e43dbb235 100644 --- a/doc/wrs-developer-manual.in +++ b/doc/wrs-developer-manual.in @@ -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. diff --git a/userspace/tools/rtu_stat.c b/userspace/tools/rtu_stat.c index 92bb44a124f460e3e6b5f1324ea57b3c2524e933..ff538e3c8b9db67c169554b98d06f61b5e90e6ed 100644 --- a/userspace/tools/rtu_stat.c +++ b/userspace/tools/rtu_stat.c @@ -44,29 +44,40 @@ struct wrs_shm_head *rtu_port_shmem; static struct rtu_vlan_table_entry vlan_tab_local[NUM_VLANS]; static struct rtu_filtering_entry rtu_htab_local[RTU_BUCKETS * HTAB_ENTRIES]; -int rtudexp_clear_entries(int netif, int force) +int rtudexp_clear_entries(int port, int type) { int val, ret; - ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_clear_entries,&val,netif,force); - return (ret<0)?ret:val; + ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_clear_entries, + &val, port, type); + return (ret < 0) ? ret : val; } -int rtudexp_add_entry(const char *eha, int port, int mode) +int rtudexp_add_entry(const char *mac, int port_mask, int type) { int val, ret; - ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_add_entry,&val,eha,port,mode); - return (ret<0)?ret:val; + ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_add_entry, + &val, mac, port_mask, type); + 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) +int rtudexp_remove_entry(const char *mac, int port_mask, int type) +{ + int val, ret; + ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_remove_entry, + &val, mac, port_mask, type); + 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) { int val, ret; int mask; sscanf(ch_mask,"%x", &mask); - ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_vlan_entry,&val,vid,fid,mask, - drop,prio,has_prio,prio_override); - return (ret<0)?ret:val; + ret = minipc_call(rtud_ch, MINIPC_TIMEOUT, &rtud_export_vlan_entry, + &val, vid, fid, mask, drop, prio, has_prio, + prio_override); + return (ret < 0) ? ret : val; } static int cmp_rtu_entries(const void *p1, const void *p2) @@ -106,13 +117,45 @@ void show_help(char *prgname) fprintf(stderr, "usage: %s <command> <values>\n", prgname); fprintf(stderr, " help: Show this message\n"); fprintf(stderr, " list: List the routing table (same as empty command)\n"); - fprintf(stderr, " remove <ifnum>: Remove all dynamic entries for one interface\n"); - fprintf(stderr, " add <mac (XX:XX:XX:XX:XX)> <ifnum> [<mode>]: Add entry for a specific \n"); - fprintf(stderr, " MAC address (mode={%d=dynamic, %d=static})\n", + fprintf(stderr, " remove all <port> [<type>]: Remove all RTU entries for the given port\n" + " with an optional type (default %d-dynamic)\n", + RTU_ENTRY_TYPE_DYNAMIC); + fprintf(stderr, " remove <mac> <port> [<type>]: Add a RTU entry for a specific\n" + " MAC address on a given port with an optional\n" + " type (default %d-static)\n", + RTU_ENTRY_TYPE_STATIC); + fprintf(stderr, " remove mask <mac> <port_mask> [<type>]: Add a RTU entry for a specific\n" + " MAC address on a given port mask with\n" + " an optional type (default %d-static)\n", + RTU_ENTRY_TYPE_STATIC); + fprintf(stderr, " add <mac> <port> [<type>]: Add entry for a specific MAC address with an\n" + " optional type (default %d-static)\n", + RTU_ENTRY_TYPE_STATIC); + fprintf(stderr, " add mask <mac> <port_mask> [<type>]: Add an entry for a specific \n" + " MAC address and multiple ports with\n" + " an optional type (default %d-static)\n", + RTU_ENTRY_TYPE_STATIC); + 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"); + fprintf(stderr, "\n"); + fprintf(stderr, "Where:\n"); + fprintf(stderr, " <mac> MAC address to be used in the RTU rule;\n" + " it is in the format XX:XX:XX:XX:XX:XX\n"); + fprintf(stderr, " <port> port number on which RTU rule is registered; it is a port\n" + " number from 1 to 18, or the CPU (19)\n"); + fprintf(stderr, " <port_mask> Mask of ports on which RTU rule is registered;\n" + " it is a hex mask of ports in the format 0xXXXXX\n"); + fprintf(stderr, " <type> Numerical representation of rule's type %d=dynamic or %d=static\n", RTU_ENTRY_TYPE_DYNAMIC, RTU_ENTRY_TYPE_STATIC); - fprintf(stderr, " vlan <vid> <fid> <hex mask> [<drop>, <prio>, <has_prio>, <prio_override>]: \n"); - fprintf(stderr, " Add VLAN entry with vid, fid, mask and drop flag (Write mask=0x0 \n"); - fprintf(stderr, " and drop=1 to remove the VLAN)\n"); + fprintf(stderr, " <vid> VLAN ID\n"); + fprintf(stderr, " <fid> Filtering Database ID\n"); + fprintf(stderr, " <drop> Set to 1 to drop frames with <vid>; 0 don't drop\n"); + fprintf(stderr, " <prio> Priority to override the VLAN-tagged received frames\n" + " (if <prio_override> true)\n"); + fprintf(stderr, " <has_prio> Indicates there is valid <prio>\n"); + fprintf(stderr, " <prio_override> Use the <prio> in the VLAN Table to override the frame's\n" + " PRIO in the tag\n"); exit(1); } @@ -277,6 +320,39 @@ int open_rtu_shm(void) return 0; } +int read_port(char *port, int nports) +{ + int i; + if (!strcmp(port, "CPU") || !strcmp(port, "cpu")) { + return 1 + nports; /* CPU is usually a 19th port */ + } + + i = strtol(port, NULL, 0); + /* interface number 1..18, CPU is 19 */ + if (0 < i && i <= (nports + 1)) { /* 18 ports + CPU */ + return i; + } + return -1; +} + +int read_port_mask(char *mask, int nports) +{ + int i; + if (!strcmp(mask, "CPU") || !strcmp(mask, "cpu")) { + return 1 << nports; /* CPU is usually at 19th bit */ + } + if (!strcmp(mask, "ALL") || !strcmp(mask, "all")) { + return (1 << (nports + 1)) - 1; + } + + i = strtol(mask, NULL, 0); + /* interface number 1..18, CPU is 19 */ + if (0 < i && i <= ((1 << (nports + 1)) - 1)) { /* 18 ports + CPU */ + return i; + } + return -1; +} + int main(int argc, char **argv) { int i, isok; @@ -285,6 +361,8 @@ int main(int argc, char **argv) int vid_active = 0; char mac_buf[ETH_ALEN_STR]; int n_wait = 0; + int ret; + int type; nports = get_nports_from_hal(); @@ -308,64 +386,186 @@ int main(int argc, char **argv) return -1; } - isok=0; - if(argc>1) - { - if (strcmp(argv[1], "remove") == 0) { - i = atoidef(argc, argv, 2, -1); - /* interface number 1..18*/ - if ((0 < i && i <= 18) - && (rtudexp_clear_entries(i - 1, - atoidef(argc, argv, 3, 0) - ) == 0)) { - /* ok */ - isok = 1; - } else { - printf("Could not %s entry for wri%d\n", - argv[1], i); - exit(1); - } - } else if (strcmp(argv[1], "add") == 0) { - /* interface number 1..18*/ - if ((argc > 3) - && (rtudexp_add_entry(argv[2], - atoi(argv[3]) - 1, - atoidef(argc, argv, 4, 0) - ) == 0)) { - /* ok */ - isok = 1; - } else { - printf("Could not %s entry for %s\n", argv[2], - argv[3] - 1); - exit(1); - } - } else if (strcmp(argv[1], "vlan") == 0) { - if ((argc > 3) - && (rtudexp_vlan_entry(atoi(argv[2]), - atoi(argv[3]) - 1, - argv[4], - atoidef(argc, argv, 5, 0), - atoidef(argc, argv, 6, 0), - atoidef(argc, argv, 7, 0), - atoidef(argc, argv, 8, 0) - ) == 0)) { - /* ok */ - isok = 1; - } else { - printf("Could not %s entry for %s\n", argv[2], - argv[3]); - exit(1); - } - } else if (strcmp(argv[1], "list") == 0) + isok = 0; +/* ****************** remove all <port> [<type>] *************************** */ + if (argc >= 4 + && !strcmp(argv[1], "remove") + && !strcmp(argv[2], "all")) { + /* rtu_stat remove all <port> [<type>] */ + i = read_port(argv[3], nports); + /* interface number 1..18, CPU is 19 */ + if (i < 0) { + printf("Wrong port number %s\n", argv[3]); + exit(1); + } + type = atoidef(argc, argv, 5, RTU_ENTRY_TYPE_DYNAMIC); + if (rtu_check_type(type)) { + fprintf(stderr, "rtu_stat: Unknown type %d\n", type); + exit(1); + } + ret = rtudexp_clear_entries(i - 1, /* port */ + type /* type */ + ); + /* ok */ + isok = 1; +/* ****************** remove mask <mac> <port_mask> [<type>] *************** */ + } else if (argc >= 5 + && !strcmp(argv[1], "remove") + && !strcmp(argv[2], "mask")) { + /* rtu_stat remove mask <mac> <port_mask> [<type>] */ + i = read_port_mask(argv[4], nports); + /* interface number 1..18, CPU is 19 */ + if (i < 0) { + printf("Wrong port mask 0x%s\n", argv[4]); + exit(1); + } + if (mac_verify(argv[3])) { + fprintf(stderr, "rtu_stat: Wrong MAC %s\n", argv[3]); + exit(1); + } + type = atoidef(argc, argv, 5, RTU_ENTRY_TYPE_STATIC); + if (rtu_check_type(type)) { + fprintf(stderr, "rtu_stat: Unknown type %d\n", type); + exit(1); + } + ret = rtudexp_remove_entry(argv[3], /* MAC */ + i, /* port mask */ + type /* type */ + ); + if (ret > 0) + printf("Removed %d entries for port mask 0x%x\n", + ret, i); + if (ret < 0) { + printf("Could not remove entry for port mask 0x%x\n", + i); + exit(1); + } + isok = 1; +/* ****************** remove <mac> <port> [<type>] ************************* */ + } else if (argc >= 4 + && !strcmp(argv[1], "remove")) { + /* rtu_stat remove <mac> <port> [<type>] */ + i = read_port(argv[3], nports); + /* interface number 1..18, CPU is 19 */ + if (i < 0) { + printf("Wrong port number %s\n", argv[3]); + exit(1); + } + if (mac_verify(argv[2])) { + fprintf(stderr, "rtu_stat: Wrong MAC %s\n", argv[2]); + exit(1); + } + type = atoidef(argc, argv, 4, RTU_ENTRY_TYPE_STATIC); + if (rtu_check_type(type)) { + fprintf(stderr, "rtu_stat: Unknown type %d\n", type); + exit(1); + } + ret = rtudexp_remove_entry(argv[2], /* MAC */ + 1 << (i - 1), /* port mask */ + type /* type */ + ); + if (ret > 0) + printf("Removed %d entries for port %d (wri%d)\n", + ret, i, i); + if (ret < 0) { + printf("Could not remove entry for port %d (wri%d)\n", + i, i); + exit(1); + } + isok = 1; +/* ****************** add mask <mac> <port_mask> [<type>] ****************** */ + } else if (argc >= 5 + && !strcmp(argv[1], "add") + && !strcmp(argv[2], "mask")) { + /* rtu_stat add mask <mac> <port_mask> [<type>] */ + i = read_port_mask(argv[4], nports); + /* interface number 1..18, CPU is 19 */ + if (i < 0) { + printf("Wrong port mask 0x%s\n", argv[4]); + exit(1); + } + if (mac_verify(argv[3])) { + fprintf(stderr, "rtu_stat: Wrong MAC %s\n", argv[3]); + exit(1); + } + type = atoidef(argc, argv, 5, RTU_ENTRY_TYPE_STATIC); + if (rtu_check_type(type)) { + fprintf(stderr, "rtu_stat: Unknown type %d\n", type); + exit(1); + } + ret = rtudexp_add_entry(argv[3], /* MAC */ + i, /* port mask */ + type /* type */ + ); + if (ret > 0) + printf("Added %d entries for port mask 0x%x\n", + ret, i); + if (ret < 0) { + printf("Could not add entry for port mask 0x%x\n", i); + exit(1); + } + isok = 1; +/* ****************** add <mac> <port> [<type>] **************************** */ + } else if (argc >= 4 + && !strcmp(argv[1], "add")) { + /* rtu_stat add <mac> <port> [<type>] */ + i = read_port(argv[3], nports); + /* interface number 1..18, CPU is 19 */ + if (i < 0) { + printf("Wrong port number %s\n", argv[3]); + exit(1); + } + if (mac_verify(argv[2])) { + fprintf(stderr, "rtu_stat: Wrong MAC %s\n", argv[2]); + exit(1); + } + type = atoidef(argc, argv, 4, RTU_ENTRY_TYPE_STATIC); + if (rtu_check_type(type)) { + fprintf(stderr, "rtu_stat: Unknown type %d\n", type); + exit(1); + } + ret = rtudexp_add_entry(argv[2], /* MAC */ + 1 << (i - 1), /* port mask */ + type /* type */ + ); + if (ret > 0) + printf("Added %d entries for port %d (wri%d)\n", + ret, i, i); + if (ret < 0) { + printf("Could not add entry for port %d (wri%d)\n", + i, i); + exit(1); + } + isok = 1; +/* ****************** vlan <vid> <fid> <port_mask> + * [<drop>, <prio>, <has_prio>, <prio_override>] *** */ + } else if (argc >= 5 + && !strcmp(argv[1], "vlan")) { + if (rtudexp_vlan_entry(atoi(argv[2]), + atoi(argv[3]) - 1, + argv[4], + atoidef(argc, argv, 5, 0), + atoidef(argc, argv, 6, 0), + atoidef(argc, argv, 7, 0), + atoidef(argc, argv, 8, 0) + ) == 0) { + /* ok */ isok = 1; - - //Does not continue - if (!isok) - show_help(argv[0]); - - + } else { + printf("Vlan command error\n"); + exit(1); + } + } else if (argc >= 2 + && !strcmp(argv[1], "list")) + isok = 1; + + /* Does not continue */ + if (argc > 1 && !isok) { + show_help(argv[0]); + exit(1); } + /* read filter entires from shm to local memory for data consistency */ if (read_htab(&htab_read_entries)) { printf("Too many retries while reading htab entries from RTUd " @@ -385,12 +585,11 @@ int main(int argc, char **argv) { if (!rtu_htab_local[i].valid) continue; - printf("%-25s %-12s %2d %s (hash %03x:%x) ", + printf("%-25s %-12s %2d %-7s (hash %03x:%x) ", mac_to_buffer(rtu_htab_local[i].mac, mac_buf), decode_ports(rtu_htab_local[i].port_mask_dst, nports), rtu_htab_local[i].fid, - rtu_htab_local[i].dynamic == RTU_ENTRY_TYPE_DYNAMIC ? - "DYNAMIC" : "STATIC ", + rtu_type_to_str(rtu_htab_local[i].dynamic), rtu_htab_local[i].addr.hash, rtu_htab_local[i].addr.bucket); if (rtu_htab_local[i].dynamic == RTU_ENTRY_TYPE_DYNAMIC) diff --git a/userspace/wrsw_rtud/rtu_fd.c b/userspace/wrsw_rtud/rtu_fd.c index 92e059e6fec7a3a1c817789d7c5beaa9078eca0a..5cfc9ea9ad5acfa504add513552a85afd6b74b46 100644 --- a/userspace/wrsw_rtud/rtu_fd.c +++ b/userspace/wrsw_rtud/rtu_fd.c @@ -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 diff --git a/userspace/wrsw_rtud/rtu_fd.h b/userspace/wrsw_rtud/rtu_fd.h index 2271edd1defddac91149b5164737eff268f60c02..0adf7412edab97eaee900fedb579d1891f809619 100644 --- a/userspace/wrsw_rtud/rtu_fd.h +++ b/userspace/wrsw_rtud/rtu_fd.h @@ -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, diff --git a/userspace/wrsw_rtud/rtud_exports.c b/userspace/wrsw_rtud/rtud_exports.c index 8fe3558182c1f036a8256c03fb83f6747232b59d..0e928dc4f1b2e0186ab4427a516e1252d149f217 100644 --- a/userspace/wrsw_rtud/rtud_exports.c +++ b/userspace/wrsw_rtud/rtud_exports.c @@ -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; diff --git a/userspace/wrsw_rtud/rtud_exports.h b/userspace/wrsw_rtud/rtud_exports.h index 5480a0e655b2739e0f9299d4064b22ce66c8154f..087ee28604fcf2ac4464de91011ea83d4bb36bf3 100644 --- a/userspace/wrsw_rtud/rtud_exports.h +++ b/userspace/wrsw_rtud/rtud_exports.h @@ -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, }, };