All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
@ 2017-12-19 23:59 ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

This is an implementation of the ipsec hardware offload feature for
the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
These patches apply to net-next v4.14 as well as Jeff Kirsher's next-queue
v4.15-rc1-206-ge47375b.

The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
Associations (SAs), using up to 128 inbound IP addresses, and using the
rfc4106(gcm(aes)) encryption.  This code does not yet support IPv6,
checksum offload, or TSO in conjunction with the ipsec offload - those
will be added in the future.

This code shows improvements in both packet throughput and CPU utilization.
For example, here are some quicky numbers that show the magnitude of the
performance gain on a single run of "iperf -c <dest>" with the ipsec
offload on both ends of a point-to-point connection:

	9.4 Gbps - normal case
	7.6 Gbps - ipsec with offload
	343 Mbps - ipsec no offload

To set up a similar test case, you first need to be sure you have a recent
version of iproute2 that supports the ipsec offload tag, probably something
from ip 4.12 or newer would be best.  I have a shell script that builds
up the appropriate commands for me, but here are the resulting commands
for all tcp traffic between 14.0.0.52 and 14.0.0.70:

For the left side (14.0.0.52):
  ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
     proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport reqid 0x07
  ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
     proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport reqid 0x07
  ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir out
  ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir in
 
For the right side (14.0.0.70):
  ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
     proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport reqid 0x07
  ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
     proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport reqid 0x07
  ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir out
  ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir in

In both cases, the command "ip x s flush ; ip x p flush" will clean
it all out and remove the offloads.

Lastly, thanks to Alex Duyck for his early comments.

Please see the individual patches for specific update info.

v3: fixes after comments from those wonderfully pesky kbuild robots
v2: fixes after comments from Alex

Shannon Nelson (10):
  ixgbe: clean up ipsec defines
  ixgbe: add ipsec register access routines
  ixgbe: add ipsec engine start and stop routines
  ixgbe: add ipsec data structures
  ixgbe: add ipsec offload add and remove SA
  ixgbe: restore offloaded SAs after a reset
  ixgbe: process the Rx ipsec offload
  ixgbe: process the Tx ipsec offload
  ixgbe: ipsec offload stats
  ixgbe: register ipsec offload with the xfrm subsystem

 drivers/net/ethernet/intel/ixgbe/Makefile        |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   2 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 923 +++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h   |  92 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  39 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  22 +-
 8 files changed, 1093 insertions(+), 23 deletions(-)
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
@ 2017-12-19 23:59 ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

This is an implementation of the ipsec hardware offload feature for
the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
These patches apply to net-next v4.14 as well as Jeff Kirsher's next-queue
v4.15-rc1-206-ge47375b.

The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
Associations (SAs), using up to 128 inbound IP addresses, and using the
rfc4106(gcm(aes)) encryption.  This code does not yet support IPv6,
checksum offload, or TSO in conjunction with the ipsec offload - those
will be added in the future.

This code shows improvements in both packet throughput and CPU utilization.
For example, here are some quicky numbers that show the magnitude of the
performance gain on a single run of "iperf -c <dest>" with the ipsec
offload on both ends of a point-to-point connection:

	9.4 Gbps - normal case
	7.6 Gbps - ipsec with offload
	343 Mbps - ipsec no offload

To set up a similar test case, you first need to be sure you have a recent
version of iproute2 that supports the ipsec offload tag, probably something
from ip 4.12 or newer would be best.  I have a shell script that builds
up the appropriate commands for me, but here are the resulting commands
for all tcp traffic between 14.0.0.52 and 14.0.0.70:

For the left side (14.0.0.52):
  ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
     proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport reqid 0x07
  ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
     proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport reqid 0x07
  ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir out
  ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir in
 
For the right side (14.0.0.70):
  ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
     proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport reqid 0x07
  ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
     proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport reqid 0x07
  ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir out
  ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport \
     reqid 0x07 replay-window 32 \
     aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
     sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir in

In both cases, the command "ip x s flush ; ip x p flush" will clean
it all out and remove the offloads.

Lastly, thanks to Alex Duyck for his early comments.

Please see the individual patches for specific update info.

v3: fixes after comments from those wonderfully pesky kbuild robots
v2: fixes after comments from Alex

Shannon Nelson (10):
  ixgbe: clean up ipsec defines
  ixgbe: add ipsec register access routines
  ixgbe: add ipsec engine start and stop routines
  ixgbe: add ipsec data structures
  ixgbe: add ipsec offload add and remove SA
  ixgbe: restore offloaded SAs after a reset
  ixgbe: process the Rx ipsec offload
  ixgbe: process the Tx ipsec offload
  ixgbe: ipsec offload stats
  ixgbe: register ipsec offload with the xfrm subsystem

 drivers/net/ethernet/intel/ixgbe/Makefile        |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   2 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 923 +++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h   |  92 +++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  39 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  22 +-
 8 files changed, 1093 insertions(+), 23 deletions(-)
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h

-- 
2.7.4


^ permalink raw reply	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 01/10] ixgbe: clean up ipsec defines
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

Clean up the ipsec/macsec descriptor bit definitions to match the rest
of the defines and file organization.  Also recognise the bit-definition
overlap in the error mask macro.

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index ffa0ee5..3df0763 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2321,11 +2321,6 @@ enum {
 #define IXGBE_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
 #define IXGBE_TXD_STAT_DD    0x00000001 /* Descriptor Done */
 
-#define IXGBE_RXDADV_IPSEC_STATUS_SECP                  0x00020000
-#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL       0x08000000
-#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH         0x10000000
-#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED            0x18000000
-#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK               0x18000000
 /* Multiple Transmit Queue Command Register */
 #define IXGBE_MTQC_RT_ENA       0x1 /* DCB Enable */
 #define IXGBE_MTQC_VT_ENA       0x2 /* VMDQ2 Enable */
@@ -2377,6 +2372,9 @@ enum {
 #define IXGBE_RXDADV_ERR_LE     0x02000000 /* Length Error */
 #define IXGBE_RXDADV_ERR_PE     0x08000000 /* Packet Error */
 #define IXGBE_RXDADV_ERR_OSE    0x10000000 /* Oversize Error */
+#define IXGBE_RXDADV_ERR_IPSEC_INV_PROTOCOL  0x08000000 /* overlap ERR_PE  */
+#define IXGBE_RXDADV_ERR_IPSEC_INV_LENGTH    0x10000000 /* overlap ERR_OSE */
+#define IXGBE_RXDADV_ERR_IPSEC_AUTH_FAILED   0x18000000
 #define IXGBE_RXDADV_ERR_USE    0x20000000 /* Undersize Error */
 #define IXGBE_RXDADV_ERR_TCPE   0x40000000 /* TCP/UDP Checksum Error */
 #define IXGBE_RXDADV_ERR_IPE    0x80000000 /* IP Checksum Error */
@@ -2398,6 +2396,7 @@ enum {
 #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
 #define IXGBE_RXDADV_STAT_FCSTAT_DDP    0x00000030 /* 11: Ctxt w/ DDP */
 #define IXGBE_RXDADV_STAT_TS		0x00010000 /* IEEE 1588 Time Stamp */
+#define IXGBE_RXDADV_STAT_SECP          0x00020000 /* IPsec/MACsec pkt found */
 
 /* PSRTYPE bit definitions */
 #define IXGBE_PSRTYPE_TCPHDR    0x00000010
@@ -2464,13 +2463,6 @@ enum {
 #define IXGBE_RXDADV_PKTTYPE_ETQF_MASK  0x00000070 /* ETQF has 8 indices */
 #define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4          /* Right-shift 4 bits */
 
-/* Security Processing bit Indication */
-#define IXGBE_RXDADV_LNKSEC_STATUS_SECP         0x00020000
-#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH   0x08000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR  0x10000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK      0x18000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG       0x18000000
-
 /* Masks to determine if packets should be dropped due to frame errors */
 #define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
 				      IXGBE_RXD_ERR_CE | \
@@ -2484,6 +2476,8 @@ enum {
 				      IXGBE_RXDADV_ERR_LE | \
 				      IXGBE_RXDADV_ERR_PE | \
 				      IXGBE_RXDADV_ERR_OSE | \
+				      IXGBE_RXDADV_ERR_IPSEC_INV_PROTOCOL | \
+				      IXGBE_RXDADV_ERR_IPSEC_INV_LENGTH | \
 				      IXGBE_RXDADV_ERR_USE)
 
 /* Multicast bit mask */
@@ -2893,6 +2887,7 @@ struct ixgbe_adv_tx_context_desc {
 				 IXGBE_ADVTXD_POPTS_SHIFT)
 #define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
 				 IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_POPTS_IPSEC     0x00000400 /* IPSec offload request */
 #define IXGBE_ADVTXD_POPTS_ISCO_1ST  0x00000000 /* 1st TSO of iSCSI PDU */
 #define IXGBE_ADVTXD_POPTS_ISCO_MDL  0x00000800 /* Middle TSO of iSCSI PDU */
 #define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
@@ -2908,7 +2903,6 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_ADVTXD_TUCMD_L4T_SCTP  0x00001000  /* L4 Packet TYPE of SCTP */
 #define IXGBE_ADVTXD_TUCMD_L4T_RSV     0x00001800 /* RSV L4 Packet TYPE */
 #define IXGBE_ADVTXD_TUCMD_MKRREQ    0x00002000 /*Req requires Markers and CRC*/
-#define IXGBE_ADVTXD_POPTS_IPSEC      0x00000400 /* IPSec offload request */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
 #define IXGBE_ADVTXT_TUCMD_FCOE      0x00008000       /* FCoE Frame Type */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 01/10] ixgbe: clean up ipsec defines
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

Clean up the ipsec/macsec descriptor bit definitions to match the rest
of the defines and file organization.  Also recognise the bit-definition
overlap in the error mask macro.

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index ffa0ee5..3df0763 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2321,11 +2321,6 @@ enum {
 #define IXGBE_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
 #define IXGBE_TXD_STAT_DD    0x00000001 /* Descriptor Done */
 
-#define IXGBE_RXDADV_IPSEC_STATUS_SECP                  0x00020000
-#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL       0x08000000
-#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH         0x10000000
-#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED            0x18000000
-#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK               0x18000000
 /* Multiple Transmit Queue Command Register */
 #define IXGBE_MTQC_RT_ENA       0x1 /* DCB Enable */
 #define IXGBE_MTQC_VT_ENA       0x2 /* VMDQ2 Enable */
@@ -2377,6 +2372,9 @@ enum {
 #define IXGBE_RXDADV_ERR_LE     0x02000000 /* Length Error */
 #define IXGBE_RXDADV_ERR_PE     0x08000000 /* Packet Error */
 #define IXGBE_RXDADV_ERR_OSE    0x10000000 /* Oversize Error */
+#define IXGBE_RXDADV_ERR_IPSEC_INV_PROTOCOL  0x08000000 /* overlap ERR_PE  */
+#define IXGBE_RXDADV_ERR_IPSEC_INV_LENGTH    0x10000000 /* overlap ERR_OSE */
+#define IXGBE_RXDADV_ERR_IPSEC_AUTH_FAILED   0x18000000
 #define IXGBE_RXDADV_ERR_USE    0x20000000 /* Undersize Error */
 #define IXGBE_RXDADV_ERR_TCPE   0x40000000 /* TCP/UDP Checksum Error */
 #define IXGBE_RXDADV_ERR_IPE    0x80000000 /* IP Checksum Error */
@@ -2398,6 +2396,7 @@ enum {
 #define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
 #define IXGBE_RXDADV_STAT_FCSTAT_DDP    0x00000030 /* 11: Ctxt w/ DDP */
 #define IXGBE_RXDADV_STAT_TS		0x00010000 /* IEEE 1588 Time Stamp */
+#define IXGBE_RXDADV_STAT_SECP          0x00020000 /* IPsec/MACsec pkt found */
 
 /* PSRTYPE bit definitions */
 #define IXGBE_PSRTYPE_TCPHDR    0x00000010
@@ -2464,13 +2463,6 @@ enum {
 #define IXGBE_RXDADV_PKTTYPE_ETQF_MASK  0x00000070 /* ETQF has 8 indices */
 #define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4          /* Right-shift 4 bits */
 
-/* Security Processing bit Indication */
-#define IXGBE_RXDADV_LNKSEC_STATUS_SECP         0x00020000
-#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH   0x08000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR  0x10000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK      0x18000000
-#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG       0x18000000
-
 /* Masks to determine if packets should be dropped due to frame errors */
 #define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
 				      IXGBE_RXD_ERR_CE | \
@@ -2484,6 +2476,8 @@ enum {
 				      IXGBE_RXDADV_ERR_LE | \
 				      IXGBE_RXDADV_ERR_PE | \
 				      IXGBE_RXDADV_ERR_OSE | \
+				      IXGBE_RXDADV_ERR_IPSEC_INV_PROTOCOL | \
+				      IXGBE_RXDADV_ERR_IPSEC_INV_LENGTH | \
 				      IXGBE_RXDADV_ERR_USE)
 
 /* Multicast bit mask */
@@ -2893,6 +2887,7 @@ struct ixgbe_adv_tx_context_desc {
 				 IXGBE_ADVTXD_POPTS_SHIFT)
 #define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
 				 IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_POPTS_IPSEC     0x00000400 /* IPSec offload request */
 #define IXGBE_ADVTXD_POPTS_ISCO_1ST  0x00000000 /* 1st TSO of iSCSI PDU */
 #define IXGBE_ADVTXD_POPTS_ISCO_MDL  0x00000800 /* Middle TSO of iSCSI PDU */
 #define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
@@ -2908,7 +2903,6 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_ADVTXD_TUCMD_L4T_SCTP  0x00001000  /* L4 Packet TYPE of SCTP */
 #define IXGBE_ADVTXD_TUCMD_L4T_RSV     0x00001800 /* RSV L4 Packet TYPE */
 #define IXGBE_ADVTXD_TUCMD_MKRREQ    0x00002000 /*Req requires Markers and CRC*/
-#define IXGBE_ADVTXD_POPTS_IPSEC      0x00000400 /* IPSec offload request */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
 #define IXGBE_ADVTXT_TUCMD_FCOE      0x00008000       /* FCoE Frame Type */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 02/10] ixgbe: add ipsec register access routines
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

Add a few routines to make access to the ipsec registers just a little
easier, and throw in the beginnings of an initialization.

v3: fixed a couple checkpatch warnings

v2: Rx table selector becomes an enum with a shift
    Combine the clear table loops into one
    Name the table index shift value
    Use the addr as __be32

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/Makefile      |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   6 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 161 +++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h |  53 ++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +
 5 files changed, 222 insertions(+)
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h

diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile
index 35e6fa6..8319465 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -42,3 +42,4 @@ ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
 ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o
 ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o
 ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
+ixgbe-$(CONFIG_XFRM_OFFLOAD) += ixgbe_ipsec.o
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index dd55787..1e11462 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -52,6 +52,7 @@
 #ifdef CONFIG_IXGBE_DCA
 #include <linux/dca.h>
 #endif
+#include "ixgbe_ipsec.h"
 
 #include <net/busy_poll.h>
 
@@ -1001,4 +1002,9 @@ void ixgbe_store_key(struct ixgbe_adapter *adapter);
 void ixgbe_store_reta(struct ixgbe_adapter *adapter);
 s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
+#ifdef CONFIG_XFRM_OFFLOAD
+void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
+#else
+static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
+#endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
new file mode 100644
index 0000000..bd7585f
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ *
+ * Intel 10 Gigabit PCI Express Linux driver
+ * Copyright(c) 2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Linux NICS <linux.nics@intel.com>
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ ******************************************************************************/
+
+#include "ixgbe.h"
+
+/**
+ * ixgbe_ipsec_set_tx_sa - set the Tx SA registers
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @key: key byte array
+ * @salt: salt bytes
+ **/
+static void ixgbe_ipsec_set_tx_sa(struct ixgbe_hw *hw, u16 idx,
+				  u32 key[], u32 salt)
+{
+	u32 reg;
+	int i;
+
+	for (i = 0; i < 4; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(i), cpu_to_be32(key[3 - i]));
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT, cpu_to_be32(salt));
+	IXGBE_WRITE_FLUSH(hw);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_IPSTXIDX);
+	reg &= IXGBE_RXTXIDX_IPS_EN;
+	reg |= idx << IXGBE_RXTXIDX_IDX_SHIFT | IXGBE_RXTXIDX_WRITE;
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, reg);
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_ipsec_set_rx_item - set an Rx table item
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @tbl: table selector
+ *
+ * Trigger the device to store into a particular Rx table the
+ * data that has already been loaded into the input register
+ **/
+static void ixgbe_ipsec_set_rx_item(struct ixgbe_hw *hw, u16 idx,
+				    enum ixgbe_ipsec_tbl_sel tbl)
+{
+	u32 reg;
+
+	reg = IXGBE_READ_REG(hw, IXGBE_IPSRXIDX);
+	reg &= IXGBE_RXTXIDX_IPS_EN;
+	reg |= tbl << IXGBE_RXIDX_TBL_SHIFT |
+	       idx << IXGBE_RXTXIDX_IDX_SHIFT |
+	       IXGBE_RXTXIDX_WRITE;
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, reg);
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_ipsec_set_rx_sa - set up the register bits to save SA info
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @spi: security parameter index
+ * @key: key byte array
+ * @salt: salt bytes
+ * @mode: rx decrypt control bits
+ * @ip_idx: index into IP table for related IP address
+ **/
+static void ixgbe_ipsec_set_rx_sa(struct ixgbe_hw *hw, u16 idx, __be32 spi,
+				  u32 key[], u32 salt, u32 mode, u32 ip_idx)
+{
+	int i;
+
+	/* store the SPI (in bigendian) and IPidx */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXSPI, spi);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIPIDX, ip_idx);
+	IXGBE_WRITE_FLUSH(hw);
+
+	ixgbe_ipsec_set_rx_item(hw, idx, ips_rx_spi_tbl);
+
+	/* store the key, salt, and mode */
+	for (i = 0; i < 4; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(i), cpu_to_be32(key[3 - i]));
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT, cpu_to_be32(salt));
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD, mode);
+	IXGBE_WRITE_FLUSH(hw);
+
+	ixgbe_ipsec_set_rx_item(hw, idx, ips_rx_key_tbl);
+}
+
+/**
+ * ixgbe_ipsec_set_rx_ip - set up the register bits to save SA IP addr info
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @addr: IP address byte array
+ **/
+static void ixgbe_ipsec_set_rx_ip(struct ixgbe_hw *hw, u16 idx, __be32 addr[])
+{
+	int i;
+
+	/* store the ip address */
+	for (i = 0; i < 4; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(i), addr[i]);
+	IXGBE_WRITE_FLUSH(hw);
+
+	ixgbe_ipsec_set_rx_item(hw, idx, ips_rx_ip_tbl);
+}
+
+/**
+ * ixgbe_ipsec_clear_hw_tables - because some tables don't get cleared on reset
+ * @adapter: board private structure
+ **/
+static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 buf[4] = {0, 0, 0, 0};
+	u16 idx;
+
+	/* disable Rx and Tx SA lookup */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, 0);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, 0);
+
+	/* scrub the tables - split the loops for the max of the IP table */
+	for (idx = 0; idx < IXGBE_IPSEC_MAX_RX_IP_COUNT; idx++) {
+		ixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);
+		ixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);
+		ixgbe_ipsec_set_rx_ip(hw, idx, (__be32 *)buf);
+	}
+	for (; idx < IXGBE_IPSEC_MAX_RX_IP_COUNT; idx++) {
+		ixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);
+		ixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);
+	}
+}
+
+/**
+ * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
+ * @adapter: board private structure
+ **/
+void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
+{
+	ixgbe_ipsec_clear_hw_tables(adapter);
+}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
new file mode 100644
index 0000000..8fe8289
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
@@ -0,0 +1,53 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  Copyright(c) 2017 Oracle and/or its affiliates. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _IXGBE_IPSEC_H_
+#define _IXGBE_IPSEC_H_
+
+#define IXGBE_IPSEC_MAX_SA_COUNT	1024
+#define IXGBE_IPSEC_MAX_RX_IP_COUNT	128
+#define IXGBE_IPSEC_BASE_RX_INDEX	0
+#define IXGBE_IPSEC_BASE_TX_INDEX	IXGBE_IPSEC_MAX_SA_COUNT
+
+#define IXGBE_RXTXIDX_IPS_EN		0x00000001
+#define IXGBE_RXIDX_TBL_SHIFT		1
+enum ixgbe_ipsec_tbl_sel {
+	ips_rx_ip_tbl	=	0x01,
+	ips_rx_spi_tbl	=	0x02,
+	ips_rx_key_tbl	=	0x03,
+};
+
+#define IXGBE_RXTXIDX_IDX_SHIFT		3
+#define IXGBE_RXTXIDX_READ		0x40000000
+#define IXGBE_RXTXIDX_WRITE		0x80000000
+
+#define IXGBE_RXMOD_VALID		0x00000001
+#define IXGBE_RXMOD_PROTO_ESP		0x00000004
+#define IXGBE_RXMOD_DECRYPT		0x00000008
+#define IXGBE_RXMOD_IPV6		0x00000010
+
+#endif /* _IXGBE_IPSEC_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 6d5f31e..51fb3cf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10327,6 +10327,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 					 NETIF_F_FCOE_MTU;
 	}
 #endif /* IXGBE_FCOE */
+	ixgbe_init_ipsec_offload(adapter);
 
 	if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
 		netdev->hw_features |= NETIF_F_LRO;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 02/10] ixgbe: add ipsec register access routines
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

Add a few routines to make access to the ipsec registers just a little
easier, and throw in the beginnings of an initialization.

v3: fixed a couple checkpatch warnings

v2: Rx table selector becomes an enum with a shift
    Combine the clear table loops into one
    Name the table index shift value
    Use the addr as __be32

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/Makefile      |   1 +
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   6 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 161 +++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h |  53 ++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +
 5 files changed, 222 insertions(+)
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
 create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h

diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile
index 35e6fa6..8319465 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -42,3 +42,4 @@ ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
 ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o
 ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o
 ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
+ixgbe-$(CONFIG_XFRM_OFFLOAD) += ixgbe_ipsec.o
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index dd55787..1e11462 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -52,6 +52,7 @@
 #ifdef CONFIG_IXGBE_DCA
 #include <linux/dca.h>
 #endif
+#include "ixgbe_ipsec.h"
 
 #include <net/busy_poll.h>
 
@@ -1001,4 +1002,9 @@ void ixgbe_store_key(struct ixgbe_adapter *adapter);
 void ixgbe_store_reta(struct ixgbe_adapter *adapter);
 s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
