All of lore.kernel.org
 help / color / mirror / Atom feed
From: Edward Cree <ecree@solarflare.com>
To: Ben Hutchings <ben@decadent.org.uk>
Cc: <netdev@vger.kernel.org>
Subject: [PATCH v2 ethtool 1/2] Add IPv6 support to NFC
Date: Thu, 17 Mar 2016 19:17:16 +0000	[thread overview]
Message-ID: <56EB02BC.8070405@solarflare.com> (raw)
In-Reply-To: <56EB00D6.3060003@solarflare.com>

Signed-off-by: Edward Cree <ecree@solarflare.com>
---
 ethtool.c |  21 +++++
 rxclass.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 274 insertions(+), 14 deletions(-)

diff --git a/ethtool.c b/ethtool.c
index 0cd0d4f..b476dcc 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -32,6 +32,7 @@
 #include <sys/stat.h>
 #include <stdio.h>
 #include <stddef.h>
+#include <stdbool.h>
 #include <errno.h>
 #include <sys/utsname.h>
 #include <limits.h>
@@ -3540,6 +3541,22 @@ static int do_permaddr(struct cmd_context *ctx)
 	return err;
 }
 
+static bool flow_type_is_ntuple_supported(__u32 flow_type)
+{
+	switch (flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW:
+	case SCTP_V4_FLOW:
+	case AH_V4_FLOW:
+	case ESP_V4_FLOW:
+	case IPV4_USER_FLOW:
+	case ETHER_FLOW:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int flow_spec_to_ntuple(struct ethtool_rx_flow_spec *fsp,
 			       struct ethtool_rx_ntuple_flow_spec *ntuple)
 {
@@ -3563,6 +3580,10 @@ static int flow_spec_to_ntuple(struct ethtool_rx_flow_spec *fsp,
 	    fsp->m_ext.vlan_etype)
 		return -1;
 
+	/* IPv6 flow types are not supported by ntuple */
+	if (!flow_type_is_ntuple_supported(fsp->flow_type & ~FLOW_EXT))
+		return -1;
+
 	/* Set entire ntuple to ~0 to guarantee all masks are set */
 	memset(ntuple, ~0, sizeof(*ntuple));
 
diff --git a/rxclass.c b/rxclass.c
index cd686a3..c7bfeba 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -39,6 +39,25 @@ static void rxclass_print_ipv4_rule(__be32 sip, __be32 sipm, __be32 dip,
 		tos, tosm);
 }
 
+static void rxclass_print_ipv6_rule(__be32 *sip, __be32 *sipm, __be32 *dip,
+				    __be32 *dipm, u8 tclass, u8 tclassm)
+{
+	char sip_str[INET6_ADDRSTRLEN];
+	char sipm_str[INET6_ADDRSTRLEN];
+	char dip_str[INET6_ADDRSTRLEN];
+	char dipm_str[INET6_ADDRSTRLEN];
+
+	fprintf(stdout,
+		"\tSrc IP addr: %s mask: %s\n"
+		"\tDest IP addr: %s mask: %s\n"
+		"\tTraffic Class: 0x%x mask: 0x%x\n",
+		inet_ntop(AF_INET6, sip, sip_str, INET6_ADDRSTRLEN),
+		inet_ntop(AF_INET6, sipm, sipm_str, INET6_ADDRSTRLEN),
+		inet_ntop(AF_INET6, dip, dip_str, INET6_ADDRSTRLEN),
+		inet_ntop(AF_INET6, dipm, dipm_str, INET6_ADDRSTRLEN),
+		tclass, tclassm);
+}
+
 static void rxclass_print_nfc_spec_ext(struct ethtool_rx_flow_spec *fsp)
 {
 	if (fsp->flow_type & FLOW_EXT) {
@@ -127,7 +146,7 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
 			ntohl(fsp->h_u.esp_ip4_spec.spi),
 			ntohl(fsp->m_u.esp_ip4_spec.spi));
 		break;
-	case IP_USER_FLOW:
+	case IPV4_USER_FLOW:
 		fprintf(stdout, "\tRule Type: Raw IPv4\n");
 		rxclass_print_ipv4_rule(fsp->h_u.usr_ip4_spec.ip4src,
 				     fsp->m_u.usr_ip4_spec.ip4src,
@@ -143,6 +162,62 @@ static void rxclass_print_nfc_rule(struct ethtool_rx_flow_spec *fsp)
 			ntohl(fsp->h_u.usr_ip4_spec.l4_4_bytes),
 			ntohl(fsp->m_u.usr_ip4_spec.l4_4_bytes));
 		break;
+	case TCP_V6_FLOW:
+	case UDP_V6_FLOW:
+	case SCTP_V6_FLOW:
+		if (flow_type == TCP_V6_FLOW)
+			fprintf(stdout, "\tRule Type: TCP over IPv6\n");
+		else if (flow_type == UDP_V6_FLOW)
+			fprintf(stdout, "\tRule Type: UDP over IPv6\n");
+		else
+			fprintf(stdout, "\tRule Type: SCTP over IPv6\n");
+		rxclass_print_ipv6_rule(fsp->h_u.tcp_ip6_spec.ip6src,
+				     fsp->m_u.tcp_ip6_spec.ip6src,
+				     fsp->h_u.tcp_ip6_spec.ip6dst,
+				     fsp->m_u.tcp_ip6_spec.ip6dst,
+				     fsp->h_u.tcp_ip6_spec.tclass,
+				     fsp->m_u.tcp_ip6_spec.tclass);
+		fprintf(stdout,
+			"\tSrc port: %d mask: 0x%x\n"
+			"\tDest port: %d mask: 0x%x\n",
+			ntohs(fsp->h_u.tcp_ip6_spec.psrc),
+			ntohs(fsp->m_u.tcp_ip6_spec.psrc),
+			ntohs(fsp->h_u.tcp_ip6_spec.pdst),
+			ntohs(fsp->m_u.tcp_ip6_spec.pdst));
+		break;
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+		if (flow_type == AH_V6_FLOW)
+			fprintf(stdout, "\tRule Type: IPSEC AH over IPv6\n");
+		else
+			fprintf(stdout, "\tRule Type: IPSEC ESP over IPv6\n");
+		rxclass_print_ipv6_rule(fsp->h_u.ah_ip6_spec.ip6src,
+				     fsp->m_u.ah_ip6_spec.ip6src,
+				     fsp->h_u.ah_ip6_spec.ip6dst,
+				     fsp->m_u.ah_ip6_spec.ip6dst,
+				     fsp->h_u.ah_ip6_spec.tclass,
+				     fsp->m_u.ah_ip6_spec.tclass);
+		fprintf(stdout,
+			"\tSPI: %d mask: 0x%x\n",
+			ntohl(fsp->h_u.esp_ip6_spec.spi),
+			ntohl(fsp->m_u.esp_ip6_spec.spi));
+		break;
+	case IPV6_USER_FLOW:
+		fprintf(stdout, "\tRule Type: Raw IPv6\n");
+		rxclass_print_ipv6_rule(fsp->h_u.usr_ip6_spec.ip6src,
+				     fsp->m_u.usr_ip6_spec.ip6src,
+				     fsp->h_u.usr_ip6_spec.ip6dst,
+				     fsp->m_u.usr_ip6_spec.ip6dst,
+				     fsp->h_u.usr_ip6_spec.tclass,
+				     fsp->m_u.usr_ip6_spec.tclass);
+		fprintf(stdout,
+			"\tProtocol: %d mask: 0x%x\n"
+			"\tL4 bytes: 0x%x mask: 0x%x\n",
+			fsp->h_u.usr_ip6_spec.l4_proto,
+			fsp->m_u.usr_ip6_spec.l4_proto,
+			ntohl(fsp->h_u.usr_ip6_spec.l4_4_bytes),
+			ntohl(fsp->m_u.usr_ip6_spec.l4_4_bytes));
+		break;
 	case ETHER_FLOW:
 		dmac = fsp->h_u.ether_spec.h_dest;
 		dmacm = fsp->m_u.ether_spec.h_dest;
@@ -190,21 +265,20 @@ static void rxclass_print_rule(struct ethtool_rx_flow_spec *fsp)
 	case SCTP_V4_FLOW:
 	case AH_V4_FLOW:
 	case ESP_V4_FLOW:
-	case ETHER_FLOW:
-		rxclass_print_nfc_rule(fsp);
-		break;
-	case IP_USER_FLOW:
-		if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) {
-			rxclass_print_nfc_rule(fsp);
-			break;
-		}
-		/* IPv6 User Flow falls through to the case below */
 	case TCP_V6_FLOW:
 	case UDP_V6_FLOW:
 	case SCTP_V6_FLOW:
 	case AH_V6_FLOW:
 	case ESP_V6_FLOW:
-		fprintf(stderr, "IPv6 flows not implemented\n");
+	case IPV6_USER_FLOW:
+	case ETHER_FLOW:
+		rxclass_print_nfc_rule(fsp);
+		break;
+	case IPV4_USER_FLOW:
+		if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4)
+			rxclass_print_nfc_rule(fsp);
+		else /* IPv6 uses IPV6_USER_FLOW */
+			fprintf(stderr, "IPV4_USER_FLOW with wrong ip_ver\n");
 		break;
 	default:
 		fprintf(stderr, "rxclass: Unknown flow type\n");
@@ -530,6 +604,7 @@ typedef enum {
 	OPT_BE32,
 	OPT_BE64,
 	OPT_IP4,
+	OPT_IP6,
 	OPT_MAC,
 } rule_opt_type_t;
 
@@ -663,6 +738,114 @@ static const struct rule_opts rule_nfc_usr_ip4[] = {
 	  offsetof(struct ethtool_rx_flow_spec, m_ext.h_dest) },
 };
 
