summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ethtool.8.in6
-rw-r--r--ethtool.c5
-rw-r--r--rxclass.c62
3 files changed, 54 insertions, 19 deletions
diff --git a/ethtool.8.in b/ethtool.8.in
index 2da50aa..8df16f3 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -268,6 +268,7 @@ ethtool \- query or control network driver and hardware settings
.BM vlan\-etype
.BM vlan
.BM user\-def
+.RB [ dst-mac \ \*(MA\ [ m \ \*(MA]]
.BN action
.BN loc
.RB |
@@ -739,6 +740,11 @@ Includes the VLAN tag and an optional mask.
.BI user\-def \ N \\fR\ [\\fPm \ N \\fR]\\fP
Includes 64-bits of user-specific data and an optional mask.
.TP
+.BR dst-mac \ \*(MA\ [ m \ \*(MA]
+Includes the destination MAC address, specified as 6 bytes in hexadecimal
+separated by colons, along with an optional mask.
+Valid for all IPv4 based flow-types.
+.TP
.BI action \ N
Specifies the Rx queue to send packets to, or some other action.
.TS
diff --git a/ethtool.c b/ethtool.c
index 345c21c..55bc082 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -3231,6 +3231,10 @@ static int flow_spec_to_ntuple(struct ethtool_rx_flow_spec *fsp,
if (fsp->location != RX_CLS_LOC_ANY)
return -1;
+ /* destination MAC address in L3/L4 rules is not supported by ntuple */
+ if (fsp->flow_type & FLOW_MAC_EXT)
+ return -1;
+
/* verify ring cookie can transfer to action */
if (fsp->ring_cookie > INT_MAX && fsp->ring_cookie < (u64)(-2))
return -1;
@@ -3814,6 +3818,7 @@ static const struct option {
" [ vlan-etype %x [m %x] ]\n"
" [ vlan %x [m %x] ]\n"
" [ user-def %x [m %x] ]\n"
+ " [ dst-mac %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]\n"
" [ action %d ]\n"
" [ loc %d]] |\n"
" delete %d\n" },
diff --git a/rxclass.c b/rxclass.c
index e1633a8..1564b62 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -41,26 +41,38 @@ static void rxclass_print_ipv4_rule(__be32 sip, __be32 sipm, __be32 dip,
static void rxclass_print_nfc_spec_ext(struct ethtool_rx_flow_spec *fsp)
{
- u64 data, datam;
- __u16 etype, etypem, tci, tcim;
+ if (fsp->flow_type & FLOW_EXT) {
+ u64 data, datam;
+ __u16 etype, etypem, tci, tcim;
+ etype = ntohs(fsp->h_ext.vlan_etype);
+ etypem = ntohs(~fsp->m_ext.vlan_etype);
+ tci = ntohs(fsp->h_ext.vlan_tci);
+ tcim = ntohs(~fsp->m_ext.vlan_tci);
+ data = (u64)ntohl(fsp->h_ext.data[0]) << 32;
+ data = (u64)ntohl(fsp->h_ext.data[1]);
+ datam = (u64)ntohl(~fsp->m_ext.data[0]) << 32;
+ datam |= (u64)ntohl(~fsp->m_ext.data[1]);
- if (!(fsp->flow_type & FLOW_EXT))
- return;
+ fprintf(stdout,
+ "\tVLAN EtherType: 0x%x mask: 0x%x\n"
+ "\tVLAN: 0x%x mask: 0x%x\n"
+ "\tUser-defined: 0x%llx mask: 0x%llx\n",
+ etype, etypem, tci, tcim, data, datam);
+ }
- etype = ntohs(fsp->h_ext.vlan_etype);
- etypem = ntohs(~fsp->m_ext.vlan_etype);
- tci = ntohs(fsp->h_ext.vlan_tci);
- tcim = ntohs(~fsp->m_ext.vlan_tci);
- data = (u64)ntohl(fsp->h_ext.data[0]) << 32;
- data = (u64)ntohl(fsp->h_ext.data[1]);
- datam = (u64)ntohl(~fsp->m_ext.data[0]) << 32;
- datam |= (u64)ntohl(~fsp->m_ext.data[1]);
+ if (fsp->flow_type & FLOW_MAC_EXT) {
+ unsigned char *dmac, *dmacm;
- fprintf(stdout,
- "\tVLAN EtherType: 0x%x mask: 0x%x\n"
- "\tVLAN: 0x%x mask: 0x%x\n"
- "\tUser-defined: 0x%llx mask: 0x%llx\n",
- etype, etypem, tci, tcim, data, datam);
+ dmac = fsp->h_ext.h_dest;
+ dmacm = fsp->m_ext.h_dest;
+
+ fprintf(stdout,
+ "\tDest MAC addr: %02X:%02X:%02X:%02X:%02X:%02X"
+ " mask: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ dmac[0], dmac[1], dmac[2], dmac[3], dmac[4],
+ dmac[5], dmacm[0], dmacm[1], dmacm[2], dmacm[3],
+ dmacm[4], dmacm[5]);
+ }
}
static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
@@ -70,7 +82,7 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
fprintf(stdout, "Filter: %d\n", fsp->location);
- flow_type = fsp->flow_type & ~FLOW_EXT;
+ flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT);
invert_flow_mask(fsp);
@@ -172,7 +184,7 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp)
{
/* print the rule in this location */
- switch (fsp->flow_type & ~FLOW_EXT) {
+ switch (fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
case TCP_V4_FLOW:
case UDP_V4_FLOW:
case SCTP_V4_FLOW:
@@ -533,6 +545,7 @@ typedef enum {
#define NTUPLE_FLAG_VLAN 0x100
#define NTUPLE_FLAG_UDEF 0x200
#define NTUPLE_FLAG_VETH 0x400
+#define NFC_FLAG_MAC_ADDR 0x800
struct rule_opts {
const char *name;
@@ -571,6 +584,9 @@ static const struct rule_opts rule_nfc_tcp_ip4[] = {
{ "user-def", OPT_BE64, NTUPLE_FLAG_UDEF,
offsetof(struct ethtool_rx_flow_spec, h_ext.data),
offsetof(struct ethtool_rx_flow_spec, m_ext.data) },
+ { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR,
+ offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest),
+ offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) },
};
static const struct rule_opts rule_nfc_esp_ip4[] = {
@@ -599,6 +615,9 @@ static const struct rule_opts rule_nfc_esp_ip4[] = {
{ "user-def", OPT_BE64, NTUPLE_FLAG_UDEF,
offsetof(struct ethtool_rx_flow_spec, h_ext.data),
offsetof(struct ethtool_rx_flow_spec, m_ext.data) },
+ { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR,
+ offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest),
+ offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) },
};
static const struct rule_opts rule_nfc_usr_ip4[] = {
@@ -639,6 +658,9 @@ static const struct rule_opts rule_nfc_usr_ip4[] = {
{ "user-def", OPT_BE64, NTUPLE_FLAG_UDEF,
offsetof(struct ethtool_rx_flow_spec, h_ext.data),
offsetof(struct ethtool_rx_flow_spec, m_ext.data) },
+ { "dst-mac", OPT_MAC, NFC_FLAG_MAC_ADDR,
+ offsetof(struct ethtool_rx_flow_spec, h_ext.h_dest),
+ offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) },
};
static const struct rule_opts rule_nfc_ether[] = {
@@ -1063,6 +1085,8 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx,
fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
if (flags & (NTUPLE_FLAG_VLAN | NTUPLE_FLAG_UDEF | NTUPLE_FLAG_VETH))
fsp->flow_type |= FLOW_EXT;
+ if (flags & NFC_FLAG_MAC_ADDR)
+ fsp->flow_type |= FLOW_MAC_EXT;
return 0;