+#ifdef CONFIG_XFRM_OFFLOAD
+void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
+#else
+static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
+#endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
new file mode 100644
index 0000000..bd7585f
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ *
+ * Intel 10 Gigabit PCI Express Linux driver
+ * Copyright(c) 2017 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Linux NICS <linux.nics@intel.com>
+ * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ ******************************************************************************/
+
+#include "ixgbe.h"
+
+/**
+ * ixgbe_ipsec_set_tx_sa - set the Tx SA registers
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @key: key byte array
+ * @salt: salt bytes
+ **/
+static void ixgbe_ipsec_set_tx_sa(struct ixgbe_hw *hw, u16 idx,
+				  u32 key[], u32 salt)
+{
+	u32 reg;
+	int i;
+
+	for (i = 0; i < 4; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_IPSTXKEY(i), cpu_to_be32(key[3 - i]));
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXSALT, cpu_to_be32(salt));
+	IXGBE_WRITE_FLUSH(hw);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_IPSTXIDX);
+	reg &= IXGBE_RXTXIDX_IPS_EN;
+	reg |= idx << IXGBE_RXTXIDX_IDX_SHIFT | IXGBE_RXTXIDX_WRITE;
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, reg);
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_ipsec_set_rx_item - set an Rx table item
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @tbl: table selector
+ *
+ * Trigger the device to store into a particular Rx table the
+ * data that has already been loaded into the input register
+ **/
+static void ixgbe_ipsec_set_rx_item(struct ixgbe_hw *hw, u16 idx,
+				    enum ixgbe_ipsec_tbl_sel tbl)
+{
+	u32 reg;
+
+	reg = IXGBE_READ_REG(hw, IXGBE_IPSRXIDX);
+	reg &= IXGBE_RXTXIDX_IPS_EN;
+	reg |= tbl << IXGBE_RXIDX_TBL_SHIFT |
+	       idx << IXGBE_RXTXIDX_IDX_SHIFT |
+	       IXGBE_RXTXIDX_WRITE;
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, reg);
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_ipsec_set_rx_sa - set up the register bits to save SA info
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @spi: security parameter index
+ * @key: key byte array
+ * @salt: salt bytes
+ * @mode: rx decrypt control bits
+ * @ip_idx: index into IP table for related IP address
+ **/
+static void ixgbe_ipsec_set_rx_sa(struct ixgbe_hw *hw, u16 idx, __be32 spi,
+				  u32 key[], u32 salt, u32 mode, u32 ip_idx)
+{
+	int i;
+
+	/* store the SPI (in bigendian) and IPidx */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXSPI, spi);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIPIDX, ip_idx);
+	IXGBE_WRITE_FLUSH(hw);
+
+	ixgbe_ipsec_set_rx_item(hw, idx, ips_rx_spi_tbl);
+
+	/* store the key, salt, and mode */
+	for (i = 0; i < 4; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_IPSRXKEY(i), cpu_to_be32(key[3 - i]));
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXSALT, cpu_to_be32(salt));
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXMOD, mode);
+	IXGBE_WRITE_FLUSH(hw);
+
+	ixgbe_ipsec_set_rx_item(hw, idx, ips_rx_key_tbl);
+}
+
+/**
+ * ixgbe_ipsec_set_rx_ip - set up the register bits to save SA IP addr info
+ * @hw: hw specific details
+ * @idx: register index to write
+ * @addr: IP address byte array
+ **/
+static void ixgbe_ipsec_set_rx_ip(struct ixgbe_hw *hw, u16 idx, __be32 addr[])
+{
+	int i;
+
+	/* store the ip address */
+	for (i = 0; i < 4; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_IPSRXIPADDR(i), addr[i]);
+	IXGBE_WRITE_FLUSH(hw);
+
+	ixgbe_ipsec_set_rx_item(hw, idx, ips_rx_ip_tbl);
+}
+
+/**
+ * ixgbe_ipsec_clear_hw_tables - because some tables don't get cleared on reset
+ * @adapter: board private structure
+ **/
+static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 buf[4] = {0, 0, 0, 0};
+	u16 idx;
+
+	/* disable Rx and Tx SA lookup */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, 0);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, 0);
+
+	/* scrub the tables - split the loops for the max of the IP table */
+	for (idx = 0; idx < IXGBE_IPSEC_MAX_RX_IP_COUNT; idx++) {
+		ixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);
+		ixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);
+		ixgbe_ipsec_set_rx_ip(hw, idx, (__be32 *)buf);
+	}
+	for (; idx < IXGBE_IPSEC_MAX_RX_IP_COUNT; idx++) {
+		ixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);
+		ixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);
+	}
+}
+
+/**
+ * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
+ * @adapter: board private structure
+ **/
+void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
+{
+	ixgbe_ipsec_clear_hw_tables(adapter);
+}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
new file mode 100644
index 0000000..8fe8289
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
@@ -0,0 +1,53 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  Copyright(c) 2017 Oracle and/or its affiliates. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _IXGBE_IPSEC_H_
+#define _IXGBE_IPSEC_H_
+
+#define IXGBE_IPSEC_MAX_SA_COUNT	1024
+#define IXGBE_IPSEC_MAX_RX_IP_COUNT	128
+#define IXGBE_IPSEC_BASE_RX_INDEX	0
+#define IXGBE_IPSEC_BASE_TX_INDEX	IXGBE_IPSEC_MAX_SA_COUNT
+
+#define IXGBE_RXTXIDX_IPS_EN		0x00000001
+#define IXGBE_RXIDX_TBL_SHIFT		1
+enum ixgbe_ipsec_tbl_sel {
+	ips_rx_ip_tbl	=	0x01,
+	ips_rx_spi_tbl	=	0x02,
+	ips_rx_key_tbl	=	0x03,
+};
+
+#define IXGBE_RXTXIDX_IDX_SHIFT		3
+#define IXGBE_RXTXIDX_READ		0x40000000
+#define IXGBE_RXTXIDX_WRITE		0x80000000
+
+#define IXGBE_RXMOD_VALID		0x00000001
+#define IXGBE_RXMOD_PROTO_ESP		0x00000004
+#define IXGBE_RXMOD_DECRYPT		0x00000008
+#define IXGBE_RXMOD_IPV6		0x00000010
+
+#endif /* _IXGBE_IPSEC_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 6d5f31e..51fb3cf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10327,6 +10327,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 					 NETIF_F_FCOE_MTU;
 	}
 #endif /* IXGBE_FCOE */
+	ixgbe_init_ipsec_offload(adapter);
 
 	if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)
 		netdev->hw_features |= NETIF_F_LRO;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 03/10] ixgbe: add ipsec engine start and stop routines
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

Add in the code for running and stopping the hardware ipsec
encryption/decryption engine.  It is good to keep the engine
off when not in use in order to save on the power draw.

v2: add limiter to do-while loop waiting for paths to drain

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 142 +++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index bd7585f..85eaafc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -152,10 +152,152 @@ static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
 }
 
 /**
+ * ixgbe_ipsec_stop_data
+ * @adapter: board private structure
+ **/
+static void ixgbe_ipsec_stop_data(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	bool link = adapter->link_up;
+	u32 t_rdy, r_rdy;
+	u32 limit;
+	u32 reg;
+
+	/* halt data paths */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+	reg |= IXGBE_SECTXCTRL_TX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	reg |= IXGBE_SECRXCTRL_RX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);
+
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* If the tx fifo doesn't have link, but still has data,
+	 * we can't clear the tx sec block.  Set the MAC loopback
+	 * before block clear
+	 */
+	if (!link) {
+		reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+		reg |= IXGBE_MACC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_MACC, reg);
+
+		reg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+		reg |= IXGBE_HLREG0_LPBK;
+		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);
+
+		IXGBE_WRITE_FLUSH(hw);
+		mdelay(3);
+	}
+
+	/* wait for the paths to empty */
+	limit = 20;
+	do {
+		mdelay(10);
+		t_rdy = IXGBE_READ_REG(hw, IXGBE_SECTXSTAT) &
+			IXGBE_SECTXSTAT_SECTX_RDY;
+		r_rdy = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT) &
+			IXGBE_SECRXSTAT_SECRX_RDY;
+	} while (!t_rdy && !r_rdy && limit--);
+
+	/* undo loopback if we played with it earlier */
+	if (!link) {
+		reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+		reg &= ~IXGBE_MACC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_MACC, reg);
+
+		reg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+		reg &= ~IXGBE_HLREG0_LPBK;
+		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);
+
+		IXGBE_WRITE_FLUSH(hw);
+	}
+}
+
+/**
+ * ixgbe_ipsec_stop_engine
+ * @adapter: board private structure
+ **/
+static void ixgbe_ipsec_stop_engine(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 reg;
+
+	ixgbe_ipsec_stop_data(adapter);
+
+	/* disable Rx and Tx SA lookup */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, 0);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, 0);
+
+	/* disable the Rx and Tx engines and full packet store-n-forward */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+	reg |= IXGBE_SECTXCTRL_SECTX_DIS;
+	reg &= ~IXGBE_SECTXCTRL_STORE_FORWARD;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	reg |= IXGBE_SECRXCTRL_SECRX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);
+
+	/* restore the "tx security buffer almost full threshold" to 0x250 */
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, 0x250);
+
+	/* Set minimum IFG between packets back to the default 0x1 */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+	reg = (reg & 0xfffffff0) | 0x1;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
+
+	/* final set for normal (no ipsec offload) processing */
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_SECTX_DIS);
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, IXGBE_SECRXCTRL_SECRX_DIS);
+
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_ipsec_start_engine
+ * @adapter: board private structure
+ *
+ * NOTE: this increases power consumption whether being used or not
+ **/
+static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 reg;
+
+	ixgbe_ipsec_stop_data(adapter);
+
+	/* Set minimum IFG between packets to 3 */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+	reg = (reg & 0xfffffff0) | 0x3;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
+
+	/* Set "tx security buffer almost full threshold" to 0x15 so that the
+	 * almost full indication is generated only after buffer contains at
+	 * least an entire jumbo packet.
+	 */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXBUFFAF);
+	reg = (reg & 0xfffffc00) | 0x15;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, reg);
+
+	/* restart the data paths by clearing the DISABLE bits */
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, 0);
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_STORE_FORWARD);
+
+	/* enable Rx and Tx SA lookup */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, IXGBE_RXTXIDX_IPS_EN);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, IXGBE_RXTXIDX_IPS_EN);
+
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
  * @adapter: board private structure
  **/
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
 {
 	ixgbe_ipsec_clear_hw_tables(adapter);
+	ixgbe_ipsec_stop_engine(adapter);
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 03/10] ixgbe: add ipsec engine start and stop routines
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

Add in the code for running and stopping the hardware ipsec
encryption/decryption engine.  It is good to keep the engine
off when not in use in order to save on the power draw.

v2: add limiter to do-while loop waiting for paths to drain

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 142 +++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index bd7585f..85eaafc 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -152,10 +152,152 @@ static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
 }
 
 /**
+ * ixgbe_ipsec_stop_data
+ * @adapter: board private structure
+ **/
+static void ixgbe_ipsec_stop_data(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	bool link = adapter->link_up;
+	u32 t_rdy, r_rdy;
+	u32 limit;
+	u32 reg;
+
+	/* halt data paths */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+	reg |= IXGBE_SECTXCTRL_TX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	reg |= IXGBE_SECRXCTRL_RX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);
+
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* If the tx fifo doesn't have link, but still has data,
+	 * we can't clear the tx sec block.  Set the MAC loopback
+	 * before block clear
+	 */
+	if (!link) {
+		reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+		reg |= IXGBE_MACC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_MACC, reg);
+
+		reg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+		reg |= IXGBE_HLREG0_LPBK;
+		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);
+
+		IXGBE_WRITE_FLUSH(hw);
+		mdelay(3);
+	}
+
+	/* wait for the paths to empty */
+	limit = 20;
+	do {
+		mdelay(10);
+		t_rdy = IXGBE_READ_REG(hw, IXGBE_SECTXSTAT) &
+			IXGBE_SECTXSTAT_SECTX_RDY;
+		r_rdy = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT) &
+			IXGBE_SECRXSTAT_SECRX_RDY;
+	} while (!t_rdy && !r_rdy && limit--);
+
+	/* undo loopback if we played with it earlier */
+	if (!link) {
+		reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+		reg &= ~IXGBE_MACC_FLU;
+		IXGBE_WRITE_REG(hw, IXGBE_MACC, reg);
+
+		reg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
+		reg &= ~IXGBE_HLREG0_LPBK;
+		IXGBE_WRITE_REG(hw, IXGBE_HLREG0, reg);
+
+		IXGBE_WRITE_FLUSH(hw);
+	}
+}
+
+/**
+ * ixgbe_ipsec_stop_engine
+ * @adapter: board private structure
+ **/
+static void ixgbe_ipsec_stop_engine(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 reg;
+
+	ixgbe_ipsec_stop_data(adapter);
+
+	/* disable Rx and Tx SA lookup */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, 0);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, 0);
+
+	/* disable the Rx and Tx engines and full packet store-n-forward */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXCTRL);
+	reg |= IXGBE_SECTXCTRL_SECTX_DIS;
+	reg &= ~IXGBE_SECTXCTRL_STORE_FORWARD;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, reg);
+
+	reg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+	reg |= IXGBE_SECRXCTRL_SECRX_DIS;
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, reg);
+
+	/* restore the "tx security buffer almost full threshold" to 0x250 */
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, 0x250);
+
+	/* Set minimum IFG between packets back to the default 0x1 */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+	reg = (reg & 0xfffffff0) | 0x1;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
+
+	/* final set for normal (no ipsec offload) processing */
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_SECTX_DIS);
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, IXGBE_SECRXCTRL_SECRX_DIS);
+
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_ipsec_start_engine
+ * @adapter: board private structure
+ *
+ * NOTE: this increases power consumption whether being used or not
+ **/
+static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 reg;
+
+	ixgbe_ipsec_stop_data(adapter);
+
+	/* Set minimum IFG between packets to 3 */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXMINIFG);
+	reg = (reg & 0xfffffff0) | 0x3;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXMINIFG, reg);
+
+	/* Set "tx security buffer almost full threshold" to 0x15 so that the
+	 * almost full indication is generated only after buffer contains at
+	 * least an entire jumbo packet.
+	 */
+	reg = IXGBE_READ_REG(hw, IXGBE_SECTXBUFFAF);
+	reg = (reg & 0xfffffc00) | 0x15;
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXBUFFAF, reg);
+
+	/* restart the data paths by clearing the DISABLE bits */
+	IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, 0);
+	IXGBE_WRITE_REG(hw, IXGBE_SECTXCTRL, IXGBE_SECTXCTRL_STORE_FORWARD);
+
+	/* enable Rx and Tx SA lookup */
+	IXGBE_WRITE_REG(hw, IXGBE_IPSTXIDX, IXGBE_RXTXIDX_IPS_EN);
+	IXGBE_WRITE_REG(hw, IXGBE_IPSRXIDX, IXGBE_RXTXIDX_IPS_EN);
+
+	IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
  * @adapter: board private structure
  **/
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
 {
 	ixgbe_ipsec_clear_hw_tables(adapter);
+	ixgbe_ipsec_stop_engine(adapter);
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 04/10] ixgbe: add ipsec data structures
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

Set up the data structures to be used by the ipsec offload.

v2: ipaddr[] becomes __be32
    increase the hash table size

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  5 ++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h | 40 ++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 1e11462..9487750 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -622,6 +622,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_EEE_CAPABLE			BIT(14)
 #define IXGBE_FLAG2_EEE_ENABLED			BIT(15)
 #define IXGBE_FLAG2_RX_LEGACY			BIT(16)
+#define IXGBE_FLAG2_IPSEC_ENABLED		BIT(17)
 
 	/* Tx fast path data */
 	int num_tx_queues;
@@ -772,6 +773,10 @@ struct ixgbe_adapter {
 
 #define IXGBE_RSS_KEY_SIZE     40  /* size of RSS Hash Key in bytes */
 	u32 *rss_key;
+
+#ifdef CONFIG_XFRM
+	struct ixgbe_ipsec *ipsec;
+#endif /* CONFIG_XFRM */
 };
 
 static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
index 8fe8289..da3ce78 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
@@ -50,4 +50,44 @@ enum ixgbe_ipsec_tbl_sel {
 #define IXGBE_RXMOD_DECRYPT		0x00000008
 #define IXGBE_RXMOD_IPV6		0x00000010
 
+struct rx_sa {
+	struct hlist_node hlist;
+	struct xfrm_state *xs;
+	__be32 ipaddr[4];
+	u32 key[4];
+	u32 salt;
+	u32 mode;
+	u8  iptbl_ind;
+	bool used;
+	bool decrypt;
+};
+
+struct rx_ip_sa {
+	__be32 ipaddr[4];
+	u32 ref_cnt;
+	bool used;
+};
+
+struct tx_sa {
+	struct xfrm_state *xs;
+	u32 key[4];
+	u32 salt;
+	bool encrypt;
+	bool used;
+};
+
+struct ixgbe_ipsec_tx_data {
+	u32 flags;
+	u16 trailer_len;
+	u16 sa_idx;
+};
+
+struct ixgbe_ipsec {
+	u16 num_rx_sa;
+	u16 num_tx_sa;
+	struct rx_ip_sa *ip_tbl;
+	struct rx_sa *rx_tbl;
+	struct tx_sa *tx_tbl;
+	DECLARE_HASHTABLE(rx_sa_list, 10);
+};
 #endif /* _IXGBE_IPSEC_H_ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 04/10] ixgbe: add ipsec data structures
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

Set up the data structures to be used by the ipsec offload.

v2: ipaddr[] becomes __be32
    increase the hash table size

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  5 ++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h | 40 ++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 1e11462..9487750 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -622,6 +622,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG2_EEE_CAPABLE			BIT(14)
 #define IXGBE_FLAG2_EEE_ENABLED			BIT(15)
 #define IXGBE_FLAG2_RX_LEGACY			BIT(16)
+#define IXGBE_FLAG2_IPSEC_ENABLED		BIT(17)
 
 	/* Tx fast path data */
 	int num_tx_queues;
@@ -772,6 +773,10 @@ struct ixgbe_adapter {
 
 #define IXGBE_RSS_KEY_SIZE     40  /* size of RSS Hash Key in bytes */
 	u32 *rss_key;
+
+#ifdef CONFIG_XFRM
+	struct ixgbe_ipsec *ipsec;
+#endif /* CONFIG_XFRM */
 };
 
 static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
index 8fe8289..da3ce78 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
@@ -50,4 +50,44 @@ enum ixgbe_ipsec_tbl_sel {
 #define IXGBE_RXMOD_DECRYPT		0x00000008
 #define IXGBE_RXMOD_IPV6		0x00000010
 
+struct rx_sa {
+	struct hlist_node hlist;
+	struct xfrm_state *xs;
+	__be32 ipaddr[4];
+	u32 key[4];
+	u32 salt;
+	u32 mode;
+	u8  iptbl_ind;
+	bool used;
+	bool decrypt;
+};
+
+struct rx_ip_sa {
+	__be32 ipaddr[4];
+	u32 ref_cnt;
+	bool used;
+};
+
+struct tx_sa {
+	struct xfrm_state *xs;
+	u32 key[4];
+	u32 salt;
+	bool encrypt;
+	bool used;
+};
+
+struct ixgbe_ipsec_tx_data {
+	u32 flags;
+	u16 trailer_len;
+	u16 sa_idx;
+};
+
+struct ixgbe_ipsec {
+	u16 num_rx_sa;
+	u16 num_tx_sa;
+	struct rx_ip_sa *ip_tbl;
+	struct rx_sa *rx_tbl;
+	struct tx_sa *tx_tbl;
+	DECLARE_HASHTABLE(rx_sa_list, 10);
+};
 #endif /* _IXGBE_IPSEC_H_ */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

Add the functions for setting up and removing offloaded SAs (Security
Associations) with the x540 hardware.  We set up the callback structure
but we don't yet set the hardware feature bit to be sure the XFRM service
won't actually try to use us for an offload yet.

The software tables are made up to mimic the hardware tables to make it
easier to track what's in the hardware, and the SA table index is used
for the XFRM offload handle.  However, there is a hashing field in the
Rx SA tracking that will be used to facilitate faster table searches in
the Rx fast path.

v2: fix use of num_rx_sa that should be num_tx_sa
    change aes_gcm_name to a const array
    tighten up the key parsing code
    add another label to the init error handling
    move table deletion to a separate function

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   2 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 394 ++++++++++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +
 3 files changed, 396 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 9487750..8f41508 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1009,7 +1009,9 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
 #ifdef CONFIG_XFRM_OFFLOAD
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
+void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
+static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 85eaafc..96971ce 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -26,6 +26,8 @@
  ******************************************************************************/
 
 #include "ixgbe.h"
+#include <net/xfrm.h>
+#include <crypto/aead.h>
 
 /**
  * ixgbe_ipsec_set_tx_sa - set the Tx SA registers
@@ -131,6 +133,7 @@ static void ixgbe_ipsec_set_rx_ip(struct ixgbe_hw *hw, u16 idx, __be32 addr[])
  **/
 static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
 {
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 buf[4] = {0, 0, 0, 0};
 	u16 idx;
@@ -149,6 +152,9 @@ static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
 		ixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);
 		ixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);
 	}
