From f5286cddc3b0d517e0928e7b1def3a4de23497d3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 23 Sep 2010 22:49:43 +0100 Subject: ethtool: Add Ethernet-level RX n-tuple filtering and 'clear' action Signed-off-by: Ben Hutchings --- ethtool.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 8 deletions(-) (limited to 'ethtool.c') diff --git a/ethtool.c b/ethtool.c index ea6a26f..31158f8 100644 --- a/ethtool.c +++ b/ethtool.c @@ -240,11 +240,15 @@ static struct option { " equal N | weight W0 W1 ...\n" }, { "-U", "--config-ntuple", MODE_SNTUPLE, "Configure Rx ntuple filters " "and actions", - " flow-type tcp4|udp4|sctp4\n" - " [ src-ip ADDR [src-ip-mask MASK] ]\n" - " [ dst-ip ADDR [dst-ip-mask MASK] ]\n" - " [ src-port PORT [src-port-mask MASK] ]\n" - " [ dst-port PORT [dst-port-mask MASK] ]\n" + " { flow-type tcp4|udp4|sctp4\n" + " [ src-ip ADDR [src-ip-mask MASK] ]\n" + " [ dst-ip ADDR [dst-ip-mask MASK] ]\n" + " [ src-port PORT [src-port-mask MASK] ]\n" + " [ dst-port PORT [dst-port-mask MASK] ]\n" + " | flow-type ether\n" + " [ src MAC-ADDR [src-mask MASK] ]\n" + " [ dst MAC-ADDR [dst-mask MASK] ]\n" + " [ proto N [proto-mask MASK] ] }\n" " [ vlan VLAN-TAG [vlan-mask MASK] ]\n" " [ user-def DATA [user-def-mask MASK] ]\n" " action N\n" }, @@ -377,6 +381,12 @@ static int ntuple_psrc_seen = 0; static int ntuple_psrc_mask_seen = 0; static int ntuple_pdst_seen = 0; static int ntuple_pdst_mask_seen = 0; +static int ntuple_ether_dst_seen = 0; +static int ntuple_ether_dst_mask_seen = 0; +static int ntuple_ether_src_seen = 0; +static int ntuple_ether_src_mask_seen = 0; +static int ntuple_ether_proto_seen = 0; +static int ntuple_ether_proto_mask_seen = 0; static int ntuple_vlan_tag_seen = 0; static int ntuple_vlan_tag_mask_seen = 0; static int ntuple_user_def_seen = 0; @@ -497,7 +507,7 @@ static struct cmdline_info cmdline_coalesce[] = { { "tx-frames-high", CMDL_S32, &coal_tx_frames_high_wanted, &ecoal.tx_max_coalesced_frames_high }, }; -static struct cmdline_info cmdline_ntuple[] = { +static struct cmdline_info cmdline_ntuple_tcp_ip4[] = { { "src-ip", CMDL_IP4, &ntuple_fs.h_u.tcp_ip4_spec.ip4src, NULL, 0, &ntuple_ip4src_seen }, { "src-ip-mask", CMDL_IP4, &ntuple_fs.m_u.tcp_ip4_spec.ip4src, NULL, @@ -525,6 +535,30 @@ static struct cmdline_info cmdline_ntuple[] = { { "action", CMDL_S32, &ntuple_fs.action, NULL }, }; +static struct cmdline_info cmdline_ntuple_ether[] = { + { "dst", CMDL_MAC, ntuple_fs.h_u.ether_spec.h_dest, NULL, + 0, &ntuple_ether_dst_seen }, + { "dst-mask", CMDL_MAC, ntuple_fs.m_u.ether_spec.h_dest, NULL, + 0, &ntuple_ether_dst_mask_seen }, + { "src", CMDL_MAC, ntuple_fs.h_u.ether_spec.h_source, NULL, + 0, &ntuple_ether_src_seen }, + { "src-mask", CMDL_MAC, ntuple_fs.m_u.ether_spec.h_source, NULL, + 0, &ntuple_ether_src_mask_seen }, + { "proto", CMDL_BE16, &ntuple_fs.h_u.ether_spec.h_proto, NULL, + 0, &ntuple_ether_proto_seen }, + { "proto-mask", CMDL_BE16, &ntuple_fs.m_u.ether_spec.h_proto, NULL, + 0, &ntuple_ether_proto_mask_seen }, + { "vlan", CMDL_U16, &ntuple_fs.vlan_tag, NULL, + 0, &ntuple_vlan_tag_seen }, + { "vlan-mask", CMDL_U16, &ntuple_fs.vlan_tag_mask, NULL, + 0, &ntuple_vlan_tag_mask_seen }, + { "user-def", CMDL_U64, &ntuple_fs.data, NULL, + 0, &ntuple_user_def_seen }, + { "user-def-mask", CMDL_U64, &ntuple_fs.data_mask, NULL, + 0, &ntuple_user_def_mask_seen }, + { "action", CMDL_S32, &ntuple_fs.action, NULL }, +}; + static struct cmdline_info cmdline_msglvl[] = { { "drv", CMDL_FLAG, &msglvl_wanted, NULL, NETIF_MSG_DRV, &msglvl_mask }, @@ -741,6 +775,8 @@ static int rxflow_str_to_type(const char *str) flow_type = AH_ESP_V6_FLOW; else if (!strcmp(str, "sctp6")) flow_type = SCTP_V6_FLOW; + else if (!strcmp(str, "ether")) + flow_type = ETHER_FLOW; return flow_type; } @@ -1551,8 +1587,8 @@ static void parse_rxntupleopts(int argc, char **argp, int i) case SCTP_V4_FLOW: parse_generic_cmdline(argc, argp, i + 1, &sntuple_changed, - cmdline_ntuple, - ARRAY_SIZE(cmdline_ntuple)); + cmdline_ntuple_tcp_ip4, + ARRAY_SIZE(cmdline_ntuple_tcp_ip4)); if (!ntuple_ip4src_seen) ntuple_fs.m_u.tcp_ip4_spec.ip4src = 0xffffffff; if (!ntuple_ip4dst_seen) @@ -1563,6 +1599,19 @@ static void parse_rxntupleopts(int argc, char **argp, int i) ntuple_fs.m_u.tcp_ip4_spec.pdst = 0xffff; ntuple_fs.m_u.tcp_ip4_spec.tos = 0xff; break; + case ETHER_FLOW: + parse_generic_cmdline(argc, argp, i + 1, + &sntuple_changed, + cmdline_ntuple_ether, + ARRAY_SIZE(cmdline_ntuple_ether)); + if (!ntuple_ether_dst_seen) + memset(ntuple_fs.m_u.ether_spec.h_dest, 0xff, ETH_ALEN); + if (!ntuple_ether_src_seen) + memset(ntuple_fs.m_u.ether_spec.h_source, 0xff, + ETH_ALEN); + if (!ntuple_ether_proto_seen) + ntuple_fs.m_u.ether_spec.h_proto = 0xffff; + break; default: fprintf(stderr, "Unsupported flow type \"%s\"\n", argp[i]); exit(106); @@ -1578,6 +1627,9 @@ static void parse_rxntupleopts(int argc, char **argp, int i) (ntuple_ip4dst_mask_seen && !ntuple_ip4dst_seen) || (ntuple_psrc_mask_seen && !ntuple_psrc_seen) || (ntuple_pdst_mask_seen && !ntuple_pdst_seen) || + (ntuple_ether_dst_mask_seen && !ntuple_ether_dst_seen) || + (ntuple_ether_src_mask_seen && !ntuple_ether_src_seen) || + (ntuple_ether_proto_mask_seen && !ntuple_ether_proto_seen) || (ntuple_vlan_tag_mask_seen && !ntuple_vlan_tag_seen) || (ntuple_user_def_mask_seen && !ntuple_user_def_seen)) { fprintf(stderr, "Cannot specify mask without value\n"); -- cgit v1.2.1