+static const struct rule_opts rule_nfc_tcp_ip6[] = {
+	{ "src-ip", OPT_IP6, NFC_FLAG_SADDR,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.ip6src),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.ip6src) },
+	{ "dst-ip", OPT_IP6, NFC_FLAG_DADDR,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.ip6dst),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.ip6dst) },
+	{ "tclass", OPT_U8, NFC_FLAG_TOS,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.tclass),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.tclass) },
+	{ "src-port", OPT_BE16, NFC_FLAG_SPORT,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.psrc),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.psrc) },
+	{ "dst-port", OPT_BE16, NFC_FLAG_DPORT,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.tcp_ip6_spec.pdst),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.tcp_ip6_spec.pdst) },
+	{ "action", OPT_U64, NFC_FLAG_RING,
+	  offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 },
+	{ "loc", OPT_U32, NFC_FLAG_LOC,
+	  offsetof(struct ethtool_rx_flow_spec, location), -1 },
+	{ "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH,
+	  offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype),
+	  offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) },
+	{ "vlan", OPT_BE16, NTUPLE_FLAG_VLAN,
+	  offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci),
+	  offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) },
+	{ "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_ip6[] = {
+	{ "src-ip", OPT_IP6, NFC_FLAG_SADDR,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.ip6src),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.ip6src) },
+	{ "dst-ip", OPT_IP6, NFC_FLAG_DADDR,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.ip6dst),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.ip6dst) },
+	{ "tclass", OPT_U8, NFC_FLAG_TOS,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.tclass),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.tclass) },
+	{ "spi", OPT_BE32, NFC_FLAG_SPI,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.esp_ip6_spec.spi),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.esp_ip6_spec.spi) },
+	{ "action", OPT_U64, NFC_FLAG_RING,
+	  offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 },
+	{ "loc", OPT_U32, NFC_FLAG_LOC,
+	  offsetof(struct ethtool_rx_flow_spec, location), -1 },
+	{ "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH,
+	  offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype),
+	  offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) },
+	{ "vlan", OPT_BE16, NTUPLE_FLAG_VLAN,
+	  offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci),
+	  offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) },
+	{ "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_ip6[] = {
+	{ "src-ip", OPT_IP6, NFC_FLAG_SADDR,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.ip6src),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.ip6src) },
+	{ "dst-ip", OPT_IP6, NFC_FLAG_DADDR,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.ip6dst),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.ip6dst) },
+	{ "tclass", OPT_U8, NFC_FLAG_TOS,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.tclass),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.tclass) },
+	{ "l4proto", OPT_U8, NFC_FLAG_PROTO,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_proto),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_proto) },
+	{ "l4data", OPT_BE32, NFC_FLAG_SPI,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) },
+	{ "spi", OPT_BE32, NFC_FLAG_SPI,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) },
+	{ "src-port", OPT_BE16, NFC_FLAG_SPORT,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes),
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) },
+	{ "dst-port", OPT_BE16, NFC_FLAG_DPORT,
+	  offsetof(struct ethtool_rx_flow_spec, h_u.usr_ip6_spec.l4_4_bytes) + 2,
+	  offsetof(struct ethtool_rx_flow_spec, m_u.usr_ip6_spec.l4_4_bytes) + 2 },
+	{ "action", OPT_U64, NFC_FLAG_RING,
+	  offsetof(struct ethtool_rx_flow_spec, ring_cookie), -1 },
+	{ "loc", OPT_U32, NFC_FLAG_LOC,
+	  offsetof(struct ethtool_rx_flow_spec, location), -1 },
+	{ "vlan-etype", OPT_BE16, NTUPLE_FLAG_VETH,
+	  offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_etype),
+	  offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_etype) },
+	{ "vlan", OPT_BE16, NTUPLE_FLAG_VLAN,
+	  offsetof(struct ethtool_rx_flow_spec, h_ext.vlan_tci),
+	  offsetof(struct ethtool_rx_flow_spec, m_ext.vlan_tci) },
+	{ "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[] = {
 	{ "src", OPT_MAC, NFC_FLAG_SADDR,
 	  offsetof(struct ethtool_rx_flow_spec, h_u.ether_spec.h_source),
@@ -726,6 +909,14 @@ static int rxclass_get_ipv4(char *str, __be32 *val)
 	return 0;
 }
 
+static int rxclass_get_ipv6(char *str, __be32 *val)
+{
+	if (!inet_pton(AF_INET6, str, val))
+		return -1;
+
+	return 0;
+}
+
 static int rxclass_get_ether(char *str, unsigned char *val)
 {
 	unsigned int buf[ETH_ALEN];
@@ -851,6 +1042,16 @@ static int rxclass_get_val(char *str, unsigned char *p, u32 *flags,
 			*(__be32 *)&p[opt->moffset] = (__be32)mask;
 		break;
 	}
+	case OPT_IP6: {
+		__be32 val[4];
+		err = rxclass_get_ipv6(str, val);
+		if (err)
+			return -1;
+		memcpy(&p[opt->offset], val, sizeof(val));
+		if (opt->moffset >= 0)
+			memset(&p[opt->moffset], mask, sizeof(val));
+		break;
+	}
 	case OPT_MAC: {
 		unsigned char val[ETH_ALEN];
 		err = rxclass_get_ether(str, val);
@@ -950,6 +1151,17 @@ static int rxclass_get_mask(char *str, unsigned char *p,
 		*(__be32 *)&p[opt->moffset] = ~val;
 		break;
 	}
+	case OPT_IP6: {
+		__be32 val[4], *field;
+		int i;
+		err = rxclass_get_ipv6(str, val);
+		if (err)
+			return -1;
+		field = (__be32 *)&p[opt->moffset];
+		for (i = 0; i < 4; i++)
+			field[i] = ~val[i];
+		break;
+	}
 	case OPT_MAC: {
 		unsigned char val[ETH_ALEN];
 		int i;
@@ -996,7 +1208,19 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx,
 	else if (!strcmp(argp[0], "esp4"))
 		flow_type = ESP_V4_FLOW;
 	else if (!strcmp(argp[0], "ip4"))
-		flow_type = IP_USER_FLOW;
+		flow_type = IPV4_USER_FLOW;
+	else if (!strcmp(argp[0], "tcp6"))
+		flow_type = TCP_V6_FLOW;
+	else if (!strcmp(argp[0], "udp6"))
+		flow_type = UDP_V6_FLOW;
+	else if (!strcmp(argp[0], "sctp6"))
+		flow_type = SCTP_V6_FLOW;
+	else if (!strcmp(argp[0], "ah6"))
+		flow_type = AH_V6_FLOW;
+	else if (!strcmp(argp[0], "esp6"))
+		flow_type = ESP_V6_FLOW;
+	else if (!strcmp(argp[0], "ip6"))
+		flow_type = IPV6_USER_FLOW;
 	else if (!strcmp(argp[0], "ether"))
 		flow_type = ETHER_FLOW;
 	else
@@ -1014,10 +1238,25 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx,
 		options = rule_nfc_esp_ip4;
 		n_opts = ARRAY_SIZE(rule_nfc_esp_ip4);
 		break;
-	case IP_USER_FLOW:
+	case IPV4_USER_FLOW:
 		options = rule_nfc_usr_ip4;
 		n_opts = ARRAY_SIZE(rule_nfc_usr_ip4);
 		break;
+	case TCP_V6_FLOW:
+	case UDP_V6_FLOW:
+	case SCTP_V6_FLOW:
+		options = rule_nfc_tcp_ip6;
+		n_opts = ARRAY_SIZE(rule_nfc_tcp_ip6);
+		break;
+	case AH_V6_FLOW:
+	case ESP_V6_FLOW:
+		options = rule_nfc_esp_ip6;
+		n_opts = ARRAY_SIZE(rule_nfc_esp_ip6);
+		break;
+	case IPV6_USER_FLOW:
+		options = rule_nfc_usr_ip6;
+		n_opts = ARRAY_SIZE(rule_nfc_usr_ip6);
+		break;
 	case ETHER_FLOW:
 		options = rule_nfc_ether;
 		n_opts = ARRAY_SIZE(rule_nfc_ether);
@@ -1081,7 +1320,7 @@ int rxclass_parse_ruleopts(struct cmd_context *ctx,
 		}
 	}
 
-	if (flow_type == IP_USER_FLOW)
+	if (flow_type == IPV4_USER_FLOW)
 		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;

  reply	other threads:[~2016-03-17 19:17 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-17 19:09 [PATCH v2 ethtool 0/2] IPv6 RXNFC Edward Cree
2016-03-17 19:17 ` Edward Cree [this message]
2016-03-17 19:17 ` [PATCH v2 ethtool 2/2] Documentation for IPv6 NFC Edward Cree
2016-04-22 13:41 ` [PATCH v2 ethtool 0/2] IPv6 RXNFC Edward Cree
2016-06-25 23:18 ` Ben Hutchings

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56EB02BC.8070405@solarflare.com \
    --to=ecree@solarflare.com \
    --cc=ben@decadent.org.uk \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.