+
+	ipsec->num_rx_sa = 0;
+	ipsec->num_tx_sa = 0;
 }
 
 /**
@@ -293,11 +299,397 @@ static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
 }
 
 /**
+ * ixgbe_ipsec_find_empty_idx - find the first unused security parameter index
+ * @ipsec: pointer to ipsec struct
+ * @rxtable: true if we need to look in the Rx table
+ *
+ * Returns the first unused index in either the Rx or Tx SA table
+ **/
+static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable)
+{
+	u32 i;
+
+	if (rxtable) {
+		if (ipsec->num_rx_sa == IXGBE_IPSEC_MAX_SA_COUNT)
+			return -ENOSPC;
+
+		/* search rx sa table */
+		for (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {
+			if (!ipsec->rx_tbl[i].used)
+				return i;
+		}
+	} else {
+		if (ipsec->num_tx_sa == IXGBE_IPSEC_MAX_SA_COUNT)
+			return -ENOSPC;
+
+		/* search tx sa table */
+		for (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {
+			if (!ipsec->tx_tbl[i].used)
+				return i;
+		}
+	}
+
+	return -ENOSPC;
+}
+
+/**
+ * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol
+ * @xs: pointer to xfrm_state struct
+ * @mykey: pointer to key array to populate
+ * @mysalt: pointer to salt value to populate
+ *
+ * This copies the protocol keys and salt to our own data tables.  The
+ * 82599 family only supports the one algorithm.
+ **/
+static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
+					u32 *mykey, u32 *mysalt)
+{
+	struct net_device *dev = xs->xso.dev;
+	unsigned char *key_data;
+	char *alg_name = NULL;
+	const char aes_gcm_name[] = "rfc4106(gcm(aes))";
+	int key_len;
+
+	if (xs->aead) {
+		key_data = &xs->aead->alg_key[0];
+		key_len = xs->aead->alg_key_len;
+		alg_name = xs->aead->alg_name;
+	} else {
+		netdev_err(dev, "Unsupported IPsec algorithm\n");
+		return -EINVAL;
+	}
+
+	if (strcmp(alg_name, aes_gcm_name)) {
+		netdev_err(dev, "Unsupported IPsec algorithm - please use %s\n",
+			   aes_gcm_name);
+		return -EINVAL;
+	}
+
+	/* The key bytes come down in a bigendian array of bytes, so
+	 * we don't need to do any byteswapping.
+	 * 160 accounts for 16 byte key and 4 byte salt
+	 */
+	if (key_len == 160) {
+		*mysalt = ((u32 *)key_data)[4];
+	} else if (key_len != 128) {
+		netdev_err(dev, "IPsec hw offload only supports keys up to 128 bits with a 32 bit salt\n");
+		return -EINVAL;
+	} else {
+		netdev_info(dev, "IPsec hw offload parameters missing 32 bit salt value\n");
+		*mysalt = 0;
+	}
+	memcpy(mykey, key_data, 16);
+
+	return 0;
+}
+
+/**
+ * ixgbe_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
+{
+	struct net_device *dev = xs->xso.dev;
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct ixgbe_hw *hw = &adapter->hw;
+	int checked, match, first;
+	u16 sa_idx;
+	int ret;
+	int i;
+
+	if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
+		netdev_err(dev, "Unsupported protocol 0x%04x for ipsec offload\n",
+			   xs->id.proto);
+		return -EINVAL;
+	}
+
+	if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
+		struct rx_sa rsa;
+
+		if (xs->calg) {
+			netdev_err(dev, "Compression offload not supported\n");
+			return -EINVAL;
+		}
+
+		/* find the first unused index */
+		ret = ixgbe_ipsec_find_empty_idx(ipsec, true);
+		if (ret < 0) {
+			netdev_err(dev, "No space for SA in Rx table!\n");
+			return ret;
+		}
+		sa_idx = (u16)ret;
+
+		memset(&rsa, 0, sizeof(rsa));
+		rsa.used = true;
+		rsa.xs = xs;
+
+		if (rsa.xs->id.proto & IPPROTO_ESP)
+			rsa.decrypt = xs->ealg || xs->aead;
+
+		/* get the key and salt */
+		ret = ixgbe_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);
+		if (ret) {
+			netdev_err(dev, "Failed to get key data for Rx SA table\n");
+			return ret;
+		}
+
+		/* get ip for rx sa table */
+		if (xs->xso.flags & XFRM_OFFLOAD_IPV6)
+			memcpy(rsa.ipaddr, &xs->id.daddr.a6, 16);
+		else
+			memcpy(&rsa.ipaddr[3], &xs->id.daddr.a4, 4);
+
+		/* The HW does not have a 1:1 mapping from keys to IP addrs, so
+		 * check for a matching IP addr entry in the table.  If the addr
+		 * already exists, use it; else find an unused slot and add the
+		 * addr.  If one does not exist and there are no unused table
+		 * entries, fail the request.
+		 */
+
+		/* Find an existing match or first not used, and stop looking
+		 * after we've checked all we know we have.
+		 */
+		checked = 0;
+		match = -1;
+		first = -1;
+		for (i = 0;
+		     i < IXGBE_IPSEC_MAX_RX_IP_COUNT &&
+		     (checked < ipsec->num_rx_sa || first < 0);
+		     i++) {
+			if (ipsec->ip_tbl[i].used) {
+				if (!memcmp(ipsec->ip_tbl[i].ipaddr,
+					    rsa.ipaddr, sizeof(rsa.ipaddr))) {
+					match = i;
+					break;
+				}
+				checked++;
+			} else if (first < 0) {
+				first = i;  /* track the first empty seen */
+			}
+		}
+
+		if (ipsec->num_rx_sa == 0)
+			first = 0;
+
+		if (match >= 0) {
+			/* addrs are the same, we should use this one */
+			rsa.iptbl_ind = match;
+			ipsec->ip_tbl[match].ref_cnt++;
+
+		} else if (first >= 0) {
+			/* no matches, but here's an empty slot */
+			rsa.iptbl_ind = first;
+
+			memcpy(ipsec->ip_tbl[first].ipaddr,
+			       rsa.ipaddr, sizeof(rsa.ipaddr));
+			ipsec->ip_tbl[first].ref_cnt = 1;
+			ipsec->ip_tbl[first].used = true;
+
+			ixgbe_ipsec_set_rx_ip(hw, rsa.iptbl_ind, rsa.ipaddr);
+
+		} else {
+			/* no match and no empty slot */
+			netdev_err(dev, "No space for SA in Rx IP SA table\n");
+			memset(&rsa, 0, sizeof(rsa));
+			return -ENOSPC;
+		}
+
+		rsa.mode = IXGBE_RXMOD_VALID;
+		if (rsa.xs->id.proto & IPPROTO_ESP)
+			rsa.mode |= IXGBE_RXMOD_PROTO_ESP;
+		if (rsa.decrypt)
+			rsa.mode |= IXGBE_RXMOD_DECRYPT;
+		if (rsa.xs->xso.flags & XFRM_OFFLOAD_IPV6)
+			rsa.mode |= IXGBE_RXMOD_IPV6;
+
+		/* the preparations worked, so save the info */
+		memcpy(&ipsec->rx_tbl[sa_idx], &rsa, sizeof(rsa));
+
+		ixgbe_ipsec_set_rx_sa(hw, sa_idx, rsa.xs->id.spi, rsa.key,
+				      rsa.salt, rsa.mode, rsa.iptbl_ind);
+		xs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_RX_INDEX;
+
+		ipsec->num_rx_sa++;
+
+		/* hash the new entry for faster search in Rx path */
+		hash_add_rcu(ipsec->rx_sa_list, &ipsec->rx_tbl[sa_idx].hlist,
+			     rsa.xs->id.spi);
+	} else {
+		struct tx_sa tsa;
+
+		/* find the first unused index */
+		ret = ixgbe_ipsec_find_empty_idx(ipsec, false);
+		if (ret < 0) {
+			netdev_err(dev, "No space for SA in Tx table\n");
+			return ret;
+		}
+		sa_idx = (u16)ret;
+
+		memset(&tsa, 0, sizeof(tsa));
+		tsa.used = true;
+		tsa.xs = xs;
+
+		if (xs->id.proto & IPPROTO_ESP)
+			tsa.encrypt = xs->ealg || xs->aead;
+
+		ret = ixgbe_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);
+		if (ret) {
+			netdev_err(dev, "Failed to get key data for Tx SA table\n");
+			memset(&tsa, 0, sizeof(tsa));
+			return ret;
+		}
+
+		/* the preparations worked, so save the info */
+		memcpy(&ipsec->tx_tbl[sa_idx], &tsa, sizeof(tsa));
+
+		ixgbe_ipsec_set_tx_sa(hw, sa_idx, tsa.key, tsa.salt);
+
+		xs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_TX_INDEX;
+
+		ipsec->num_tx_sa++;
+	}
+
+	/* enable the engine if not already warmed up */
+	if (!(adapter->flags2 & IXGBE_FLAG2_IPSEC_ENABLED)) {
+		ixgbe_ipsec_start_engine(adapter);
+		adapter->flags2 |= IXGBE_FLAG2_IPSEC_ENABLED;
+	}
+
+	return 0;
+}
+
+/**
+ * ixgbe_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
+{
+	struct net_device *dev = xs->xso.dev;
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 zerobuf[4] = {0, 0, 0, 0};
+	u16 sa_idx;
+
+	if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
+		struct rx_sa *rsa;
+		u8 ipi;
+
+		sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX;
+		rsa = &ipsec->rx_tbl[sa_idx];
+
+		if (!rsa->used) {
+			netdev_err(dev, "Invalid Rx SA selected sa_idx=%d offload_handle=%lu\n",
+				   sa_idx, xs->xso.offload_handle);
+			return;
+		}
+
+		ixgbe_ipsec_set_rx_sa(hw, sa_idx, 0, zerobuf, 0, 0, 0);
+		hash_del_rcu(&rsa->hlist);
+
+		/* if the IP table entry is referenced by only this SA,
+		 * i.e. ref_cnt is only 1, clear the IP table entry as well
+		 */
+		ipi = rsa->iptbl_ind;
+		if (ipsec->ip_tbl[ipi].ref_cnt > 0) {
+			ipsec->ip_tbl[ipi].ref_cnt--;
+
+			if (!ipsec->ip_tbl[ipi].ref_cnt) {
+				memset(&ipsec->ip_tbl[ipi], 0,
+				       sizeof(struct rx_ip_sa));
+				ixgbe_ipsec_set_rx_ip(hw, ipi, zerobuf);
+			}
+		}
+
+		memset(rsa, 0, sizeof(struct rx_sa));
+		ipsec->num_rx_sa--;
+	} else {
+		sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;
+
+		if (!ipsec->tx_tbl[sa_idx].used) {
+			netdev_err(dev, "Invalid Tx SA selected sa_idx=%d offload_handle=%lu\n",
+				   sa_idx, xs->xso.offload_handle);
+			return;
+		}
+
+		ixgbe_ipsec_set_tx_sa(hw, sa_idx, zerobuf, 0);
+		memset(&ipsec->tx_tbl[sa_idx], 0, sizeof(struct tx_sa));
+		ipsec->num_tx_sa--;
+	}
+
+	/* if there are no SAs left, stop the engine to save energy */
+	if (ipsec->num_rx_sa == 0 && ipsec->num_tx_sa == 0) {
+		adapter->flags2 &= ~IXGBE_FLAG2_IPSEC_ENABLED;
+		ixgbe_ipsec_stop_engine(adapter);
+	}
+}
+
+static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
+	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
+	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
+};
+
+/**
  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
  * @adapter: board private structure
  **/
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
 {
-	ixgbe_ipsec_clear_hw_tables(adapter);
+	struct ixgbe_ipsec *ipsec;
+	size_t size;
+
+	ipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL);
+	if (!ipsec)
+		goto err1;
+	hash_init(ipsec->rx_sa_list);
+
+	size = sizeof(struct rx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;
+	ipsec->rx_tbl = kzalloc(size, GFP_KERNEL);
+	if (!ipsec->rx_tbl)
+		goto err2;
+
+	size = sizeof(struct tx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;
+	ipsec->tx_tbl = kzalloc(size, GFP_KERNEL);
+	if (!ipsec->tx_tbl)
+		goto err2;
+
+	size = sizeof(struct rx_ip_sa) * IXGBE_IPSEC_MAX_RX_IP_COUNT;
+	ipsec->ip_tbl = kzalloc(size, GFP_KERNEL);
+	if (!ipsec->ip_tbl)
+		goto err2;
+
+	ipsec->num_rx_sa = 0;
+	ipsec->num_tx_sa = 0;
+
+	adapter->ipsec = ipsec;
 	ixgbe_ipsec_stop_engine(adapter);
+	ixgbe_ipsec_clear_hw_tables(adapter);
+
+	return;
+
+err2:
+	kfree(ipsec->ip_tbl);
+	kfree(ipsec->rx_tbl);
+	kfree(ipsec->tx_tbl);
+err1:
+	kfree(adapter->ipsec);
+	netdev_err(adapter->netdev, "Unable to allocate memory for SA tables");
+}
+
+/**
+ * ixgbe_stop_ipsec_offload - tear down the ipsec offload
+ * @adapter: board private structure
+ **/
+void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+
+	adapter->ipsec = NULL;
+	if (ipsec) {
+		kfree(ipsec->ip_tbl);
+		kfree(ipsec->rx_tbl);
+		kfree(ipsec->tx_tbl);
+		kfree(ipsec);
+	}
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 51fb3cf..2b3da0c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10565,6 +10565,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
 	if (netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(netdev);
 
+	ixgbe_stop_ipsec_offload(adapter);
 	ixgbe_clear_interrupt_scheme(adapter);
 
 	ixgbe_release_hw_control(adapter);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

Add the functions for setting up and removing offloaded SAs (Security
Associations) with the x540 hardware.  We set up the callback structure
but we don't yet set the hardware feature bit to be sure the XFRM service
won't actually try to use us for an offload yet.

The software tables are made up to mimic the hardware tables to make it
easier to track what's in the hardware, and the SA table index is used
for the XFRM offload handle.  However, there is a hashing field in the
Rx SA tracking that will be used to facilitate faster table searches in
the Rx fast path.

v2: fix use of num_rx_sa that should be num_tx_sa
    change aes_gcm_name to a const array
    tighten up the key parsing code
    add another label to the init error handling
    move table deletion to a separate function

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   2 +
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 394 ++++++++++++++++++++++++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +
 3 files changed, 396 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 9487750..8f41508 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1009,7 +1009,9 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 		       u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
 #ifdef CONFIG_XFRM_OFFLOAD
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
+void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
+static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 85eaafc..96971ce 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -26,6 +26,8 @@
  ******************************************************************************/
 
 #include "ixgbe.h"
+#include <net/xfrm.h>
+#include <crypto/aead.h>
 
 /**
  * ixgbe_ipsec_set_tx_sa - set the Tx SA registers
@@ -131,6 +133,7 @@ static void ixgbe_ipsec_set_rx_ip(struct ixgbe_hw *hw, u16 idx, __be32 addr[])
  **/
 static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
 {
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 buf[4] = {0, 0, 0, 0};
 	u16 idx;
@@ -149,6 +152,9 @@ static void ixgbe_ipsec_clear_hw_tables(struct ixgbe_adapter *adapter)
 		ixgbe_ipsec_set_tx_sa(hw, idx, buf, 0);
 		ixgbe_ipsec_set_rx_sa(hw, idx, 0, buf, 0, 0, 0);
 	}
+
+	ipsec->num_rx_sa = 0;
+	ipsec->num_tx_sa = 0;
 }
 
 /**
@@ -293,11 +299,397 @@ static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
 }
 
 /**
+ * ixgbe_ipsec_find_empty_idx - find the first unused security parameter index
+ * @ipsec: pointer to ipsec struct
+ * @rxtable: true if we need to look in the Rx table
+ *
+ * Returns the first unused index in either the Rx or Tx SA table
+ **/
+static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable)
+{
+	u32 i;
+
+	if (rxtable) {
+		if (ipsec->num_rx_sa == IXGBE_IPSEC_MAX_SA_COUNT)
+			return -ENOSPC;
+
+		/* search rx sa table */
+		for (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {
+			if (!ipsec->rx_tbl[i].used)
+				return i;
+		}
+	} else {
+		if (ipsec->num_tx_sa == IXGBE_IPSEC_MAX_SA_COUNT)
+			return -ENOSPC;
+
+		/* search tx sa table */
+		for (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {
+			if (!ipsec->tx_tbl[i].used)
+				return i;
+		}
+	}
+
+	return -ENOSPC;
+}
+
+/**
+ * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol
+ * @xs: pointer to xfrm_state struct
+ * @mykey: pointer to key array to populate
+ * @mysalt: pointer to salt value to populate
+ *
+ * This copies the protocol keys and salt to our own data tables.  The
+ * 82599 family only supports the one algorithm.
+ **/
+static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
+					u32 *mykey, u32 *mysalt)
+{
+	struct net_device *dev = xs->xso.dev;
+	unsigned char *key_data;
+	char *alg_name = NULL;
+	const char aes_gcm_name[] = "rfc4106(gcm(aes))";
+	int key_len;
+
+	if (xs->aead) {
+		key_data = &xs->aead->alg_key[0];
+		key_len = xs->aead->alg_key_len;
+		alg_name = xs->aead->alg_name;
+	} else {
+		netdev_err(dev, "Unsupported IPsec algorithm\n");
+		return -EINVAL;
+	}
+
+	if (strcmp(alg_name, aes_gcm_name)) {
+		netdev_err(dev, "Unsupported IPsec algorithm - please use %s\n",
+			   aes_gcm_name);
+		return -EINVAL;
+	}
+
+	/* The key bytes come down in a bigendian array of bytes, so
+	 * we don't need to do any byteswapping.
+	 * 160 accounts for 16 byte key and 4 byte salt
+	 */
+	if (key_len == 160) {
+		*mysalt = ((u32 *)key_data)[4];
+	} else if (key_len != 128) {
+		netdev_err(dev, "IPsec hw offload only supports keys up to 128 bits with a 32 bit salt\n");
+		return -EINVAL;
+	} else {
+		netdev_info(dev, "IPsec hw offload parameters missing 32 bit salt value\n");
+		*mysalt = 0;
+	}
+	memcpy(mykey, key_data, 16);
+
+	return 0;
+}
+
+/**
+ * ixgbe_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
+{
+	struct net_device *dev = xs->xso.dev;
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct ixgbe_hw *hw = &adapter->hw;
+	int checked, match, first;
+	u16 sa_idx;
+	int ret;
+	int i;
+
+	if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
+		netdev_err(dev, "Unsupported protocol 0x%04x for ipsec offload\n",
+			   xs->id.proto);
+		return -EINVAL;
+	}
+
+	if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
+		struct rx_sa rsa;
+
+		if (xs->calg) {
+			netdev_err(dev, "Compression offload not supported\n");
+			return -EINVAL;
+		}
+
+		/* find the first unused index */
+		ret = ixgbe_ipsec_find_empty_idx(ipsec, true);
+		if (ret < 0) {
+			netdev_err(dev, "No space for SA in Rx table!\n");
+			return ret;
+		}
+		sa_idx = (u16)ret;
+
+		memset(&rsa, 0, sizeof(rsa));
+		rsa.used = true;
+		rsa.xs = xs;
+
+		if (rsa.xs->id.proto & IPPROTO_ESP)
+			rsa.decrypt = xs->ealg || xs->aead;
+
+		/* get the key and salt */
+		ret = ixgbe_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);
+		if (ret) {
+			netdev_err(dev, "Failed to get key data for Rx SA table\n");
+			return ret;
+		}
+
+		/* get ip for rx sa table */
+		if (xs->xso.flags & XFRM_OFFLOAD_IPV6)
+			memcpy(rsa.ipaddr, &xs->id.daddr.a6, 16);
+		else
+			memcpy(&rsa.ipaddr[3], &xs->id.daddr.a4, 4);
+
+		/* The HW does not have a 1:1 mapping from keys to IP addrs, so
+		 * check for a matching IP addr entry in the table.  If the addr
+		 * already exists, use it; else find an unused slot and add the
+		 * addr.  If one does not exist and there are no unused table
+		 * entries, fail the request.
+		 */
+
+		/* Find an existing match or first not used, and stop looking
+		 * after we've checked all we know we have.
+		 */
+		checked = 0;
+		match = -1;
+		first = -1;
+		for (i = 0;
+		     i < IXGBE_IPSEC_MAX_RX_IP_COUNT &&
+		     (checked < ipsec->num_rx_sa || first < 0);
+		     i++) {
+			if (ipsec->ip_tbl[i].used) {
+				if (!memcmp(ipsec->ip_tbl[i].ipaddr,
+					    rsa.ipaddr, sizeof(rsa.ipaddr))) {
+					match = i;
+					break;
+				}
+				checked++;
+			} else if (first < 0) {
+				first = i;  /* track the first empty seen */
+			}
+		}
+
+		if (ipsec->num_rx_sa == 0)
+			first = 0;
+
+		if (match >= 0) {
+			/* addrs are the same, we should use this one */
+			rsa.iptbl_ind = match;
+			ipsec->ip_tbl[match].ref_cnt++;
+
+		} else if (first >= 0) {
+			/* no matches, but here's an empty slot */
+			rsa.iptbl_ind = first;
+
+			memcpy(ipsec->ip_tbl[first].ipaddr,
+			       rsa.ipaddr, sizeof(rsa.ipaddr));
+			ipsec->ip_tbl[first].ref_cnt = 1;
+			ipsec->ip_tbl[first].used = true;
+
+			ixgbe_ipsec_set_rx_ip(hw, rsa.iptbl_ind, rsa.ipaddr);
+
+		} else {
+			/* no match and no empty slot */
+			netdev_err(dev, "No space for SA in Rx IP SA table\n");
+			memset(&rsa, 0, sizeof(rsa));
+			return -ENOSPC;
+		}
+
+		rsa.mode = IXGBE_RXMOD_VALID;
+		if (rsa.xs->id.proto & IPPROTO_ESP)
+			rsa.mode |= IXGBE_RXMOD_PROTO_ESP;
+		if (rsa.decrypt)
+			rsa.mode |= IXGBE_RXMOD_DECRYPT;
+		if (rsa.xs->xso.flags & XFRM_OFFLOAD_IPV6)
+			rsa.mode |= IXGBE_RXMOD_IPV6;
+
+		/* the preparations worked, so save the info */
+		memcpy(&ipsec->rx_tbl[sa_idx], &rsa, sizeof(rsa));
+
+		ixgbe_ipsec_set_rx_sa(hw, sa_idx, rsa.xs->id.spi, rsa.key,
+				      rsa.salt, rsa.mode, rsa.iptbl_ind);
+		xs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_RX_INDEX;
+
+		ipsec->num_rx_sa++;
+
+		/* hash the new entry for faster search in Rx path */
+		hash_add_rcu(ipsec->rx_sa_list, &ipsec->rx_tbl[sa_idx].hlist,
+			     rsa.xs->id.spi);
+	} else {
+		struct tx_sa tsa;
+
+		/* find the first unused index */
+		ret = ixgbe_ipsec_find_empty_idx(ipsec, false);
+		if (ret < 0) {
+			netdev_err(dev, "No space for SA in Tx table\n");
+			return ret;
+		}
+		sa_idx = (u16)ret;
+
+		memset(&tsa, 0, sizeof(tsa));
+		tsa.used = true;
+		tsa.xs = xs;
+
+		if (xs->id.proto & IPPROTO_ESP)
+			tsa.encrypt = xs->ealg || xs->aead;
+
+		ret = ixgbe_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);
+		if (ret) {
+			netdev_err(dev, "Failed to get key data for Tx SA table\n");
+			memset(&tsa, 0, sizeof(tsa));
+			return ret;
+		}
+
+		/* the preparations worked, so save the info */
+		memcpy(&ipsec->tx_tbl[sa_idx], &tsa, sizeof(tsa));
+
+		ixgbe_ipsec_set_tx_sa(hw, sa_idx, tsa.key, tsa.salt);
+
+		xs->xso.offload_handle = sa_idx + IXGBE_IPSEC_BASE_TX_INDEX;
+
+		ipsec->num_tx_sa++;
+	}
+
+	/* enable the engine if not already warmed up */
+	if (!(adapter->flags2 & IXGBE_FLAG2_IPSEC_ENABLED)) {
+		ixgbe_ipsec_start_engine(adapter);
+		adapter->flags2 |= IXGBE_FLAG2_IPSEC_ENABLED;
+	}
+
+	return 0;
+}
+
+/**
+ * ixgbe_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
+{
+	struct net_device *dev = xs->xso.dev;
+	struct ixgbe_adapter *adapter = netdev_priv(dev);
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 zerobuf[4] = {0, 0, 0, 0};
+	u16 sa_idx;
+
+	if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
+		struct rx_sa *rsa;
+		u8 ipi;
+
+		sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX;
+		rsa = &ipsec->rx_tbl[sa_idx];
+
+		if (!rsa->used) {
+			netdev_err(dev, "Invalid Rx SA selected sa_idx=%d offload_handle=%lu\n",
+				   sa_idx, xs->xso.offload_handle);
+			return;
+		}
+
+		ixgbe_ipsec_set_rx_sa(hw, sa_idx, 0, zerobuf, 0, 0, 0);
+		hash_del_rcu(&rsa->hlist);
+
+		/* if the IP table entry is referenced by only this SA,
+		 * i.e. ref_cnt is only 1, clear the IP table entry as well
+		 */
+		ipi = rsa->iptbl_ind;
+		if (ipsec->ip_tbl[ipi].ref_cnt > 0) {
+			ipsec->ip_tbl[ipi].ref_cnt--;
+
+			if (!ipsec->ip_tbl[ipi].ref_cnt) {
+				memset(&ipsec->ip_tbl[ipi], 0,
+				       sizeof(struct rx_ip_sa));
+				ixgbe_ipsec_set_rx_ip(hw, ipi, zerobuf);
+			}
+		}
+
+		memset(rsa, 0, sizeof(struct rx_sa));
+		ipsec->num_rx_sa--;
+	} else {
+		sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;
+
+		if (!ipsec->tx_tbl[sa_idx].used) {
+			netdev_err(dev, "Invalid Tx SA selected sa_idx=%d offload_handle=%lu\n",
+				   sa_idx, xs->xso.offload_handle);
+			return;
+		}
+
+		ixgbe_ipsec_set_tx_sa(hw, sa_idx, zerobuf, 0);
+		memset(&ipsec->tx_tbl[sa_idx], 0, sizeof(struct tx_sa));
+		ipsec->num_tx_sa--;
+	}
+
+	/* if there are no SAs left, stop the engine to save energy */
+	if (ipsec->num_rx_sa == 0 && ipsec->num_tx_sa == 0) {
+		adapter->flags2 &= ~IXGBE_FLAG2_IPSEC_ENABLED;
+		ixgbe_ipsec_stop_engine(adapter);
+	}
+}
+
+static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
+	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
+	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
+};
+
+/**
  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
  * @adapter: board private structure
  **/
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
 {
-	ixgbe_ipsec_clear_hw_tables(adapter);
+	struct ixgbe_ipsec *ipsec;
+	size_t size;
+
+	ipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL);
+	if (!ipsec)
+		goto err1;
+	hash_init(ipsec->rx_sa_list);
+
+	size = sizeof(struct rx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;
+	ipsec->rx_tbl = kzalloc(size, GFP_KERNEL);
+	if (!ipsec->rx_tbl)
+		goto err2;
+
+	size = sizeof(struct tx_sa) * IXGBE_IPSEC_MAX_SA_COUNT;
+	ipsec->tx_tbl = kzalloc(size, GFP_KERNEL);
+	if (!ipsec->tx_tbl)
+		goto err2;
+
+	size = sizeof(struct rx_ip_sa) * IXGBE_IPSEC_MAX_RX_IP_COUNT;
+	ipsec->ip_tbl = kzalloc(size, GFP_KERNEL);
+	if (!ipsec->ip_tbl)
+		goto err2;
+
+	ipsec->num_rx_sa = 0;
+	ipsec->num_tx_sa = 0;
+
+	adapter->ipsec = ipsec;
 	ixgbe_ipsec_stop_engine(adapter);
+	ixgbe_ipsec_clear_hw_tables(adapter);
+
+	return;
+
+err2:
+	kfree(ipsec->ip_tbl);
+	kfree(ipsec->rx_tbl);
+	kfree(ipsec->tx_tbl);
+err1:
+	kfree(adapter->ipsec);
+	netdev_err(adapter->netdev, "Unable to allocate memory for SA tables");
+}
+
+/**
+ * ixgbe_stop_ipsec_offload - tear down the ipsec offload
+ * @adapter: board private structure
+ **/
+void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+
+	adapter->ipsec = NULL;
+	if (ipsec) {
+		kfree(ipsec->ip_tbl);
+		kfree(ipsec->rx_tbl);
+		kfree(ipsec->tx_tbl);
+		kfree(ipsec);
+	}
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 51fb3cf..2b3da0c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -10565,6 +10565,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
 	if (netdev->reg_state == NETREG_REGISTERED)
 		unregister_netdev(netdev);
 
