summaryrefslogtreecommitdiff
path: root/ethtool.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2010-09-23 22:49:43 +0100
committerBen Hutchings <bhutchings@solarflare.com>2010-11-16 19:10:27 +0000
commitf5286cddc3b0d517e0928e7b1def3a4de23497d3 (patch)
tree4ec739a4479182b7147b6833a1778579f4d3853f /ethtool.c
parent9362cee5318a3eeb7aa464e3b5e5ac12a63c9652 (diff)
downloadethtool-f5286cddc3b0d517e0928e7b1def3a4de23497d3.tar.gz
ethtool: Add Ethernet-level RX n-tuple filtering and 'clear' action
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'ethtool.c')
-rw-r--r--ethtool.c68
1 files changed, 60 insertions, 8 deletions
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");