From b29aa90ebcf9627e960b07c3f58eaceffdf61dd3 Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Tue, 11 Dec 2012 14:03:56 +0200 Subject: Added dst-mac parameter for L3/L4 flow spec rules. This is usefull in vSwitch configurations. Signed-off-by: Yan Burman Signed-off-by: Amir Vadai Signed-off-by: Ben Hutchings --- ethtool.8.in | 6 ++++++ ethtool.c | 5 +++++ rxclass.c | 62 +++++++++++++++++++++++++++++++++++++++++------------------- 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; -- cgit v1.2.1