+	ixgbe_stop_ipsec_offload(adapter);
 	ixgbe_clear_interrupt_scheme(adapter);
 
 	ixgbe_release_hw_control(adapter);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 06/10] ixgbe: restore offloaded SAs after a reset
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

On a chip reset most of the table contents are lost, so must be
restored.  This scans the driver's ipsec tables and restores both
the filled and empty table slots to their pre-reset values.

v2: during restore, clean the tables before restarting

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 41 ++++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  1 +
 3 files changed, 44 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 8f41508..af690c2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1010,8 +1010,10 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 #ifdef CONFIG_XFRM_OFFLOAD
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
 void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);
+void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
+static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 96971ce..9cf120d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -299,6 +299,47 @@ static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
 }
 
 /**
+ * ixgbe_ipsec_restore - restore the ipsec HW settings after a reset
+ * @adapter: board private structure
+ **/
+void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
+
+	if (!(adapter->flags2 & IXGBE_FLAG2_IPSEC_ENABLED))
+		return;
+
+	/* clean up and restart the engine */
+	ixgbe_ipsec_stop_engine(adapter);
+	ixgbe_ipsec_clear_hw_tables(adapter);
+	ixgbe_ipsec_start_engine(adapter);
+
+	/* reload the IP addrs */
+	for (i = 0; i < IXGBE_IPSEC_MAX_RX_IP_COUNT; i++) {
+		struct rx_ip_sa *ipsa = &ipsec->ip_tbl[i];
+
+		if (ipsa->used)
+			ixgbe_ipsec_set_rx_ip(hw, i, ipsa->ipaddr);
+	}
+
+	/* reload the Rx and Tx keys */
+	for (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {
+		struct rx_sa *rsa = &ipsec->rx_tbl[i];
+		struct tx_sa *tsa = &ipsec->tx_tbl[i];
+
+		if (rsa->used)
+			ixgbe_ipsec_set_rx_sa(hw, i, rsa->xs->id.spi,
+					      rsa->key, rsa->salt,
+					      rsa->mode, rsa->iptbl_ind);
+
+		if (tsa->used)
+			ixgbe_ipsec_set_tx_sa(hw, i, tsa->key, tsa->salt);
+	}
+}
+
+/**
  * ixgbe_ipsec_find_empty_idx - find the first unused security parameter index
  * @ipsec: pointer to ipsec struct
  * @rxtable: true if we need to look in the Rx table
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 2b3da0c..04e8b26 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5347,6 +5347,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
 
 	ixgbe_set_rx_mode(adapter->netdev);
 	ixgbe_restore_vlan(adapter);
+	ixgbe_ipsec_restore(adapter);
 
 	switch (hw->mac.type) {
 	case ixgbe_mac_82599EB:
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 06/10] ixgbe: restore offloaded SAs after a reset
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

On a chip reset most of the table contents are lost, so must be
restored.  This scans the driver's ipsec tables and restores both
the filled and empty table slots to their pre-reset values.

v2: during restore, clean the tables before restarting

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 41 ++++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  1 +
 3 files changed, 44 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 8f41508..af690c2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1010,8 +1010,10 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 #ifdef CONFIG_XFRM_OFFLOAD
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
 void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);
+void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
+static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 96971ce..9cf120d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -299,6 +299,47 @@ static void ixgbe_ipsec_start_engine(struct ixgbe_adapter *adapter)
 }
 
 /**
+ * ixgbe_ipsec_restore - restore the ipsec HW settings after a reset
+ * @adapter: board private structure
+ **/
+void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct ixgbe_hw *hw = &adapter->hw;
+	int i;
+
+	if (!(adapter->flags2 & IXGBE_FLAG2_IPSEC_ENABLED))
+		return;
+
+	/* clean up and restart the engine */
+	ixgbe_ipsec_stop_engine(adapter);
+	ixgbe_ipsec_clear_hw_tables(adapter);
+	ixgbe_ipsec_start_engine(adapter);
+
+	/* reload the IP addrs */
+	for (i = 0; i < IXGBE_IPSEC_MAX_RX_IP_COUNT; i++) {
+		struct rx_ip_sa *ipsa = &ipsec->ip_tbl[i];
+
+		if (ipsa->used)
+			ixgbe_ipsec_set_rx_ip(hw, i, ipsa->ipaddr);
+	}
+
+	/* reload the Rx and Tx keys */
+	for (i = 0; i < IXGBE_IPSEC_MAX_SA_COUNT; i++) {
+		struct rx_sa *rsa = &ipsec->rx_tbl[i];
+		struct tx_sa *tsa = &ipsec->tx_tbl[i];
+
+		if (rsa->used)
+			ixgbe_ipsec_set_rx_sa(hw, i, rsa->xs->id.spi,
+					      rsa->key, rsa->salt,
+					      rsa->mode, rsa->iptbl_ind);
+
+		if (tsa->used)
+			ixgbe_ipsec_set_tx_sa(hw, i, tsa->key, tsa->salt);
+	}
+}
+
+/**
  * ixgbe_ipsec_find_empty_idx - find the first unused security parameter index
  * @ipsec: pointer to ipsec struct
  * @rxtable: true if we need to look in the Rx table
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 2b3da0c..04e8b26 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5347,6 +5347,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
 
 	ixgbe_set_rx_mode(adapter->netdev);
 	ixgbe_restore_vlan(adapter);
+	ixgbe_ipsec_restore(adapter);
 
 	switch (hw->mac.type) {
 	case ixgbe_mac_82599EB:
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 07/10] ixgbe: process the Rx ipsec offload
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-19 23:59   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

If the chip sees and decrypts an ipsec offload, set up the skb
sp pointer with the ralated SA info.  Since the chip is rude
enough to keep to itself the table index it used for the
decryption, we have to do our own table lookup, using the
hash for speed.

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  6 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 89 ++++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  3 +
 3 files changed, 98 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index af690c2..a094b23 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1011,9 +1011,15 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
 void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);
 void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
+void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
+		    union ixgbe_adv_rx_desc *rx_desc,
+		    struct sk_buff *skb);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
+static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
+				  union ixgbe_adv_rx_desc *rx_desc,
+				  struct sk_buff *skb) { };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 9cf120d..a9b8f5c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -374,6 +374,35 @@ static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable)
 }
 
 /**
+ * ixgbe_ipsec_find_rx_state - find the state that matches
+ * @ipsec: pointer to ipsec struct
+ * @daddr: inbound address to match
+ * @proto: protocol to match
+ * @spi: SPI to match
+ *
+ * Returns a pointer to the matching SA state information
+ **/
+static struct xfrm_state *ixgbe_ipsec_find_rx_state(struct ixgbe_ipsec *ipsec,
+						    __be32 daddr, u8 proto,
+						    __be32 spi)
+{
+	struct rx_sa *rsa;
+	struct xfrm_state *ret = NULL;
+
+	rcu_read_lock();
+	hash_for_each_possible_rcu(ipsec->rx_sa_list, rsa, hlist, spi)
+		if (spi == rsa->xs->id.spi &&
+		    daddr == rsa->xs->id.daddr.a4 &&
+		    proto == rsa->xs->id.proto) {
+			ret = rsa->xs;
+			xfrm_state_hold(ret);
+			break;
+		}
+	rcu_read_unlock();
+	return ret;
+}
+
+/**
  * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol
  * @xs: pointer to xfrm_state struct
  * @mykey: pointer to key array to populate
@@ -672,6 +701,66 @@ static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
 };
 
 /**
+ * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
+ * @rx_ring: receiving ring
+ * @rx_desc: receive data descriptor
+ * @skb: current data packet
+ *
+ * Determine if there was an ipsec encapsulation noticed, and if so set up
+ * the resulting status for later in the receive stack.
+ **/
+void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
+		    union ixgbe_adv_rx_desc *rx_desc,
+		    struct sk_buff *skb)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(rx_ring->netdev);
+	u16 pkt_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info);
+	u16 ipsec_pkt_types = IXGBE_RXDADV_PKTTYPE_IPSEC_AH |
+				IXGBE_RXDADV_PKTTYPE_IPSEC_ESP;
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct xfrm_offload *xo = NULL;
+	struct xfrm_state *xs = NULL;
+	struct iphdr *iph;
+	u8 *c_hdr;
+	__be32 spi;
+	u8 proto;
+
+	/* we can assume no vlan header in the way, b/c the
+	 * hw won't recognize the IPsec packet and anyway the
+	 * currently vlan device doesn't support xfrm offload.
+	 */
+	/* TODO: not supporting IPv6 yet */
+	iph = (struct iphdr *)(skb->data + ETH_HLEN);
+	c_hdr = (u8 *)iph + iph->ihl * 4;
+	switch (pkt_info & ipsec_pkt_types) {
+	case IXGBE_RXDADV_PKTTYPE_IPSEC_AH:
+		spi = ((struct ip_auth_hdr *)c_hdr)->spi;
+		proto = IPPROTO_AH;
+		break;
+	case IXGBE_RXDADV_PKTTYPE_IPSEC_ESP:
+		spi = ((struct ip_esp_hdr *)c_hdr)->spi;
+		proto = IPPROTO_ESP;
+		break;
+	default:
+		return;
+	}
+
+	xs = ixgbe_ipsec_find_rx_state(ipsec, iph->daddr, proto, spi);
+	if (unlikely(!xs))
+		return;
+
+	skb->sp = secpath_dup(skb->sp);
+	if (unlikely(!skb->sp))
+		return;
+
+	skb->sp->xvec[skb->sp->len++] = xs;
+	skb->sp->olen++;
+	xo = xfrm_offload(skb);
+	xo->flags = CRYPTO_DONE;
+	xo->status = CRYPTO_SUCCESS;
+}
+
+/**
  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
  * @adapter: board private structure
  **/
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 04e8b26..0ee1e5e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1755,6 +1755,9 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
 
 	skb_record_rx_queue(skb, rx_ring->queue_index);
 
+	if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_SECP))
+		ixgbe_ipsec_rx(rx_ring, rx_desc, skb);
+
 	skb->protocol = eth_type_trans(skb, dev);
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 07/10] ixgbe: process the Rx ipsec offload
@ 2017-12-19 23:59   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-19 23:59 UTC (permalink / raw)
  To: intel-wired-lan

If the chip sees and decrypts an ipsec offload, set up the skb
sp pointer with the ralated SA info.  Since the chip is rude
enough to keep to itself the table index it used for the
decryption, we have to do our own table lookup, using the
hash for speed.

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  6 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 89 ++++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  3 +
 3 files changed, 98 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index af690c2..a094b23 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -1011,9 +1011,15 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter);
 void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter);
 void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
+void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
+		    union ixgbe_adv_rx_desc *rx_desc,
+		    struct sk_buff *skb);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
+static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
+				  union ixgbe_adv_rx_desc *rx_desc,
+				  struct sk_buff *skb) { };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 9cf120d..a9b8f5c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -374,6 +374,35 @@ static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable)
 }
 
 /**
+ * ixgbe_ipsec_find_rx_state - find the state that matches
+ * @ipsec: pointer to ipsec struct
+ * @daddr: inbound address to match
+ * @proto: protocol to match
+ * @spi: SPI to match
+ *
+ * Returns a pointer to the matching SA state information
+ **/
+static struct xfrm_state *ixgbe_ipsec_find_rx_state(struct ixgbe_ipsec *ipsec,
+						    __be32 daddr, u8 proto,
+						    __be32 spi)
+{
+	struct rx_sa *rsa;
+	struct xfrm_state *ret = NULL;
+
+	rcu_read_lock();
+	hash_for_each_possible_rcu(ipsec->rx_sa_list, rsa, hlist, spi)
+		if (spi == rsa->xs->id.spi &&
+		    daddr == rsa->xs->id.daddr.a4 &&
+		    proto == rsa->xs->id.proto) {
+			ret = rsa->xs;
+			xfrm_state_hold(ret);
+			break;
+		}
+	rcu_read_unlock();
+	return ret;
+}
+
+/**
  * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol
  * @xs: pointer to xfrm_state struct
  * @mykey: pointer to key array to populate
@@ -672,6 +701,66 @@ static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
 };
 
 /**
+ * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
+ * @rx_ring: receiving ring
+ * @rx_desc: receive data descriptor
+ * @skb: current data packet
+ *
+ * Determine if there was an ipsec encapsulation noticed, and if so set up
+ * the resulting status for later in the receive stack.
+ **/
+void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
+		    union ixgbe_adv_rx_desc *rx_desc,
+		    struct sk_buff *skb)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(rx_ring->netdev);
+	u16 pkt_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info);
+	u16 ipsec_pkt_types = IXGBE_RXDADV_PKTTYPE_IPSEC_AH |
+				IXGBE_RXDADV_PKTTYPE_IPSEC_ESP;
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct xfrm_offload *xo = NULL;
+	struct xfrm_state *xs = NULL;
+	struct iphdr *iph;
+	u8 *c_hdr;
+	__be32 spi;
+	u8 proto;
+
+	/* we can assume no vlan header in the way, b/c the
+	 * hw won't recognize the IPsec packet and anyway the
+	 * currently vlan device doesn't support xfrm offload.
+	 */
+	/* TODO: not supporting IPv6 yet */
+	iph = (struct iphdr *)(skb->data + ETH_HLEN);
+	c_hdr = (u8 *)iph + iph->ihl * 4;
+	switch (pkt_info & ipsec_pkt_types) {
+	case IXGBE_RXDADV_PKTTYPE_IPSEC_AH:
+		spi = ((struct ip_auth_hdr *)c_hdr)->spi;
+		proto = IPPROTO_AH;
+		break;
+	case IXGBE_RXDADV_PKTTYPE_IPSEC_ESP:
+		spi = ((struct ip_esp_hdr *)c_hdr)->spi;
+		proto = IPPROTO_ESP;
+		break;
+	default:
+		return;
+	}
+
+	xs = ixgbe_ipsec_find_rx_state(ipsec, iph->daddr, proto, spi);
+	if (unlikely(!xs))
+		return;
+
+	skb->sp = secpath_dup(skb->sp);
+	if (unlikely(!skb->sp))
+		return;
+
+	skb->sp->xvec[skb->sp->len++] = xs;
+	skb->sp->olen++;
+	xo = xfrm_offload(skb);
+	xo->flags = CRYPTO_DONE;
+	xo->status = CRYPTO_SUCCESS;
+}
+
+/**
  * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation
  * @adapter: board private structure
  **/
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 04e8b26..0ee1e5e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1755,6 +1755,9 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
 
 	skb_record_rx_queue(skb, rx_ring->queue_index);
 
+	if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_SECP))
+		ixgbe_ipsec_rx(rx_ring, rx_desc, skb);
+
 	skb->protocol = eth_type_trans(skb, dev);
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-20  0:00   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-20  0:00 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

If the skb has a security association referenced in the skb, then
set up the Tx descriptor with the ipsec offload bits.  While we're
here, we fix an oddly named field in the context descriptor struct.

v3: added ifdef CONFIG_XFRM_OFFLOAD check around call to ixgbe_ipsec_tx()

v2: use ihl != 5
    move the ixgbe_ipsec_tx() call to near the call to ixgbe_tso()
    drop the ipsec packet if the tx offload setup fails
    simplify the ixgbe_ipsec_tx() parameters by using 'first'
    leave out the ixgbe_tso() changes since we don't support TSO
       with ipsec yet.

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       | 10 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 79 ++++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c   |  4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 26 +++++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |  2 +-
 5 files changed, 112 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index a094b23..3d2b7bf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -171,10 +171,11 @@ enum ixgbe_tx_flags {
 	IXGBE_TX_FLAGS_CC	= 0x08,
 	IXGBE_TX_FLAGS_IPV4	= 0x10,
 	IXGBE_TX_FLAGS_CSUM	= 0x20,
+	IXGBE_TX_FLAGS_IPSEC	= 0x40,
 
 	/* software defined flags */
-	IXGBE_TX_FLAGS_SW_VLAN	= 0x40,
-	IXGBE_TX_FLAGS_FCOE	= 0x80,
+	IXGBE_TX_FLAGS_SW_VLAN	= 0x80,
+	IXGBE_TX_FLAGS_FCOE	= 0x100,
 };
 
 /* VLAN info */
@@ -1014,6 +1015,8 @@ void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
 void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
 		    union ixgbe_adv_rx_desc *rx_desc,
 		    struct sk_buff *skb);
+int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring, struct ixgbe_tx_buffer *first,
+		   struct ixgbe_ipsec_tx_data *itd);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
@@ -1021,5 +1024,8 @@ static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
 				  union ixgbe_adv_rx_desc *rx_desc,
 				  struct sk_buff *skb) { };
+static inline int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
+				 struct ixgbe_tx_buffer *first,
+				 struct ixgbe_ipsec_tx_data *itd) { return 0; };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index a9b8f5c..c2fd2ac 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -695,12 +695,91 @@ static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
 	}
 }
 
+/**
+ * ixgbe_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+	if (xs->props.family == AF_INET) {
+		/* Offload with IPv4 options is not supported yet */
+		if (ip_hdr(skb)->ihl != 5)
+			return false;
+	} else {
+		/* Offload with IPv6 extension headers is not support yet */
+		if (ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr))
+			return false;
+	}
+
+	return true;
+}
+
 static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
 	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
 	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
+	.xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
 };
 
 /**
+ * ixgbe_ipsec_tx - setup Tx flags for ipsec offload
+ * @tx_ring: outgoing context
+ * @first: current data packet
+ * @itd: ipsec Tx data for later use in building context descriptor
+ **/
+int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
+		   struct ixgbe_tx_buffer *first,
+		   struct ixgbe_ipsec_tx_data *itd)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct xfrm_state *xs;
+	struct tx_sa *tsa;
+
+	if (!first->skb->sp->len) {
+		netdev_err(tx_ring->netdev, "%s: no xfrm state len = %d\n",
+			   __func__, first->skb->sp->len);
+		return 0;
+	}
+
+	xs = xfrm_input_state(first->skb);
+	if (!xs) {
+		netdev_err(tx_ring->netdev, "%s: no xfrm_input_state() xs = %p\n",
+			   __func__, xs);
+		return 0;
+	}
+
+	itd->sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;
+	if (itd->sa_idx > IXGBE_IPSEC_MAX_SA_COUNT) {
+		netdev_err(tx_ring->netdev, "%s: bad sa_idx=%d handle=%lu\n",
+			   __func__, itd->sa_idx, xs->xso.offload_handle);
+		return 0;
+	}
+
+	tsa = &ipsec->tx_tbl[itd->sa_idx];
+	if (!tsa->used) {
+		netdev_err(tx_ring->netdev, "%s: unused sa_idx=%d\n",
+			   __func__, itd->sa_idx);
+		return 0;
+	}
+
+	first->tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CC;
+
+	itd->flags = 0;
+	if (xs->id.proto == IPPROTO_ESP) {
+		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
+			      IXGBE_ADVTXD_TUCMD_L4T_TCP;
+		if (first->protocol == htons(ETH_P_IP))
+			itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;
+		itd->trailer_len = xs->props.trailer_len;
+	}
+	if (tsa->encrypt)
+		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
+
+	return 1;
+}
+
+/**
  * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
  * @rx_ring: receiving ring
  * @rx_desc: receive data descriptor
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
index f1bfae0..d7875b3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
@@ -1261,7 +1261,7 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
 }
 
 void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
-		       u32 fcoe_sof_eof, u32 type_tucmd, u32 mss_l4len_idx)
+		       u32 fceof_saidx, u32 type_tucmd, u32 mss_l4len_idx)
 {
 	struct ixgbe_adv_tx_context_desc *context_desc;
 	u16 i = tx_ring->next_to_use;
@@ -1275,7 +1275,7 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
 	type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
 
 	context_desc->vlan_macip_lens	= cpu_to_le32(vlan_macip_lens);
-	context_desc->seqnum_seed	= cpu_to_le32(fcoe_sof_eof);
+	context_desc->fceof_saidx	= cpu_to_le32(fceof_saidx);
 	context_desc->type_tucmd_mlhl	= cpu_to_le32(type_tucmd);
 	context_desc->mss_l4len_idx	= cpu_to_le32(mss_l4len_idx);
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0ee1e5e..6b9a9b2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7756,10 +7756,12 @@ static inline bool ixgbe_ipv6_csum_is_sctp(struct sk_buff *skb)
 }
 
 static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
-			  struct ixgbe_tx_buffer *first)
+			  struct ixgbe_tx_buffer *first,
+			  struct ixgbe_ipsec_tx_data *itd)
 {
 	struct sk_buff *skb = first->skb;
 	u32 vlan_macip_lens = 0;
+	u32 fceof_saidx = 0;
 	u32 type_tucmd = 0;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
@@ -7800,7 +7802,12 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
 	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
 	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
 
-	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, 0);
+	if (first->tx_flags & IXGBE_TX_FLAGS_IPSEC) {
+		fceof_saidx |= itd->sa_idx;
+		type_tucmd |= itd->flags | itd->trailer_len;
+	}
+
+	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fceof_saidx, type_tucmd, 0);
 }
 
 #define IXGBE_SET_FLAG(_input, _flag, _result) \
@@ -7843,11 +7850,16 @@ static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc,
 					IXGBE_TX_FLAGS_CSUM,
 					IXGBE_ADVTXD_POPTS_TXSM);
 
-	/* enble IPv4 checksum for TSO */
+	/* enable IPv4 checksum for TSO */
 	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
 					IXGBE_TX_FLAGS_IPV4,
 					IXGBE_ADVTXD_POPTS_IXSM);
 
+	/* enable IPsec */
+	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
+					IXGBE_TX_FLAGS_IPSEC,
+					IXGBE_ADVTXD_POPTS_IPSEC);
+
 	/*
 	 * Check Context must be set if Tx switch is enabled, which it
 	 * always is for case where virtual functions are running
@@ -8306,6 +8318,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 	u32 tx_flags = 0;
 	unsigned short f;
 	u16 count = TXD_USE_COUNT(skb_headlen(skb));
+	struct ixgbe_ipsec_tx_data ipsec_tx = { 0 };
 	__be16 protocol = skb->protocol;
 	u8 hdr_len = 0;
 
@@ -8410,11 +8423,16 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 	}
 
 #endif /* IXGBE_FCOE */
+
+#ifdef CONFIG_XFRM_OFFLOAD
+	if (skb->sp && !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
+		goto out_drop;
+#endif
 	tso = ixgbe_tso(tx_ring, first, &hdr_len);
 	if (tso < 0)
 		goto out_drop;
 	else if (!tso)
-		ixgbe_tx_csum(tx_ring, first);
+		ixgbe_tx_csum(tx_ring, first, &ipsec_tx);
 
 	/* add the ATR filter if ATR is on */
 	if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 3df0763..0ac725fa 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2856,7 +2856,7 @@ union ixgbe_adv_rx_desc {
 /* Context descriptors */
 struct ixgbe_adv_tx_context_desc {
 	__le32 vlan_macip_lens;
-	__le32 seqnum_seed;
+	__le32 fceof_saidx;
 	__le32 type_tucmd_mlhl;
 	__le32 mss_l4len_idx;
 };
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
@ 2017-12-20  0:00   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-20  0:00 UTC (permalink / raw)
  To: intel-wired-lan

If the skb has a security association referenced in the skb, then
set up the Tx descriptor with the ipsec offload bits.  While we're
here, we fix an oddly named field in the context descriptor struct.

v3: added ifdef CONFIG_XFRM_OFFLOAD check around call to ixgbe_ipsec_tx()

v2: use ihl != 5
    move the ixgbe_ipsec_tx() call to near the call to ixgbe_tso()
    drop the ipsec packet if the tx offload setup fails
    simplify the ixgbe_ipsec_tx() parameters by using 'first'
    leave out the ixgbe_tso() changes since we don't support TSO
       with ipsec yet.

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h       | 10 +++-
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 79 ++++++++++++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c   |  4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 26 +++++++--
 drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |  2 +-
 5 files changed, 112 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index a094b23..3d2b7bf 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -171,10 +171,11 @@ enum ixgbe_tx_flags {
 	IXGBE_TX_FLAGS_CC	= 0x08,
 	IXGBE_TX_FLAGS_IPV4	= 0x10,
 	IXGBE_TX_FLAGS_CSUM	= 0x20,
+	IXGBE_TX_FLAGS_IPSEC	= 0x40,
 
 	/* software defined flags */
-	IXGBE_TX_FLAGS_SW_VLAN	= 0x40,
-	IXGBE_TX_FLAGS_FCOE	= 0x80,
+	IXGBE_TX_FLAGS_SW_VLAN	= 0x80,
+	IXGBE_TX_FLAGS_FCOE	= 0x100,
 };
 
 /* VLAN info */
@@ -1014,6 +1015,8 @@ void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
 void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
 		    union ixgbe_adv_rx_desc *rx_desc,
 		    struct sk_buff *skb);
+int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring, struct ixgbe_tx_buffer *first,
+		   struct ixgbe_ipsec_tx_data *itd);
 #else
 static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
@@ -1021,5 +1024,8 @@ static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
 static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
 				  union ixgbe_adv_rx_desc *rx_desc,
 				  struct sk_buff *skb) { };
+static inline int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
+				 struct ixgbe_tx_buffer *first,
+				 struct ixgbe_ipsec_tx_data *itd) { return 0; };
 #endif /* CONFIG_XFRM_OFFLOAD */
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index a9b8f5c..c2fd2ac 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -695,12 +695,91 @@ static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
 	}
 }
 
+/**
+ * ixgbe_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+	if (xs->props.family == AF_INET) {
+		/* Offload with IPv4 options is not supported yet */
+		if (ip_hdr(skb)->ihl != 5)
+			return false;
+	} else {
+		/* Offload with IPv6 extension headers is not support yet */
+		if (ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr))
+			return false;
+	}
+
+	return true;
+}
+
 static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
 	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
 	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
+	.xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
 };
 
 /**
+ * ixgbe_ipsec_tx - setup Tx flags for ipsec offload
+ * @tx_ring: outgoing context
+ * @first: current data packet
+ * @itd: ipsec Tx data for later use in building context descriptor
+ **/
+int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
+		   struct ixgbe_tx_buffer *first,
+		   struct ixgbe_ipsec_tx_data *itd)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
+	struct ixgbe_ipsec *ipsec = adapter->ipsec;
+	struct xfrm_state *xs;
+	struct tx_sa *tsa;
+
+	if (!first->skb->sp->len) {
+		netdev_err(tx_ring->netdev, "%s: no xfrm state len = %d\n",
+			   __func__, first->skb->sp->len);
+		return 0;
+	}
+
+	xs = xfrm_input_state(first->skb);
+	if (!xs) {
+		netdev_err(tx_ring->netdev, "%s: no xfrm_input_state() xs = %p\n",
+			   __func__, xs);
+		return 0;
+	}
+
+	itd->sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;
+	if (itd->sa_idx > IXGBE_IPSEC_MAX_SA_COUNT) {
+		netdev_err(tx_ring->netdev, "%s: bad sa_idx=%d handle=%lu\n",
+			   __func__, itd->sa_idx, xs->xso.offload_handle);
+		return 0;
+	}
+
+	tsa = &ipsec->tx_tbl[itd->sa_idx];
+	if (!tsa->used) {
+		netdev_err(tx_ring->netdev, "%s: unused sa_idx=%d\n",
+			   __func__, itd->sa_idx);
+		return 0;
+	}
+
+	first->tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CC;
+
+	itd->flags = 0;
+	if (xs->id.proto == IPPROTO_ESP) {
+		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
+			      IXGBE_ADVTXD_TUCMD_L4T_TCP;
+		if (first->protocol == htons(ETH_P_IP))
+			itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;
+		itd->trailer_len = xs->props.trailer_len;
+	}
+	if (tsa->encrypt)
+		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
+
+	return 1;
+}
+
+/**
  * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
  * @rx_ring: receiving ring
  * @rx_desc: receive data descriptor
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
index f1bfae0..d7875b3 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
@@ -1261,7 +1261,7 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
 }
 
 void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
-		       u32 fcoe_sof_eof, u32 type_tucmd, u32 mss_l4len_idx)
+		       u32 fceof_saidx, u32 type_tucmd, u32 mss_l4len_idx)
 {
 	struct ixgbe_adv_tx_context_desc *context_desc;
 	u16 i = tx_ring->next_to_use;
@@ -1275,7 +1275,7 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
 	type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
 
 	context_desc->vlan_macip_lens	= cpu_to_le32(vlan_macip_lens);
-	context_desc->seqnum_seed	= cpu_to_le32(fcoe_sof_eof);
+	context_desc->fceof_saidx	= cpu_to_le32(fceof_saidx);
 	context_desc->type_tucmd_mlhl	= cpu_to_le32(type_tucmd);
 	context_desc->mss_l4len_idx	= cpu_to_le32(mss_l4len_idx);
 }
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 0ee1e5e..6b9a9b2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -7756,10 +7756,12 @@ static inline bool ixgbe_ipv6_csum_is_sctp(struct sk_buff *skb)
 }
 
 static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
-			  struct ixgbe_tx_buffer *first)
+			  struct ixgbe_tx_buffer *first,
+			  struct ixgbe_ipsec_tx_data *itd)
 {
 	struct sk_buff *skb = first->skb;
 	u32 vlan_macip_lens = 0;
+	u32 fceof_saidx = 0;
 	u32 type_tucmd = 0;
 
 	if (skb->ip_summed != CHECKSUM_PARTIAL) {
@@ -7800,7 +7802,12 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
 	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
 	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
 
-	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, 0);
+	if (first->tx_flags & IXGBE_TX_FLAGS_IPSEC) {
+		fceof_saidx |= itd->sa_idx;
+		type_tucmd |= itd->flags | itd->trailer_len;
+	}
+
+	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fceof_saidx, type_tucmd, 0);
 }
 
 #define IXGBE_SET_FLAG(_input, _flag, _result) \
@@ -7843,11 +7850,16 @@ static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc,
 					IXGBE_TX_FLAGS_CSUM,
 					IXGBE_ADVTXD_POPTS_TXSM);
 
-	/* enble IPv4 checksum for TSO */
+	/* enable IPv4 checksum for TSO */
 	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
 					IXGBE_TX_FLAGS_IPV4,
 					IXGBE_ADVTXD_POPTS_IXSM);
 
+	/* enable IPsec */
+	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
+					IXGBE_TX_FLAGS_IPSEC,
+					IXGBE_ADVTXD_POPTS_IPSEC);
+
 	/*
 	 * Check Context must be set if Tx switch is enabled, which it
 	 * always is for case where virtual functions are running
@@ -8306,6 +8318,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 	u32 tx_flags = 0;
 	unsigned short f;
 	u16 count = TXD_USE_COUNT(skb_headlen(skb));
+	struct ixgbe_ipsec_tx_data ipsec_tx = { 0 };
 	__be16 protocol = skb->protocol;
 	u8 hdr_len = 0;
 
@@ -8410,11 +8423,16 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 	}
 
 #endif /* IXGBE_FCOE */
+
+#ifdef CONFIG_XFRM_OFFLOAD
+	if (skb->sp && !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
+		goto out_drop;
+#endif
 	tso = ixgbe_tso(tx_ring, first, &hdr_len);
 	if (tso < 0)
 		goto out_drop;
 	else if (!tso)
-		ixgbe_tx_csum(tx_ring, first);
+		ixgbe_tx_csum(tx_ring, first, &ipsec_tx);
 
 	/* add the ATR filter if ATR is on */
 	if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 3df0763..0ac725fa 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2856,7 +2856,7 @@ union ixgbe_adv_rx_desc {
 /* Context descriptors */
 struct ixgbe_adv_tx_context_desc {
 	__le32 vlan_macip_lens;
-	__le32 seqnum_seed;
+	__le32 fceof_saidx;
 	__le32 type_tucmd_mlhl;
 	__le32 mss_l4len_idx;
 };
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 09/10] ixgbe: ipsec offload stats
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-20  0:00   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-20  0:00 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

Add a simple statistic to count the ipsec offloads.

v2: change per ring counter to adapter rx and tx counters
    move tx_ipsec count to the tx clean code

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         | 2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    | 5 ++++-
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 3d2b7bf..1dfe147 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -629,10 +629,12 @@ struct ixgbe_adapter {
 	int num_tx_queues;
 	u16 tx_itr_setting;
 	u16 tx_work_limit;
+	u64 tx_ipsec;
 
 	/* Rx fast path data */
 	int num_rx_queues;
 	u16 rx_itr_setting;
+	u64 rx_ipsec;
 
 	/* Port number used to identify VXLAN traffic */
 	__be16 vxlan_port;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index c3e7a81..bcf011e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -114,6 +114,8 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
 	{"tx_hwtstamp_timeouts", IXGBE_STAT(tx_hwtstamp_timeouts)},
 	{"tx_hwtstamp_skipped", IXGBE_STAT(tx_hwtstamp_skipped)},
 	{"rx_hwtstamp_cleared", IXGBE_STAT(rx_hwtstamp_cleared)},
+	{"tx_ipsec", IXGBE_STAT(tx_ipsec)},
+	{"rx_ipsec", IXGBE_STAT(rx_ipsec)},
 #ifdef IXGBE_FCOE
 	{"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)},
 	{"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)},
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index c2fd2ac..4b16466 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -837,6 +837,8 @@ void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
 	xo = xfrm_offload(skb);
 	xo->flags = CRYPTO_DONE;
 	xo->status = CRYPTO_SUCCESS;
+
+	adapter->rx_ipsec++;
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 6b9a9b2..8c88d32 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1173,7 +1173,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	struct ixgbe_adapter *adapter = q_vector->adapter;
 	struct ixgbe_tx_buffer *tx_buffer;
 	union ixgbe_adv_tx_desc *tx_desc;
-	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int total_bytes = 0, total_packets = 0, total_ipsec = 0;
 	unsigned int budget = q_vector->tx.work_limit;
 	unsigned int i = tx_ring->next_to_clean;
 
@@ -1204,6 +1204,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 		/* update the statistics for this packet */
 		total_bytes += tx_buffer->bytecount;
 		total_packets += tx_buffer->gso_segs;
+		if (tx_buffer->tx_flags & IXGBE_TX_FLAGS_IPSEC)
+			total_ipsec++;
 
 		/* free the skb */
 		if (ring_is_xdp(tx_ring))
@@ -1266,6 +1268,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	u64_stats_update_end(&tx_ring->syncp);
 	q_vector->tx.total_bytes += total_bytes;
 	q_vector->tx.total_packets += total_packets;
+	adapter->tx_ipsec += total_ipsec;
 
 	if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
 		/* schedule immediate reset if we believe we hung */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 09/10] ixgbe: ipsec offload stats
@ 2017-12-20  0:00   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-20  0:00 UTC (permalink / raw)
  To: intel-wired-lan

Add a simple statistic to count the ipsec offloads.

v2: change per ring counter to adapter rx and tx counters
    move tx_ipsec count to the tx clean code

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h         | 2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 2 ++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    | 5 ++++-
 4 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 3d2b7bf..1dfe147 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -629,10 +629,12 @@ struct ixgbe_adapter {
 	int num_tx_queues;
 	u16 tx_itr_setting;
 	u16 tx_work_limit;
+	u64 tx_ipsec;
 
 	/* Rx fast path data */
 	int num_rx_queues;
 	u16 rx_itr_setting;
+	u64 rx_ipsec;
 
 	/* Port number used to identify VXLAN traffic */
 	__be16 vxlan_port;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index c3e7a81..bcf011e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -114,6 +114,8 @@ static const struct ixgbe_stats ixgbe_gstrings_stats[] = {
 	{"tx_hwtstamp_timeouts", IXGBE_STAT(tx_hwtstamp_timeouts)},
 	{"tx_hwtstamp_skipped", IXGBE_STAT(tx_hwtstamp_skipped)},
 	{"rx_hwtstamp_cleared", IXGBE_STAT(rx_hwtstamp_cleared)},
+	{"tx_ipsec", IXGBE_STAT(tx_ipsec)},
+	{"rx_ipsec", IXGBE_STAT(rx_ipsec)},
 #ifdef IXGBE_FCOE
 	{"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)},
 	{"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)},
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index c2fd2ac..4b16466 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -837,6 +837,8 @@ void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
 	xo = xfrm_offload(skb);
 	xo->flags = CRYPTO_DONE;
 	xo->status = CRYPTO_SUCCESS;
+
+	adapter->rx_ipsec++;
 }
 
 /**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 6b9a9b2..8c88d32 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1173,7 +1173,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	struct ixgbe_adapter *adapter = q_vector->adapter;
 	struct ixgbe_tx_buffer *tx_buffer;
 	union ixgbe_adv_tx_desc *tx_desc;
-	unsigned int total_bytes = 0, total_packets = 0;
+	unsigned int total_bytes = 0, total_packets = 0, total_ipsec = 0;
 	unsigned int budget = q_vector->tx.work_limit;
 	unsigned int i = tx_ring->next_to_clean;
 
@@ -1204,6 +1204,8 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 		/* update the statistics for this packet */
 		total_bytes += tx_buffer->bytecount;
 		total_packets += tx_buffer->gso_segs;
+		if (tx_buffer->tx_flags & IXGBE_TX_FLAGS_IPSEC)
+			total_ipsec++;
 
 		/* free the skb */
 		if (ring_is_xdp(tx_ring))
@@ -1266,6 +1268,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	u64_stats_update_end(&tx_ring->syncp);
 	q_vector->tx.total_bytes += total_bytes;
 	q_vector->tx.total_packets += total_packets;
+	adapter->tx_ipsec += total_ipsec;
 
 	if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
 		/* schedule immediate reset if we believe we hung */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [PATCH v3 next-queue 10/10] ixgbe: register ipsec offload with the xfrm subsystem
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-20  0:00   ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-20  0:00 UTC (permalink / raw)
  To: intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

With all the support code in place we can now link in the ipsec
offload operations and set the ESP feature flag for the XFRM
subsystem to see.

v3: added ifdef CONFIG_XFRM_OFFLOAD in ixgbe_features_check

v2: added the xdo_dev_state_free callback to make XFRM happy
    changed use of NETIF_F_HW_CSUM_BIT to NETIF_F_HW_CSUM

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 17 +++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  6 ++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 4b16466..424dbf7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -715,10 +715,23 @@ static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
 	return true;
 }
 
+/**
+ * ixgbe_ipsec_free - called by xfrm garbage collections
+ * @xs: pointer to transformer state struct
+ *
+ * We don't have any garbage to collect, so we shouldn't bother
+ * implementing this function, but the XFRM code doesn't check for
+ * existence before calling the API callback.
+ **/
+static void ixgbe_ipsec_free(struct xfrm_state *xs)
+{
+}
+
 static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
 	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
 	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
 	.xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
+	.xdo_dev_state_free = ixgbe_ipsec_free,
 };
 
 /**
@@ -877,6 +890,10 @@ void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
 	ixgbe_ipsec_stop_engine(adapter);
 	ixgbe_ipsec_clear_hw_tables(adapter);
 
+	adapter->netdev->xfrmdev_ops = &ixgbe_xfrmdev_ops;
+	adapter->netdev->features |= NETIF_F_HW_ESP;
+	adapter->netdev->hw_enc_features |= NETIF_F_HW_ESP;
+
 	return;
 
 err2:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8c88d32..2f56309 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9798,6 +9798,12 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,
 	if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID))
 		features &= ~NETIF_F_TSO;
 
+#ifdef CONFIG_XFRM_OFFLOAD
+	/* IPsec offload doesn't get along well with others *yet* */
+	if (skb->sp)
+		features &= ~(NETIF_F_TSO | NETIF_F_HW_CSUM);
+#endif
+
 	return features;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 10/10] ixgbe: register ipsec offload with the xfrm subsystem
@ 2017-12-20  0:00   ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-20  0:00 UTC (permalink / raw)
  To: intel-wired-lan

With all the support code in place we can now link in the ipsec
offload operations and set the ESP feature flag for the XFRM
subsystem to see.

v3: added ifdef CONFIG_XFRM_OFFLOAD in ixgbe_features_check

v2: added the xdo_dev_state_free callback to make XFRM happy
    changed use of NETIF_F_HW_CSUM_BIT to NETIF_F_HW_CSUM

Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 17 +++++++++++++++++
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  6 ++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 4b16466..424dbf7 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -715,10 +715,23 @@ static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
 	return true;
 }
 
+/**
+ * ixgbe_ipsec_free - called by xfrm garbage collections
+ * @xs: pointer to transformer state struct
+ *
+ * We don't have any garbage to collect, so we shouldn't bother
+ * implementing this function, but the XFRM code doesn't check for
+ * existence before calling the API callback.
+ **/
+static void ixgbe_ipsec_free(struct xfrm_state *xs)
+{
+}
+
 static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
 	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
 	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
 	.xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
+	.xdo_dev_state_free = ixgbe_ipsec_free,
 };
 
 /**
@@ -877,6 +890,10 @@ void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
 	ixgbe_ipsec_stop_engine(adapter);
 	ixgbe_ipsec_clear_hw_tables(adapter);
 
+	adapter->netdev->xfrmdev_ops = &ixgbe_xfrmdev_ops;
+	adapter->netdev->features |= NETIF_F_HW_ESP;
+	adapter->netdev->hw_enc_features |= NETIF_F_HW_ESP;
+
 	return;
 
 err2:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8c88d32..2f56309 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -9798,6 +9798,12 @@ ixgbe_features_check(struct sk_buff *skb, struct net_device *dev,
 	if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID))
 		features &= ~NETIF_F_TSO;
 
+#ifdef CONFIG_XFRM_OFFLOAD
+	/* IPsec offload doesn't get along well with others *yet* */
+	if (skb->sp)
+		features &= ~(NETIF_F_TSO | NETIF_F_HW_CSUM);
+#endif
+
 	return features;
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-21  1:17     ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 50+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-12-21  1:17 UTC (permalink / raw)
  To: Shannon Nelson
  Cc: intel-wired-lan, jeffrey.t.kirsher, steffen.klassert,
	sowmini.varadhan, netdev

Hi,

On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
> +}
> +
> +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
> +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
> +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
> +};
> +

This struct is only declared if XFRM_OFFLOAD is selected. What is
selecting it for ixgbe driver?
mlx5 driver has an extra option for ipsec offload and it then does
'depends on XFRM_OFFLOAD'

  Marcelo

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
@ 2017-12-21  1:17     ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 50+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-12-21  1:17 UTC (permalink / raw)
  To: intel-wired-lan

Hi,

On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
> +}
> +
> +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
> +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
> +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
> +};
> +

This struct is only declared if XFRM_OFFLOAD is selected. What is
selecting it for ixgbe driver?
mlx5 driver has an extra option for ipsec offload and it then does
'depends on XFRM_OFFLOAD'

  Marcelo

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
  2017-12-21  1:17     ` [Intel-wired-lan] " Marcelo Ricardo Leitner
@ 2017-12-21  1:39       ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-21  1:39 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: intel-wired-lan, jeffrey.t.kirsher, steffen.klassert,
	sowmini.varadhan, netdev

On 12/20/2017 5:17 PM, Marcelo Ricardo Leitner wrote:
> Hi,
> 
> On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
>> +}
>> +
>> +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
>> +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
>> +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
>> +};
>> +
> 
> This struct is only declared if XFRM_OFFLOAD is selected. What is
> selecting it for ixgbe driver?
> mlx5 driver has an extra option for ipsec offload and it then does
> 'depends on XFRM_OFFLOAD'
> 
>    Marcelo
> 

I didn't bother putting a 'depends' item in the ixgbe's Kconfig entry, 
and I didn't create an extra CONFIG variable to enable ixgbe's support 
of the offload.  If CONFIG_XFRM_OFFLOAD is set, then ixgbe will support it.

sln

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
@ 2017-12-21  1:39       ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-21  1:39 UTC (permalink / raw)
  To: intel-wired-lan

On 12/20/2017 5:17 PM, Marcelo Ricardo Leitner wrote:
> Hi,
> 
> On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
>> +}
>> +
>> +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
>> +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
>> +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
>> +};
>> +
> 
> This struct is only declared if XFRM_OFFLOAD is selected. What is
> selecting it for ixgbe driver?
> mlx5 driver has an extra option for ipsec offload and it then does
> 'depends on XFRM_OFFLOAD'
> 
>    Marcelo
> 

I didn't bother putting a 'depends' item in the ixgbe's Kconfig entry, 
and I didn't create an extra CONFIG variable to enable ixgbe's support 
of the offload.  If CONFIG_XFRM_OFFLOAD is set, then ixgbe will support it.

sln


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
  2017-12-21  1:39       ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-21  2:21         ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 50+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-12-21  2:21 UTC (permalink / raw)
  To: Shannon Nelson
  Cc: intel-wired-lan, jeffrey.t.kirsher, steffen.klassert,
	sowmini.varadhan, netdev, saeedm, borisp, ilant

On Wed, Dec 20, 2017 at 05:39:13PM -0800, Shannon Nelson wrote:
> On 12/20/2017 5:17 PM, Marcelo Ricardo Leitner wrote:
> > Hi,
> > 
> > On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
> > > +}
> > > +
> > > +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
> > > +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
> > > +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
> > > +};
> > > +
> > 
> > This struct is only declared if XFRM_OFFLOAD is selected. What is
> > selecting it for ixgbe driver?
> > mlx5 driver has an extra option for ipsec offload and it then does
> > 'depends on XFRM_OFFLOAD'
> > 
> >    Marcelo
> > 
> 
> I didn't bother putting a 'depends' item in the ixgbe's Kconfig entry, and I
> didn't create an extra CONFIG variable to enable ixgbe's support of the
> offload.  If CONFIG_XFRM_OFFLOAD is set, then ixgbe will support it.

You handled it via Makefile, okay. Missed it on patch 2, my bad.

Anyhow, we probably could use some standard here across the vendors
here.  With this patchset, we have 2 drivers supporting it, and 2
different ways to configure it.

  Marcelo

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
@ 2017-12-21  2:21         ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 50+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-12-21  2:21 UTC (permalink / raw)
  To: intel-wired-lan

On Wed, Dec 20, 2017 at 05:39:13PM -0800, Shannon Nelson wrote:
> On 12/20/2017 5:17 PM, Marcelo Ricardo Leitner wrote:
> > Hi,
> > 
> > On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
> > > +}
> > > +
> > > +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
> > > +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
> > > +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
> > > +};
> > > +
> > 
> > This struct is only declared if XFRM_OFFLOAD is selected. What is
> > selecting it for ixgbe driver?
> > mlx5 driver has an extra option for ipsec offload and it then does
> > 'depends on XFRM_OFFLOAD'
> > 
> >    Marcelo
> > 
> 
> I didn't bother putting a 'depends' item in the ixgbe's Kconfig entry, and I
> didn't create an extra CONFIG variable to enable ixgbe's support of the
> offload.  If CONFIG_XFRM_OFFLOAD is set, then ixgbe will support it.

You handled it via Makefile, okay. Missed it on patch 2, my bad.

Anyhow, we probably could use some standard here across the vendors
here.  With this patchset, we have 2 drivers supporting it, and 2
different ways to configure it.

  Marcelo

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
  2017-12-21  2:21         ` [Intel-wired-lan] " Marcelo Ricardo Leitner
@ 2017-12-21  3:30           ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-21  3:30 UTC (permalink / raw)
  To: Marcelo Ricardo Leitner
  Cc: intel-wired-lan, jeffrey.t.kirsher, steffen.klassert,
	sowmini.varadhan, netdev, saeedm, borisp, ilant

On 12/20/2017 6:21 PM, Marcelo Ricardo Leitner wrote:
> On Wed, Dec 20, 2017 at 05:39:13PM -0800, Shannon Nelson wrote:
>> On 12/20/2017 5:17 PM, Marcelo Ricardo Leitner wrote:
>>> Hi,
>>>
>>> On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
>>>> +}
>>>> +
>>>> +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
>>>> +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
>>>> +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
>>>> +};
>>>> +
>>>
>>> This struct is only declared if XFRM_OFFLOAD is selected. What is
>>> selecting it for ixgbe driver?
>>> mlx5 driver has an extra option for ipsec offload and it then does
>>> 'depends on XFRM_OFFLOAD'
>>>
>>>     Marcelo
>>>
>>
>> I didn't bother putting a 'depends' item in the ixgbe's Kconfig entry, and I
>> didn't create an extra CONFIG variable to enable ixgbe's support of the
>> offload.  If CONFIG_XFRM_OFFLOAD is set, then ixgbe will support it.
> 
> You handled it via Makefile, okay. Missed it on patch 2, my bad.
> 
> Anyhow, we probably could use some standard here across the vendors
> here.  With this patchset, we have 2 drivers supporting it, and 2
> different ways to configure it.

I suspect that the mlx5 folks did an extra option as part of being the 
first to support the feature, and needing an easy way to toggle support 
while they were developing it without needing to rebuild the whole 
kernel.  Now that the feature has reached a certain level of "maturity", 
I think we can treat it like other features (e.g. CONFIG_PCI_IOV, 
CONFIG_FCOE, CONFIG_PM, CONFIG_DEBUG_FS) and not need driver specific 
toggles.

sln

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
@ 2017-12-21  3:30           ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-21  3:30 UTC (permalink / raw)
  To: intel-wired-lan

On 12/20/2017 6:21 PM, Marcelo Ricardo Leitner wrote:
> On Wed, Dec 20, 2017 at 05:39:13PM -0800, Shannon Nelson wrote:
>> On 12/20/2017 5:17 PM, Marcelo Ricardo Leitner wrote:
>>> Hi,
>>>
>>> On Tue, Dec 19, 2017 at 03:59:57PM -0800, Shannon Nelson wrote:
>>>> +}
>>>> +
>>>> +static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
>>>> +	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
>>>> +	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
>>>> +};
>>>> +
>>>
>>> This struct is only declared if XFRM_OFFLOAD is selected. What is
>>> selecting it for ixgbe driver?
>>> mlx5 driver has an extra option for ipsec offload and it then does
>>> 'depends on XFRM_OFFLOAD'
>>>
>>>     Marcelo
>>>
>>
>> I didn't bother putting a 'depends' item in the ixgbe's Kconfig entry, and I
>> didn't create an extra CONFIG variable to enable ixgbe's support of the
>> offload.  If CONFIG_XFRM_OFFLOAD is set, then ixgbe will support it.
> 
> You handled it via Makefile, okay. Missed it on patch 2, my bad.
> 
> Anyhow, we probably could use some standard here across the vendors
> here.  With this patchset, we have 2 drivers supporting it, and 2
> different ways to configure it.

I suspect that the mlx5 folks did an extra option as part of being the 
first to support the feature, and needing an easy way to toggle support 
while they were developing it without needing to rebuild the whole 
kernel.  Now that the feature has reached a certain level of "maturity", 
I think we can treat it like other features (e.g. CONFIG_PCI_IOV, 
CONFIG_FCOE, CONFIG_PM, CONFIG_DEBUG_FS) and not need driver specific 
toggles.

sln


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
  2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-21  6:39   ` Yanjun Zhu
  -1 siblings, 0 replies; 50+ messages in thread
From: Yanjun Zhu @ 2017-12-21  6:39 UTC (permalink / raw)
  To: Shannon Nelson, intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev



On 2017/12/20 7:59, Shannon Nelson wrote:
> This is an implementation of the ipsec hardware offload feature for
> the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
Hi, Nelson

I notice that the ipsec feature is based on x540, x550, 82599.  But this 
ixgbe driver
will also work with 82598.

Does this ipsec feature also work with 82598?

Thanks a lot.
Zhu Yanjun
> These patches apply to net-next v4.14 as well as Jeff Kirsher's next-queue
> v4.15-rc1-206-ge47375b.
>
> The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
> Associations (SAs), using up to 128 inbound IP addresses, and using the
> rfc4106(gcm(aes)) encryption.  This code does not yet support IPv6,
> checksum offload, or TSO in conjunction with the ipsec offload - those
> will be added in the future.
>
> This code shows improvements in both packet throughput and CPU utilization.
> For example, here are some quicky numbers that show the magnitude of the
> performance gain on a single run of "iperf -c <dest>" with the ipsec
> offload on both ends of a point-to-point connection:
>
> 	9.4 Gbps - normal case
> 	7.6 Gbps - ipsec with offload
> 	343 Mbps - ipsec no offload
>
> To set up a similar test case, you first need to be sure you have a recent
> version of iproute2 that supports the ipsec offload tag, probably something
> from ip 4.12 or newer would be best.  I have a shell script that builds
> up the appropriate commands for me, but here are the resulting commands
> for all tcp traffic between 14.0.0.52 and 14.0.0.70:
>
> For the left side (14.0.0.52):
>    ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>       proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport reqid 0x07
>    ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>       proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport reqid 0x07
>    ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir out
>    ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir in
>   
> For the right side (14.0.0.70):
>    ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>       proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport reqid 0x07
>    ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>       proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport reqid 0x07
>    ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir out
>    ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir in
>
> In both cases, the command "ip x s flush ; ip x p flush" will clean
> it all out and remove the offloads.
>
> Lastly, thanks to Alex Duyck for his early comments.
>
> Please see the individual patches for specific update info.
>
> v3: fixes after comments from those wonderfully pesky kbuild robots
> v2: fixes after comments from Alex
>
> Shannon Nelson (10):
>    ixgbe: clean up ipsec defines
>    ixgbe: add ipsec register access routines
>    ixgbe: add ipsec engine start and stop routines
>    ixgbe: add ipsec data structures
>    ixgbe: add ipsec offload add and remove SA
>    ixgbe: restore offloaded SAs after a reset
>    ixgbe: process the Rx ipsec offload
>    ixgbe: process the Tx ipsec offload
>    ixgbe: ipsec offload stats
>    ixgbe: register ipsec offload with the xfrm subsystem
>
>   drivers/net/ethernet/intel/ixgbe/Makefile        |   1 +
>   drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   2 +
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 923 +++++++++++++++++++++++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h   |  92 +++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   4 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  39 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  22 +-
>   8 files changed, 1093 insertions(+), 23 deletions(-)
>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
>

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
@ 2017-12-21  6:39   ` Yanjun Zhu
  0 siblings, 0 replies; 50+ messages in thread
From: Yanjun Zhu @ 2017-12-21  6:39 UTC (permalink / raw)
  To: intel-wired-lan



On 2017/12/20 7:59, Shannon Nelson wrote:
> This is an implementation of the ipsec hardware offload feature for
> the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
Hi, Nelson

I notice that the ipsec feature is based on x540, x550, 82599.? But this 
ixgbe driver
will also work with 82598.

Does this ipsec feature also work with 82598?

Thanks a lot.
Zhu Yanjun
> These patches apply to net-next v4.14 as well as Jeff Kirsher's next-queue
> v4.15-rc1-206-ge47375b.
>
> The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
> Associations (SAs), using up to 128 inbound IP addresses, and using the
> rfc4106(gcm(aes)) encryption.  This code does not yet support IPv6,
> checksum offload, or TSO in conjunction with the ipsec offload - those
> will be added in the future.
>
> This code shows improvements in both packet throughput and CPU utilization.
> For example, here are some quicky numbers that show the magnitude of the
> performance gain on a single run of "iperf -c <dest>" with the ipsec
> offload on both ends of a point-to-point connection:
>
> 	9.4 Gbps - normal case
> 	7.6 Gbps - ipsec with offload
> 	343 Mbps - ipsec no offload
>
> To set up a similar test case, you first need to be sure you have a recent
> version of iproute2 that supports the ipsec offload tag, probably something
> from ip 4.12 or newer would be best.  I have a shell script that builds
> up the appropriate commands for me, but here are the resulting commands
> for all tcp traffic between 14.0.0.52 and 14.0.0.70:
>
> For the left side (14.0.0.52):
>    ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>       proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport reqid 0x07
>    ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>       proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport reqid 0x07
>    ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir out
>    ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir in
>   
> For the right side (14.0.0.70):
>    ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>       proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport reqid 0x07
>    ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>       proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport reqid 0x07
>    ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev eth4 dir out
>    ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport \
>       reqid 0x07 replay-window 32 \
>       aead 'rfc4106(gcm(aes))' 0x44434241343332312423222114131211f4f3f2f1 128 \
>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev eth4 dir in
>
> In both cases, the command "ip x s flush ; ip x p flush" will clean
> it all out and remove the offloads.
>
> Lastly, thanks to Alex Duyck for his early comments.
>
> Please see the individual patches for specific update info.
>
> v3: fixes after comments from those wonderfully pesky kbuild robots
> v2: fixes after comments from Alex
>
> Shannon Nelson (10):
>    ixgbe: clean up ipsec defines
>    ixgbe: add ipsec register access routines
>    ixgbe: add ipsec engine start and stop routines
>    ixgbe: add ipsec data structures
>    ixgbe: add ipsec offload add and remove SA
>    ixgbe: restore offloaded SAs after a reset
>    ixgbe: process the Rx ipsec offload
>    ixgbe: process the Tx ipsec offload
>    ixgbe: ipsec offload stats
>    ixgbe: register ipsec offload with the xfrm subsystem
>
>   drivers/net/ethernet/intel/ixgbe/Makefile        |   1 +
>   drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   2 +
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 923 +++++++++++++++++++++++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h   |  92 +++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   4 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  39 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  22 +-
>   8 files changed, 1093 insertions(+), 23 deletions(-)
>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
  2017-12-21  6:39   ` [Intel-wired-lan] " Yanjun Zhu
@ 2017-12-21  7:09     ` Yanjun Zhu
  -1 siblings, 0 replies; 50+ messages in thread
From: Yanjun Zhu @ 2017-12-21  7:09 UTC (permalink / raw)
  To: Shannon Nelson, intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev



On 2017/12/21 14:39, Yanjun Zhu wrote:
>
>
> On 2017/12/20 7:59, Shannon Nelson wrote:
>> This is an implementation of the ipsec hardware offload feature for
>> the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
> Hi, Nelson
>
> I notice that the ipsec feature is based on x540, x550, 82599. But 
> this ixgbe driver
> will also work with 82598.
>
> Does this ipsec feature also work with 82598?
Sorry. I mean, after these ipsec patches are applied, whether ipsec 
offload enabled or not,
can this ixgbe driver still work well with 82598?

Zhu Yanjun
>
> Thanks a lot.
> Zhu Yanjun
>> These patches apply to net-next v4.14 as well as Jeff Kirsher's 
>> next-queue
>> v4.15-rc1-206-ge47375b.
>>
>> The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
>> Associations (SAs), using up to 128 inbound IP addresses, and using the
>> rfc4106(gcm(aes)) encryption.  This code does not yet support IPv6,
>> checksum offload, or TSO in conjunction with the ipsec offload - those
>> will be added in the future.
>>
>> This code shows improvements in both packet throughput and CPU 
>> utilization.
>> For example, here are some quicky numbers that show the magnitude of the
>> performance gain on a single run of "iperf -c <dest>" with the ipsec
>> offload on both ends of a point-to-point connection:
>>
>>     9.4 Gbps - normal case
>>     7.6 Gbps - ipsec with offload
>>     343 Mbps - ipsec no offload
>>
>> To set up a similar test case, you first need to be sure you have a 
>> recent
>> version of iproute2 that supports the ipsec offload tag, probably 
>> something
>> from ip 4.12 or newer would be best.  I have a shell script that builds
>> up the appropriate commands for me, but here are the resulting commands
>> for all tcp traffic between 14.0.0.52 and 14.0.0.70:
>>
>> For the left side (14.0.0.52):
>>    ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>>       proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport 
>> reqid 0x07
>>    ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>>       proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport 
>> reqid 0x07
>>    ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode 
>> transport \
>>       reqid 0x07 replay-window 32 \
>>       aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>> eth4 dir out
>>    ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode 
>> transport \
>>       reqid 0x07 replay-window 32 \
>>       aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>> eth4 dir in
>>   For the right side (14.0.0.70):
>>    ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>>       proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport 
>> reqid 0x07
>>    ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>>       proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport 
>> reqid 0x07
>>    ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode 
>> transport \
>>       reqid 0x07 replay-window 32 \
>>       aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>> eth4 dir out
>>    ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode 
>> transport \
>>       reqid 0x07 replay-window 32 \
>>       aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>> eth4 dir in
>>
>> In both cases, the command "ip x s flush ; ip x p flush" will clean
>> it all out and remove the offloads.
>>
>> Lastly, thanks to Alex Duyck for his early comments.
>>
>> Please see the individual patches for specific update info.
>>
>> v3: fixes after comments from those wonderfully pesky kbuild robots
>> v2: fixes after comments from Alex
>>
>> Shannon Nelson (10):
>>    ixgbe: clean up ipsec defines
>>    ixgbe: add ipsec register access routines
>>    ixgbe: add ipsec engine start and stop routines
>>    ixgbe: add ipsec data structures
>>    ixgbe: add ipsec offload add and remove SA
>>    ixgbe: restore offloaded SAs after a reset
>>    ixgbe: process the Rx ipsec offload
>>    ixgbe: process the Tx ipsec offload
>>    ixgbe: ipsec offload stats
>>    ixgbe: register ipsec offload with the xfrm subsystem
>>
>>   drivers/net/ethernet/intel/ixgbe/Makefile        |   1 +
>>   drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
>>   drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   2 +
>>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 923 
>> +++++++++++++++++++++++
>>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h   |  92 +++
>>   drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   4 +-
>>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  39 +-
>>   drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  22 +-
>>   8 files changed, 1093 insertions(+), 23 deletions(-)
>>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
>>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
>>
>
>

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
@ 2017-12-21  7:09     ` Yanjun Zhu
  0 siblings, 0 replies; 50+ messages in thread
From: Yanjun Zhu @ 2017-12-21  7:09 UTC (permalink / raw)
  To: intel-wired-lan



On 2017/12/21 14:39, Yanjun Zhu wrote:
>
>
> On 2017/12/20 7:59, Shannon Nelson wrote:
>> This is an implementation of the ipsec hardware offload feature for
>> the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
> Hi, Nelson
>
> I notice that the ipsec feature is based on x540, x550, 82599. But 
> this ixgbe driver
> will also work with 82598.
>
> Does this ipsec feature also work with 82598?
Sorry. I mean, after these ipsec patches are applied, whether ipsec 
offload enabled or not,
can this ixgbe driver still work well with 82598?

Zhu Yanjun
>
> Thanks a lot.
> Zhu Yanjun
>> These patches apply to net-next v4.14 as well as Jeff Kirsher's 
>> next-queue
>> v4.15-rc1-206-ge47375b.
>>
>> The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
>> Associations (SAs), using up to 128 inbound IP addresses, and using the
>> rfc4106(gcm(aes)) encryption.? This code does not yet support IPv6,
>> checksum offload, or TSO in conjunction with the ipsec offload - those
>> will be added in the future.
>>
>> This code shows improvements in both packet throughput and CPU 
>> utilization.
>> For example, here are some quicky numbers that show the magnitude of the
>> performance gain on a single run of "iperf -c <dest>" with the ipsec
>> offload on both ends of a point-to-point connection:
>>
>> ????9.4 Gbps - normal case
>> ????7.6 Gbps - ipsec with offload
>> ????343 Mbps - ipsec no offload
>>
>> To set up a similar test case, you first need to be sure you have a 
>> recent
>> version of iproute2 that supports the ipsec offload tag, probably 
>> something
>> from ip 4.12 or newer would be best.? I have a shell script that builds
>> up the appropriate commands for me, but here are the resulting commands
>> for all tcp traffic between 14.0.0.52 and 14.0.0.70:
>>
>> For the left side (14.0.0.52):
>> ?? ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>> ????? proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport 
>> reqid 0x07
>> ?? ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>> ????? proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport 
>> reqid 0x07
>> ?? ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode 
>> transport \
>> ????? reqid 0x07 replay-window 32 \
>> ????? aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>> ????? sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>> eth4 dir out
>> ?? ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode 
>> transport \
>> ????? reqid 0x07 replay-window 32 \
>> ????? aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>> ????? sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>> eth4 dir in
>> ? For the right side (14.0.0.70):
>> ?? ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>> ????? proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport 
>> reqid 0x07
>> ?? ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>> ????? proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport 
>> reqid 0x07
>> ?? ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode 
>> transport \
>> ????? reqid 0x07 replay-window 32 \
>> ????? aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>> ????? sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>> eth4 dir out
>> ?? ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode 
>> transport \
>> ????? reqid 0x07 replay-window 32 \
>> ????? aead 'rfc4106(gcm(aes))' 
>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>> ????? sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>> eth4 dir in
>>
>> In both cases, the command "ip x s flush ; ip x p flush" will clean
>> it all out and remove the offloads.
>>
>> Lastly, thanks to Alex Duyck for his early comments.
>>
>> Please see the individual patches for specific update info.
>>
>> v3: fixes after comments from those wonderfully pesky kbuild robots
>> v2: fixes after comments from Alex
>>
>> Shannon Nelson (10):
>> ?? ixgbe: clean up ipsec defines
>> ?? ixgbe: add ipsec register access routines
>> ?? ixgbe: add ipsec engine start and stop routines
>> ?? ixgbe: add ipsec data structures
>> ?? ixgbe: add ipsec offload add and remove SA
>> ?? ixgbe: restore offloaded SAs after a reset
>> ?? ixgbe: process the Rx ipsec offload
>> ?? ixgbe: process the Tx ipsec offload
>> ?? ixgbe: ipsec offload stats
>> ?? ixgbe: register ipsec offload with the xfrm subsystem
>>
>> ? drivers/net/ethernet/intel/ixgbe/Makefile??????? |?? 1 +
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe.h???????? |? 33 +-
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |?? 2 +
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c?? | 923 
>> +++++++++++++++++++++++
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h?? |? 92 +++
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c???? |?? 4 +-
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_main.c??? |? 39 +-
>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_type.h??? |? 22 +-
>> ? 8 files changed, 1093 insertions(+), 23 deletions(-)
>> ? create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
>> ? create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
>>
>
>


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
  2017-12-21  7:09     ` [Intel-wired-lan] " Yanjun Zhu
@ 2017-12-21 17:55       ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-21 17:55 UTC (permalink / raw)
  To: Yanjun Zhu, intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

On 12/20/2017 11:09 PM, Yanjun Zhu wrote:
> On 2017/12/21 14:39, Yanjun Zhu wrote:
>> On 2017/12/20 7:59, Shannon Nelson wrote:
>>> This is an implementation of the ipsec hardware offload feature for
>>> the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
>> Hi, Nelson
>>
>> I notice that the ipsec feature is based on x540, x550, 82599. But 
>> this ixgbe driver
>> will also work with 82598.
>>
>> Does this ipsec feature also work with 82598?
> Sorry. I mean, after these ipsec patches are applied, whether ipsec 
> offload enabled or not,
> can this ixgbe driver still work well with 82598?

Hmm... I don't have one to test on, but I suspect the 82598 might not be 
happy with this.  I'll send a followup patch to catch this case.

Thanks!
sln


> 
> Zhu Yanjun
>>
>> Thanks a lot.
>> Zhu Yanjun
>>> These patches apply to net-next v4.14 as well as Jeff Kirsher's 
>>> next-queue
>>> v4.15-rc1-206-ge47375b.
>>>
>>> The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
>>> Associations (SAs), using up to 128 inbound IP addresses, and using the
>>> rfc4106(gcm(aes)) encryption.  This code does not yet support IPv6,
>>> checksum offload, or TSO in conjunction with the ipsec offload - those
>>> will be added in the future.
>>>
>>> This code shows improvements in both packet throughput and CPU 
>>> utilization.
>>> For example, here are some quicky numbers that show the magnitude of the
>>> performance gain on a single run of "iperf -c <dest>" with the ipsec
>>> offload on both ends of a point-to-point connection:
>>>
>>>     9.4 Gbps - normal case
>>>     7.6 Gbps - ipsec with offload
>>>     343 Mbps - ipsec no offload
>>>
>>> To set up a similar test case, you first need to be sure you have a 
>>> recent
>>> version of iproute2 that supports the ipsec offload tag, probably 
>>> something
>>> from ip 4.12 or newer would be best.  I have a shell script that builds
>>> up the appropriate commands for me, but here are the resulting commands
>>> for all tcp traffic between 14.0.0.52 and 14.0.0.70:
>>>
>>> For the left side (14.0.0.52):
>>>    ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>>>       proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport 
>>> reqid 0x07
>>>    ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>>>       proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport 
>>> reqid 0x07
>>>    ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode 
>>> transport \
>>>       reqid 0x07 replay-window 32 \
>>>       aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>>> eth4 dir out
>>>    ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode 
>>> transport \
>>>       reqid 0x07 replay-window 32 \
>>>       aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>>> eth4 dir in
>>>   For the right side (14.0.0.70):
>>>    ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>>>       proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport 
>>> reqid 0x07
>>>    ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>>>       proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport 
>>> reqid 0x07
>>>    ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode 
>>> transport \
>>>       reqid 0x07 replay-window 32 \
>>>       aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>>       sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>>> eth4 dir out
>>>    ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode 
>>> transport \
>>>       reqid 0x07 replay-window 32 \
>>>       aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>>       sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>>> eth4 dir in
>>>
>>> In both cases, the command "ip x s flush ; ip x p flush" will clean
>>> it all out and remove the offloads.
>>>
>>> Lastly, thanks to Alex Duyck for his early comments.
>>>
>>> Please see the individual patches for specific update info.
>>>
>>> v3: fixes after comments from those wonderfully pesky kbuild robots
>>> v2: fixes after comments from Alex
>>>
>>> Shannon Nelson (10):
>>>    ixgbe: clean up ipsec defines
>>>    ixgbe: add ipsec register access routines
>>>    ixgbe: add ipsec engine start and stop routines
>>>    ixgbe: add ipsec data structures
>>>    ixgbe: add ipsec offload add and remove SA
>>>    ixgbe: restore offloaded SAs after a reset
>>>    ixgbe: process the Rx ipsec offload
>>>    ixgbe: process the Tx ipsec offload
>>>    ixgbe: ipsec offload stats
>>>    ixgbe: register ipsec offload with the xfrm subsystem
>>>
>>>   drivers/net/ethernet/intel/ixgbe/Makefile        |   1 +
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe.h         |  33 +-
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |   2 +
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 923 
>>> +++++++++++++++++++++++
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h   |  92 +++
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c     |   4 +-
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |  39 +-
>>>   drivers/net/ethernet/intel/ixgbe/ixgbe_type.h    |  22 +-
>>>   8 files changed, 1093 insertions(+), 23 deletions(-)
>>>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
>>>   create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
>>>
>>
>>
> 

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload
@ 2017-12-21 17:55       ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-21 17:55 UTC (permalink / raw)
  To: intel-wired-lan

On 12/20/2017 11:09 PM, Yanjun Zhu wrote:
> On 2017/12/21 14:39, Yanjun Zhu wrote:
>> On 2017/12/20 7:59, Shannon Nelson wrote:
>>> This is an implementation of the ipsec hardware offload feature for
>>> the ixgbe driver and Intel's 10Gbe series NICs: x540, x550, 82599.
>> Hi, Nelson
>>
>> I notice that the ipsec feature is based on x540, x550, 82599. But 
>> this ixgbe driver
>> will also work with 82598.
>>
>> Does this ipsec feature also work with 82598?
> Sorry. I mean, after these ipsec patches are applied, whether ipsec 
> offload enabled or not,
> can this ixgbe driver still work well with 82598?

Hmm... I don't have one to test on, but I suspect the 82598 might not be 
happy with this.  I'll send a followup patch to catch this case.

Thanks!
sln


> 
> Zhu Yanjun
>>
>> Thanks a lot.
>> Zhu Yanjun
>>> These patches apply to net-next v4.14 as well as Jeff Kirsher's 
>>> next-queue
>>> v4.15-rc1-206-ge47375b.
>>>
>>> The ixgbe NICs support ipsec offload for 1024 Rx and 1024 Tx Security
>>> Associations (SAs), using up to 128 inbound IP addresses, and using the
>>> rfc4106(gcm(aes)) encryption.? This code does not yet support IPv6,
>>> checksum offload, or TSO in conjunction with the ipsec offload - those
>>> will be added in the future.
>>>
>>> This code shows improvements in both packet throughput and CPU 
>>> utilization.
>>> For example, here are some quicky numbers that show the magnitude of the
>>> performance gain on a single run of "iperf -c <dest>" with the ipsec
>>> offload on both ends of a point-to-point connection:
>>>
>>> ????9.4 Gbps - normal case
>>> ????7.6 Gbps - ipsec with offload
>>> ????343 Mbps - ipsec no offload
>>>
>>> To set up a similar test case, you first need to be sure you have a 
>>> recent
>>> version of iproute2 that supports the ipsec offload tag, probably 
>>> something
>>> from ip 4.12 or newer would be best.? I have a shell script that builds
>>> up the appropriate commands for me, but here are the resulting commands
>>> for all tcp traffic between 14.0.0.52 and 14.0.0.70:
>>>
>>> For the left side (14.0.0.52):
>>> ?? ip x p add dir out src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>>> ????? proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode transport 
>>> reqid 0x07
>>> ?? ip x p add dir in src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>>> ????? proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode transport 
>>> reqid 0x07
>>> ?? ip x s add proto esp src 14.0.0.52 dst 14.0.0.70 spi 0x07 mode 
>>> transport \
>>> ????? reqid 0x07 replay-window 32 \
>>> ????? aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>> ????? sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>>> eth4 dir out
>>> ?? ip x s add proto esp dst 14.0.0.52 src 14.0.0.70 spi 0x07 mode 
>>> transport \
>>> ????? reqid 0x07 replay-window 32 \
>>> ????? aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>> ????? sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>>> eth4 dir in
>>> ? For the right side (14.0.0.70):
>>> ?? ip x p add dir out src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp tmpl \
>>> ????? proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode transport 
>>> reqid 0x07
>>> ?? ip x p add dir in src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp tmpl \
>>> ????? proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode transport 
>>> reqid 0x07
>>> ?? ip x s add proto esp src 14.0.0.70 dst 14.0.0.52 spi 0x07 mode 
>>> transport \
>>> ????? reqid 0x07 replay-window 32 \
>>> ????? aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>> ????? sel src 14.0.0.70/24 dst 14.0.0.52/24 proto tcp offload dev 
>>> eth4 dir out
>>> ?? ip x s add proto esp dst 14.0.0.70 src 14.0.0.52 spi 0x07 mode 
>>> transport \
>>> ????? reqid 0x07 replay-window 32 \
>>> ????? aead 'rfc4106(gcm(aes))' 
>>> 0x44434241343332312423222114131211f4f3f2f1 128 \
>>> ????? sel src 14.0.0.52/24 dst 14.0.0.70/24 proto tcp offload dev 
>>> eth4 dir in
>>>
>>> In both cases, the command "ip x s flush ; ip x p flush" will clean
>>> it all out and remove the offloads.
>>>
>>> Lastly, thanks to Alex Duyck for his early comments.
>>>
>>> Please see the individual patches for specific update info.
>>>
>>> v3: fixes after comments from those wonderfully pesky kbuild robots
>>> v2: fixes after comments from Alex
>>>
>>> Shannon Nelson (10):
>>> ?? ixgbe: clean up ipsec defines
>>> ?? ixgbe: add ipsec register access routines
>>> ?? ixgbe: add ipsec engine start and stop routines
>>> ?? ixgbe: add ipsec data structures
>>> ?? ixgbe: add ipsec offload add and remove SA
>>> ?? ixgbe: restore offloaded SAs after a reset
>>> ?? ixgbe: process the Rx ipsec offload
>>> ?? ixgbe: process the Tx ipsec offload
>>> ?? ixgbe: ipsec offload stats
>>> ?? ixgbe: register ipsec offload with the xfrm subsystem
>>>
>>> ? drivers/net/ethernet/intel/ixgbe/Makefile??????? |?? 1 +
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe.h???????? |? 33 +-
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |?? 2 +
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c?? | 923 
>>> +++++++++++++++++++++++
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h?? |? 92 +++
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c???? |?? 4 +-
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_main.c??? |? 39 +-
>>> ? drivers/net/ethernet/intel/ixgbe/ixgbe_type.h??? |? 22 +-
>>> ? 8 files changed, 1093 insertions(+), 23 deletions(-)
>>> ? create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
>>> ? create mode 100644 drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h
>>>
>>
>>
> 

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
  2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
@ 2017-12-22  8:24     ` Yanjun Zhu
  -1 siblings, 0 replies; 50+ messages in thread
From: Yanjun Zhu @ 2017-12-22  8:24 UTC (permalink / raw)
  To: Shannon Nelson, intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev



On 2017/12/20 8:00, Shannon Nelson wrote:
> If the skb has a security association referenced in the skb, then
> set up the Tx descriptor with the ipsec offload bits.  While we're
> here, we fix an oddly named field in the context descriptor struct.
>
> v3: added ifdef CONFIG_XFRM_OFFLOAD check around call to ixgbe_ipsec_tx()
>
> v2: use ihl != 5
>      move the ixgbe_ipsec_tx() call to near the call to ixgbe_tso()
>      drop the ipsec packet if the tx offload setup fails
>      simplify the ixgbe_ipsec_tx() parameters by using 'first'
>      leave out the ixgbe_tso() changes since we don't support TSO
>         with ipsec yet.
>
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>   drivers/net/ethernet/intel/ixgbe/ixgbe.h       | 10 +++-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 79 ++++++++++++++++++++++++++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c   |  4 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 26 +++++++--
>   drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |  2 +-
>   5 files changed, 112 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> index a094b23..3d2b7bf 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> @@ -171,10 +171,11 @@ enum ixgbe_tx_flags {
>   	IXGBE_TX_FLAGS_CC	= 0x08,
>   	IXGBE_TX_FLAGS_IPV4	= 0x10,
>   	IXGBE_TX_FLAGS_CSUM	= 0x20,
> +	IXGBE_TX_FLAGS_IPSEC	= 0x40,
>   
>   	/* software defined flags */
> -	IXGBE_TX_FLAGS_SW_VLAN	= 0x40,
> -	IXGBE_TX_FLAGS_FCOE	= 0x80,
> +	IXGBE_TX_FLAGS_SW_VLAN	= 0x80,
> +	IXGBE_TX_FLAGS_FCOE	= 0x100,
>   };
>   
>   /* VLAN info */
> @@ -1014,6 +1015,8 @@ void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
>   void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
>   		    union ixgbe_adv_rx_desc *rx_desc,
>   		    struct sk_buff *skb);
> +int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring, struct ixgbe_tx_buffer *first,
> +		   struct ixgbe_ipsec_tx_data *itd);
>   #else
>   static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
>   static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
> @@ -1021,5 +1024,8 @@ static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
>   static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
>   				  union ixgbe_adv_rx_desc *rx_desc,
>   				  struct sk_buff *skb) { };
> +static inline int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
> +				 struct ixgbe_tx_buffer *first,
> +				 struct ixgbe_ipsec_tx_data *itd) { return 0; };
>   #endif /* CONFIG_XFRM_OFFLOAD */
>   #endif /* _IXGBE_H_ */
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> index a9b8f5c..c2fd2ac 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> @@ -695,12 +695,91 @@ static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
>   	}
>   }
>   
> +/**
> + * ixgbe_ipsec_offload_ok - can this packet use the xfrm hw offload
> + * @skb: current data packet
> + * @xs: pointer to transformer state struct
> + **/
> +static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
> +{
> +	if (xs->props.family == AF_INET) {
> +		/* Offload with IPv4 options is not supported yet */
> +		if (ip_hdr(skb)->ihl != 5)
> +			return false;
> +	} else {
> +		/* Offload with IPv6 extension headers is not support yet */
> +		if (ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr))
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>   static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
>   	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
>   	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
> +	.xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
>   };
>   
>   /**
> + * ixgbe_ipsec_tx - setup Tx flags for ipsec offload
> + * @tx_ring: outgoing context
> + * @first: current data packet
> + * @itd: ipsec Tx data for later use in building context descriptor
> + **/
> +int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
> +		   struct ixgbe_tx_buffer *first,
> +		   struct ixgbe_ipsec_tx_data *itd)
> +{
> +	struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
> +	struct ixgbe_ipsec *ipsec = adapter->ipsec;
> +	struct xfrm_state *xs;
> +	struct tx_sa *tsa;
> +
> +	if (!first->skb->sp->len) {
Hi, Nelson

The function ixgbe_ipsec_tx is called in tx fastpath. Can we add 
unlikely as below:
if (unlikely(!first->skb->sp->len)) ?

If I am wrong, please correct me.

Thanks a lot.
Zhu Yanjun
> +		netdev_err(tx_ring->netdev, "%s: no xfrm state len = %d\n",
> +			   __func__, first->skb->sp->len);
> +		return 0;
> +	}
> +
> +	xs = xfrm_input_state(first->skb);
> +	if (!xs) {
if (unlikely(!xs)) {
> +		netdev_err(tx_ring->netdev, "%s: no xfrm_input_state() xs = %p\n",
> +			   __func__, xs);
> +		return 0;
> +	}
> +
> +	itd->sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;
> +	if (itd->sa_idx > IXGBE_IPSEC_MAX_SA_COUNT) {
if (unlikely(itd->sa_idx > IXGBE_IPSEC_MAX_SA_COUNT))
> +		netdev_err(tx_ring->netdev, "%s: bad sa_idx=%d handle=%lu\n",
> +			   __func__, itd->sa_idx, xs->xso.offload_handle);
> +		return 0;
> +	}
> +
> +	tsa = &ipsec->tx_tbl[itd->sa_idx];
> +	if (!tsa->used) {
if (unlikely(!tsa->used)) {
> +		netdev_err(tx_ring->netdev, "%s: unused sa_idx=%d\n",
> +			   __func__, itd->sa_idx);
> +		return 0;
> +	}
> +
> +	first->tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CC;
> +
> +	itd->flags = 0;
> +	if (xs->id.proto == IPPROTO_ESP) {
> +		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
> +			      IXGBE_ADVTXD_TUCMD_L4T_TCP;
> +		if (first->protocol == htons(ETH_P_IP))
> +			itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;
> +		itd->trailer_len = xs->props.trailer_len;
> +	}
> +	if (tsa->encrypt)
> +		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
> +
> +	return 1;
> +}
> +
> +/**
>    * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
>    * @rx_ring: receiving ring
>    * @rx_desc: receive data descriptor
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> index f1bfae0..d7875b3 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> @@ -1261,7 +1261,7 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
>   }
>   
>   void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
> -		       u32 fcoe_sof_eof, u32 type_tucmd, u32 mss_l4len_idx)
> +		       u32 fceof_saidx, u32 type_tucmd, u32 mss_l4len_idx)
>   {
>   	struct ixgbe_adv_tx_context_desc *context_desc;
>   	u16 i = tx_ring->next_to_use;
> @@ -1275,7 +1275,7 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
>   	type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
>   
>   	context_desc->vlan_macip_lens	= cpu_to_le32(vlan_macip_lens);
> -	context_desc->seqnum_seed	= cpu_to_le32(fcoe_sof_eof);
> +	context_desc->fceof_saidx	= cpu_to_le32(fceof_saidx);
>   	context_desc->type_tucmd_mlhl	= cpu_to_le32(type_tucmd);
>   	context_desc->mss_l4len_idx	= cpu_to_le32(mss_l4len_idx);
>   }
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 0ee1e5e..6b9a9b2 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -7756,10 +7756,12 @@ static inline bool ixgbe_ipv6_csum_is_sctp(struct sk_buff *skb)
>   }
>   
>   static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
> -			  struct ixgbe_tx_buffer *first)
> +			  struct ixgbe_tx_buffer *first,
> +			  struct ixgbe_ipsec_tx_data *itd)
>   {
>   	struct sk_buff *skb = first->skb;
>   	u32 vlan_macip_lens = 0;
> +	u32 fceof_saidx = 0;
>   	u32 type_tucmd = 0;
>   
>   	if (skb->ip_summed != CHECKSUM_PARTIAL) {
> @@ -7800,7 +7802,12 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
>   	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
>   	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
>   
> -	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, 0);
> +	if (first->tx_flags & IXGBE_TX_FLAGS_IPSEC) {
> +		fceof_saidx |= itd->sa_idx;
> +		type_tucmd |= itd->flags | itd->trailer_len;
> +	}
> +
> +	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fceof_saidx, type_tucmd, 0);
>   }
>   
>   #define IXGBE_SET_FLAG(_input, _flag, _result) \
> @@ -7843,11 +7850,16 @@ static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc,
>   					IXGBE_TX_FLAGS_CSUM,
>   					IXGBE_ADVTXD_POPTS_TXSM);
>   
> -	/* enble IPv4 checksum for TSO */
> +	/* enable IPv4 checksum for TSO */
>   	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
>   					IXGBE_TX_FLAGS_IPV4,
>   					IXGBE_ADVTXD_POPTS_IXSM);
>   
> +	/* enable IPsec */
> +	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
> +					IXGBE_TX_FLAGS_IPSEC,
> +					IXGBE_ADVTXD_POPTS_IPSEC);
> +
>   	/*
>   	 * Check Context must be set if Tx switch is enabled, which it
>   	 * always is for case where virtual functions are running
> @@ -8306,6 +8318,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
>   	u32 tx_flags = 0;
>   	unsigned short f;
>   	u16 count = TXD_USE_COUNT(skb_headlen(skb));
> +	struct ixgbe_ipsec_tx_data ipsec_tx = { 0 };
>   	__be16 protocol = skb->protocol;
>   	u8 hdr_len = 0;
>   
> @@ -8410,11 +8423,16 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
>   	}
>   
>   #endif /* IXGBE_FCOE */
> +
> +#ifdef CONFIG_XFRM_OFFLOAD
> +	if (skb->sp && !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
> +		goto out_drop;
> +#endif
>   	tso = ixgbe_tso(tx_ring, first, &hdr_len);
>   	if (tso < 0)
>   		goto out_drop;
>   	else if (!tso)
> -		ixgbe_tx_csum(tx_ring, first);
> +		ixgbe_tx_csum(tx_ring, first, &ipsec_tx);
>   
>   	/* add the ATR filter if ATR is on */
>   	if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> index 3df0763..0ac725fa 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> @@ -2856,7 +2856,7 @@ union ixgbe_adv_rx_desc {
>   /* Context descriptors */
>   struct ixgbe_adv_tx_context_desc {
>   	__le32 vlan_macip_lens;
> -	__le32 seqnum_seed;
> +	__le32 fceof_saidx;
>   	__le32 type_tucmd_mlhl;
>   	__le32 mss_l4len_idx;
>   };

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
@ 2017-12-22  8:24     ` Yanjun Zhu
  0 siblings, 0 replies; 50+ messages in thread
From: Yanjun Zhu @ 2017-12-22  8:24 UTC (permalink / raw)
  To: intel-wired-lan



On 2017/12/20 8:00, Shannon Nelson wrote:
> If the skb has a security association referenced in the skb, then
> set up the Tx descriptor with the ipsec offload bits.  While we're
> here, we fix an oddly named field in the context descriptor struct.
>
> v3: added ifdef CONFIG_XFRM_OFFLOAD check around call to ixgbe_ipsec_tx()
>
> v2: use ihl != 5
>      move the ixgbe_ipsec_tx() call to near the call to ixgbe_tso()
>      drop the ipsec packet if the tx offload setup fails
>      simplify the ixgbe_ipsec_tx() parameters by using 'first'
>      leave out the ixgbe_tso() changes since we don't support TSO
>         with ipsec yet.
>
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>   drivers/net/ethernet/intel/ixgbe/ixgbe.h       | 10 +++-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 79 ++++++++++++++++++++++++++
>   drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c   |  4 +-
>   drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 26 +++++++--
>   drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |  2 +-
>   5 files changed, 112 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> index a094b23..3d2b7bf 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
> @@ -171,10 +171,11 @@ enum ixgbe_tx_flags {
>   	IXGBE_TX_FLAGS_CC	= 0x08,
>   	IXGBE_TX_FLAGS_IPV4	= 0x10,
>   	IXGBE_TX_FLAGS_CSUM	= 0x20,
> +	IXGBE_TX_FLAGS_IPSEC	= 0x40,
>   
>   	/* software defined flags */
> -	IXGBE_TX_FLAGS_SW_VLAN	= 0x40,
> -	IXGBE_TX_FLAGS_FCOE	= 0x80,
> +	IXGBE_TX_FLAGS_SW_VLAN	= 0x80,
> +	IXGBE_TX_FLAGS_FCOE	= 0x100,
>   };
>   
>   /* VLAN info */
> @@ -1014,6 +1015,8 @@ void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter);
>   void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
>   		    union ixgbe_adv_rx_desc *rx_desc,
>   		    struct sk_buff *skb);
> +int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring, struct ixgbe_tx_buffer *first,
> +		   struct ixgbe_ipsec_tx_data *itd);
>   #else
>   static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { };
>   static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { };
> @@ -1021,5 +1024,8 @@ static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { };
>   static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring,
>   				  union ixgbe_adv_rx_desc *rx_desc,
>   				  struct sk_buff *skb) { };
> +static inline int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
> +				 struct ixgbe_tx_buffer *first,
> +				 struct ixgbe_ipsec_tx_data *itd) { return 0; };
>   #endif /* CONFIG_XFRM_OFFLOAD */
>   #endif /* _IXGBE_H_ */
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> index a9b8f5c..c2fd2ac 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> @@ -695,12 +695,91 @@ static void ixgbe_ipsec_del_sa(struct xfrm_state *xs)
>   	}
>   }
>   
> +/**
> + * ixgbe_ipsec_offload_ok - can this packet use the xfrm hw offload
> + * @skb: current data packet
> + * @xs: pointer to transformer state struct
> + **/
> +static bool ixgbe_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
> +{
> +	if (xs->props.family == AF_INET) {
> +		/* Offload with IPv4 options is not supported yet */
> +		if (ip_hdr(skb)->ihl != 5)
> +			return false;
> +	} else {
> +		/* Offload with IPv6 extension headers is not support yet */
> +		if (ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr))
> +			return false;
> +	}
> +
> +	return true;
> +}
> +
>   static const struct xfrmdev_ops ixgbe_xfrmdev_ops = {
>   	.xdo_dev_state_add = ixgbe_ipsec_add_sa,
>   	.xdo_dev_state_delete = ixgbe_ipsec_del_sa,
> +	.xdo_dev_offload_ok = ixgbe_ipsec_offload_ok,
>   };
>   
>   /**
> + * ixgbe_ipsec_tx - setup Tx flags for ipsec offload
> + * @tx_ring: outgoing context
> + * @first: current data packet
> + * @itd: ipsec Tx data for later use in building context descriptor
> + **/
> +int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
> +		   struct ixgbe_tx_buffer *first,
> +		   struct ixgbe_ipsec_tx_data *itd)
> +{
> +	struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
> +	struct ixgbe_ipsec *ipsec = adapter->ipsec;
> +	struct xfrm_state *xs;
> +	struct tx_sa *tsa;
> +
> +	if (!first->skb->sp->len) {
Hi, Nelson

The function ixgbe_ipsec_tx is called in tx fastpath. Can we add 
unlikely as below:
if (unlikely(!first->skb->sp->len)) ?

If I am wrong, please correct me.

Thanks a lot.
Zhu Yanjun
> +		netdev_err(tx_ring->netdev, "%s: no xfrm state len = %d\n",
> +			   __func__, first->skb->sp->len);
> +		return 0;
> +	}
> +
> +	xs = xfrm_input_state(first->skb);
> +	if (!xs) {
if (unlikely(!xs)) {
> +		netdev_err(tx_ring->netdev, "%s: no xfrm_input_state() xs = %p\n",
> +			   __func__, xs);
> +		return 0;
> +	}
> +
> +	itd->sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_TX_INDEX;
> +	if (itd->sa_idx > IXGBE_IPSEC_MAX_SA_COUNT) {
if (unlikely(itd->sa_idx > IXGBE_IPSEC_MAX_SA_COUNT))
> +		netdev_err(tx_ring->netdev, "%s: bad sa_idx=%d handle=%lu\n",
> +			   __func__, itd->sa_idx, xs->xso.offload_handle);
> +		return 0;
> +	}
> +
> +	tsa = &ipsec->tx_tbl[itd->sa_idx];
> +	if (!tsa->used) {
if (unlikely(!tsa->used)) {
> +		netdev_err(tx_ring->netdev, "%s: unused sa_idx=%d\n",
> +			   __func__, itd->sa_idx);
> +		return 0;
> +	}
> +
> +	first->tx_flags |= IXGBE_TX_FLAGS_IPSEC | IXGBE_TX_FLAGS_CC;
> +
> +	itd->flags = 0;
> +	if (xs->id.proto == IPPROTO_ESP) {
> +		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP |
> +			      IXGBE_ADVTXD_TUCMD_L4T_TCP;
> +		if (first->protocol == htons(ETH_P_IP))
> +			itd->flags |= IXGBE_ADVTXD_TUCMD_IPV4;
> +		itd->trailer_len = xs->props.trailer_len;
> +	}
> +	if (tsa->encrypt)
> +		itd->flags |= IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN;
> +
> +	return 1;
> +}
> +
> +/**
>    * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor
>    * @rx_ring: receiving ring
>    * @rx_desc: receive data descriptor
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> index f1bfae0..d7875b3 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c
> @@ -1261,7 +1261,7 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
>   }
>   
>   void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
> -		       u32 fcoe_sof_eof, u32 type_tucmd, u32 mss_l4len_idx)
> +		       u32 fceof_saidx, u32 type_tucmd, u32 mss_l4len_idx)
>   {
>   	struct ixgbe_adv_tx_context_desc *context_desc;
>   	u16 i = tx_ring->next_to_use;
> @@ -1275,7 +1275,7 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
>   	type_tucmd |= IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT;
>   
>   	context_desc->vlan_macip_lens	= cpu_to_le32(vlan_macip_lens);
> -	context_desc->seqnum_seed	= cpu_to_le32(fcoe_sof_eof);
> +	context_desc->fceof_saidx	= cpu_to_le32(fceof_saidx);
>   	context_desc->type_tucmd_mlhl	= cpu_to_le32(type_tucmd);
>   	context_desc->mss_l4len_idx	= cpu_to_le32(mss_l4len_idx);
>   }
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> index 0ee1e5e..6b9a9b2 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
> @@ -7756,10 +7756,12 @@ static inline bool ixgbe_ipv6_csum_is_sctp(struct sk_buff *skb)
>   }
>   
>   static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
> -			  struct ixgbe_tx_buffer *first)
> +			  struct ixgbe_tx_buffer *first,
> +			  struct ixgbe_ipsec_tx_data *itd)
>   {
>   	struct sk_buff *skb = first->skb;
>   	u32 vlan_macip_lens = 0;
> +	u32 fceof_saidx = 0;
>   	u32 type_tucmd = 0;
>   
>   	if (skb->ip_summed != CHECKSUM_PARTIAL) {
> @@ -7800,7 +7802,12 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
>   	vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
>   	vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
>   
> -	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, 0);
> +	if (first->tx_flags & IXGBE_TX_FLAGS_IPSEC) {
> +		fceof_saidx |= itd->sa_idx;
> +		type_tucmd |= itd->flags | itd->trailer_len;
> +	}
> +
> +	ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, fceof_saidx, type_tucmd, 0);
>   }
>   
>   #define IXGBE_SET_FLAG(_input, _flag, _result) \
> @@ -7843,11 +7850,16 @@ static void ixgbe_tx_olinfo_status(union ixgbe_adv_tx_desc *tx_desc,
>   					IXGBE_TX_FLAGS_CSUM,
>   					IXGBE_ADVTXD_POPTS_TXSM);
>   
> -	/* enble IPv4 checksum for TSO */
> +	/* enable IPv4 checksum for TSO */
>   	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
>   					IXGBE_TX_FLAGS_IPV4,
>   					IXGBE_ADVTXD_POPTS_IXSM);
>   
> +	/* enable IPsec */
> +	olinfo_status |= IXGBE_SET_FLAG(tx_flags,
> +					IXGBE_TX_FLAGS_IPSEC,
> +					IXGBE_ADVTXD_POPTS_IPSEC);
> +
>   	/*
>   	 * Check Context must be set if Tx switch is enabled, which it
>   	 * always is for case where virtual functions are running
> @@ -8306,6 +8318,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
>   	u32 tx_flags = 0;
>   	unsigned short f;
>   	u16 count = TXD_USE_COUNT(skb_headlen(skb));
> +	struct ixgbe_ipsec_tx_data ipsec_tx = { 0 };
>   	__be16 protocol = skb->protocol;
>   	u8 hdr_len = 0;
>   
> @@ -8410,11 +8423,16 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
>   	}
>   
>   #endif /* IXGBE_FCOE */
> +
> +#ifdef CONFIG_XFRM_OFFLOAD
> +	if (skb->sp && !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
> +		goto out_drop;
> +#endif
>   	tso = ixgbe_tso(tx_ring, first, &hdr_len);
>   	if (tso < 0)
>   		goto out_drop;
>   	else if (!tso)
> -		ixgbe_tx_csum(tx_ring, first);
> +		ixgbe_tx_csum(tx_ring, first, &ipsec_tx);
>   
>   	/* add the ATR filter if ATR is on */
>   	if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> index 3df0763..0ac725fa 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
> @@ -2856,7 +2856,7 @@ union ixgbe_adv_rx_desc {
>   /* Context descriptors */
>   struct ixgbe_adv_tx_context_desc {
>   	__le32 vlan_macip_lens;
> -	__le32 seqnum_seed;
> +	__le32 fceof_saidx;
>   	__le32 type_tucmd_mlhl;
>   	__le32 mss_l4len_idx;
>   };


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
  2017-12-22  8:24     ` [Intel-wired-lan] " Yanjun Zhu
@ 2017-12-22 22:33       ` Shannon Nelson
  -1 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-22 22:33 UTC (permalink / raw)
  To: Yanjun Zhu, intel-wired-lan, jeffrey.t.kirsher
  Cc: steffen.klassert, sowmini.varadhan, netdev

On 12/22/2017 12:24 AM, Yanjun Zhu wrote:
> On 2017/12/20 8:00, Shannon Nelson wrote:
>> If the skb has a security association referenced in the skb, then
>> set up the Tx descriptor with the ipsec offload bits.  While we're
>> here, we fix an oddly named field in the context descriptor struct.
>>

[...]

>> +int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
>> +           struct ixgbe_tx_buffer *first,
>> +           struct ixgbe_ipsec_tx_data *itd)
>> +{
>> +    struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
>> +    struct ixgbe_ipsec *ipsec = adapter->ipsec;
>> +    struct xfrm_state *xs;
>> +    struct tx_sa *tsa;
>> +
>> +    if (!first->skb->sp->len) {
> Hi, Nelson
> 
> The function ixgbe_ipsec_tx is called in tx fastpath. Can we add 
> unlikely as below:
> if (unlikely(!first->skb->sp->len)) ?
> 
> If I am wrong, please correct me.
> 
> Thanks a lot.
> Zhu Yanjun

Yes, we can probably throw those in.  I'll be working on this code in 
the new year to get the checksum and TSO bits working and can add these 
at that time.

sln

^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
@ 2017-12-22 22:33       ` Shannon Nelson
  0 siblings, 0 replies; 50+ messages in thread
From: Shannon Nelson @ 2017-12-22 22:33 UTC (permalink / raw)
  To: intel-wired-lan

On 12/22/2017 12:24 AM, Yanjun Zhu wrote:
> On 2017/12/20 8:00, Shannon Nelson wrote:
>> If the skb has a security association referenced in the skb, then
>> set up the Tx descriptor with the ipsec offload bits.? While we're
>> here, we fix an oddly named field in the context descriptor struct.
>>

[...]

>> +int ixgbe_ipsec_tx(struct ixgbe_ring *tx_ring,
>> +?????????? struct ixgbe_tx_buffer *first,
>> +?????????? struct ixgbe_ipsec_tx_data *itd)
>> +{
>> +??? struct ixgbe_adapter *adapter = netdev_priv(tx_ring->netdev);
>> +??? struct ixgbe_ipsec *ipsec = adapter->ipsec;
>> +??? struct xfrm_state *xs;
>> +??? struct tx_sa *tsa;
>> +
>> +??? if (!first->skb->sp->len) {
> Hi, Nelson
> 
> The function ixgbe_ipsec_tx is called in tx fastpath. Can we add 
> unlikely as below:
> if (unlikely(!first->skb->sp->len)) ?
> 
> If I am wrong, please correct me.
> 
> Thanks a lot.
> Zhu Yanjun

Yes, we can probably throw those in.  I'll be working on this code in 
the new year to get the checksum and TSO bits working and can add these 
at that time.

sln



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 01/10] ixgbe: clean up ipsec defines
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:27   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:27 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 01/10] ixgbe: clean up ipsec
> defines
> 
> Clean up the ipsec/macsec descriptor bit definitions to match the rest of the
> defines and file organization.  Also recognise the bit-definition overlap in the
> error mask macro.
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 20 +++++++-------------
>  1 file changed, 7 insertions(+), 13 deletions(-)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 02/10] ixgbe: add ipsec register access routines
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:28   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:28 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 02/10] ixgbe: add ipsec
> register access routines
> 
> Add a few routines to make access to the ipsec registers just a little easier,
> and throw in the beginnings of an initialization.
> 
> v3: fixed a couple checkpatch warnings
> 
> v2: Rx table selector becomes an enum with a shift
>     Combine the clear table loops into one
>     Name the table index shift value
>     Use the addr as __be32
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/Makefile      |   1 +
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   6 +
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 161
> +++++++++++++++++++++++++
> drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h |  53 ++++++++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +
>  5 files changed, 222 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 03/10] ixgbe: add ipsec engine start and stop routines
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:28   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:28 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 03/10] ixgbe: add ipsec
> engine start and stop routines
> 
> Add in the code for running and stopping the hardware ipsec
> encryption/decryption engine.  It is good to keep the engine off when not in
> use in order to save on the power draw.
> 
> v2: add limiter to do-while loop waiting for paths to drain
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 142
> +++++++++++++++++++++++++
>  1 file changed, 142 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 04/10] ixgbe: add ipsec data structures
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:29   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:29 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 04/10] ixgbe: add ipsec data
> structures
> 
> Set up the data structures to be used by the ipsec offload.
> 
> v2: ipaddr[] becomes __be32
>     increase the hash table size
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  5 ++++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.h | 40
> ++++++++++++++++++++++++++
>  2 files changed, 45 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
  (?)
@ 2018-01-03 22:30   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:30 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 05/10] ixgbe: add ipsec
> offload add and remove SA
> 
> Add the functions for setting up and removing offloaded SAs (Security
> Associations) with the x540 hardware.  We set up the callback structure but
> we don't yet set the hardware feature bit to be sure the XFRM service won't
> actually try to use us for an offload yet.
> 
> The software tables are made up to mimic the hardware tables to make it
> easier to track what's in the hardware, and the SA table index is used for the
> XFRM offload handle.  However, there is a hashing field in the Rx SA tracking
> that will be used to facilitate faster table searches in the Rx fast path.
> 
> v2: fix use of num_rx_sa that should be num_tx_sa
>     change aes_gcm_name to a const array
>     tighten up the key parsing code
>     add another label to the init error handling
>     move table deletion to a separate function
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       |   2 +
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 394
> ++++++++++++++++++++++++-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |   1 +
>  3 files changed, 396 insertions(+), 1 deletion(-)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 06/10] ixgbe: restore offloaded SAs after a reset
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:30   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:30 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 06/10] ixgbe: restore
> offloaded SAs after a reset
> 
> On a chip reset most of the table contents are lost, so must be restored.  This
> scans the driver's ipsec tables and restores both the filled and empty table
> slots to their pre-reset values.
> 
> v2: during restore, clean the tables before restarting
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  2 ++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 41
> ++++++++++++++++++++++++++
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  1 +
>  3 files changed, 44 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 07/10] ixgbe: process the Rx ipsec offload
  2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:31   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:31 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 07/10] ixgbe: process the Rx
> ipsec offload
> 
> If the chip sees and decrypts an ipsec offload, set up the skb sp pointer with
> the ralated SA info.  Since the chip is rude enough to keep to itself the table
> index it used for the decryption, we have to do our own table lookup, using
> the hash for speed.
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       |  6 ++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 89
> ++++++++++++++++++++++++++
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  3 +
>  3 files changed, 98 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>




^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 08/10] ixgbe: process the Tx ipsec offload
  2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
  (?)
  (?)
@ 2018-01-03 22:32   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:32 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 08/10] ixgbe: process the Tx
> ipsec offload
> 
> If the skb has a security association referenced in the skb, then set up the Tx
> descriptor with the ipsec offload bits.  While we're here, we fix an oddly
> named field in the context descriptor struct.
> 
> v3: added ifdef CONFIG_XFRM_OFFLOAD check around call to
> ixgbe_ipsec_tx()
> 
> v2: use ihl != 5
>     move the ixgbe_ipsec_tx() call to near the call to ixgbe_tso()
>     drop the ipsec packet if the tx offload setup fails
>     simplify the ixgbe_ipsec_tx() parameters by using 'first'
>     leave out the ixgbe_tso() changes since we don't support TSO
>        with ipsec yet.
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h       | 10 +++-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 79
> ++++++++++++++++++++++++++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c   |  4 +-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  | 26 +++++++--
> drivers/net/ethernet/intel/ixgbe/ixgbe_type.h  |  2 +-
>  5 files changed, 112 insertions(+), 9 deletions(-)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 09/10] ixgbe: ipsec offload stats
  2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:32   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:32 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 09/10] ixgbe: ipsec offload
> stats
> 
> Add a simple statistic to count the ipsec offloads.
> 
> v2: change per ring counter to adapter rx and tx counters
>     move tx_ipsec count to the tx clean code
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h         | 2 ++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 2 ++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c   | 2 ++
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    | 5 ++++-
>  4 files changed, 10 insertions(+), 1 deletion(-)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

* [Intel-wired-lan] [PATCH v3 next-queue 10/10] ixgbe: register ipsec offload with the xfrm subsystem
  2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
  (?)
@ 2018-01-03 22:33   ` Bowers, AndrewX
  -1 siblings, 0 replies; 50+ messages in thread
From: Bowers, AndrewX @ 2018-01-03 22:33 UTC (permalink / raw)
  To: intel-wired-lan

> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Shannon Nelson
> Sent: Tuesday, December 19, 2017 4:00 PM
> To: intel-wired-lan at lists.osuosl.org; Kirsher, Jeffrey T
> <jeffrey.t.kirsher@intel.com>
> Cc: steffen.klassert at secunet.com; sowmini.varadhan at oracle.com;
> netdev at vger.kernel.org
> Subject: [Intel-wired-lan] [PATCH v3 next-queue 10/10] ixgbe: register ipsec
> offload with the xfrm subsystem
> 
> With all the support code in place we can now link in the ipsec offload
> operations and set the ESP feature flag for the XFRM subsystem to see.
> 
> v3: added ifdef CONFIG_XFRM_OFFLOAD in ixgbe_features_check
> 
> v2: added the xdo_dev_state_free callback to make XFRM happy
>     changed use of NETIF_F_HW_CSUM_BIT to NETIF_F_HW_CSUM
> 
> Signed-off-by: Shannon Nelson <shannon.nelson@oracle.com>
> ---
>  drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 17 +++++++++++++++++
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c  |  6 ++++++
>  2 files changed, 23 insertions(+)

Tested-by: Andrew Bowers <andrewx.bowers@intel.com>



^ permalink raw reply	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2018-01-03 22:33 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-19 23:59 [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload Shannon Nelson
2017-12-19 23:59 ` [Intel-wired-lan] " Shannon Nelson
2017-12-19 23:59 ` [PATCH v3 next-queue 01/10] ixgbe: clean up ipsec defines Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:27   ` Bowers, AndrewX
2017-12-19 23:59 ` [PATCH v3 next-queue 02/10] ixgbe: add ipsec register access routines Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:28   ` Bowers, AndrewX
2017-12-19 23:59 ` [PATCH v3 next-queue 03/10] ixgbe: add ipsec engine start and stop routines Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:28   ` Bowers, AndrewX
2017-12-19 23:59 ` [PATCH v3 next-queue 04/10] ixgbe: add ipsec data structures Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:29   ` Bowers, AndrewX
2017-12-19 23:59 ` [PATCH v3 next-queue 05/10] ixgbe: add ipsec offload add and remove SA Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2017-12-21  1:17   ` Marcelo Ricardo Leitner
2017-12-21  1:17     ` [Intel-wired-lan] " Marcelo Ricardo Leitner
2017-12-21  1:39     ` Shannon Nelson
2017-12-21  1:39       ` [Intel-wired-lan] " Shannon Nelson
2017-12-21  2:21       ` Marcelo Ricardo Leitner
2017-12-21  2:21         ` [Intel-wired-lan] " Marcelo Ricardo Leitner
2017-12-21  3:30         ` Shannon Nelson
2017-12-21  3:30           ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:30   ` Bowers, AndrewX
2017-12-19 23:59 ` [PATCH v3 next-queue 06/10] ixgbe: restore offloaded SAs after a reset Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:30   ` Bowers, AndrewX
2017-12-19 23:59 ` [PATCH v3 next-queue 07/10] ixgbe: process the Rx ipsec offload Shannon Nelson
2017-12-19 23:59   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:31   ` Bowers, AndrewX
2017-12-20  0:00 ` [PATCH v3 next-queue 08/10] ixgbe: process the Tx " Shannon Nelson
2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
2017-12-22  8:24   ` Yanjun Zhu
2017-12-22  8:24     ` [Intel-wired-lan] " Yanjun Zhu
2017-12-22 22:33     ` Shannon Nelson
2017-12-22 22:33       ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:32   ` Bowers, AndrewX
2017-12-20  0:00 ` [PATCH v3 next-queue 09/10] ixgbe: ipsec offload stats Shannon Nelson
2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:32   ` Bowers, AndrewX
2017-12-20  0:00 ` [PATCH v3 next-queue 10/10] ixgbe: register ipsec offload with the xfrm subsystem Shannon Nelson
2017-12-20  0:00   ` [Intel-wired-lan] " Shannon Nelson
2018-01-03 22:33   ` Bowers, AndrewX
2017-12-21  6:39 ` [PATCH v3 next-queue 00/10] ixgbe: Add ipsec offload Yanjun Zhu
2017-12-21  6:39   ` [Intel-wired-lan] " Yanjun Zhu
2017-12-21  7:09   ` Yanjun Zhu
2017-12-21  7:09     ` [Intel-wired-lan] " Yanjun Zhu
2017-12-21 17:55     ` Shannon Nelson
2017-12-21 17:55       ` [Intel-wired-lan] " Shannon Nelson

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.