* [RFC PATCH net-next 0/3] bonding: support hardware crypto offload
@ 2020-05-04 14:59 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
This is an initial "proof of concept" functional implementation for doing
pass-through of hardware encryption from bonding device to capable slaves.
This was tested using an ixgbe-driven Intel x520 NIC with libreswan and a
transport mode connection, on top of an active-backup bond, using netperf
and downing an interface during. Failover takes a moment, but does work,
and overall performance is right on par with offload when running on a
bare interface.
Caveats: this is ONLY enabled for active-backup, because I'm not sure
how one would manage multiple offload handles for different devices all
running at the same time in the same xfrm, and it relies on some minor
changes to both the xfrm code and slave device driver code to get things
to behave, and I don't have immediate access to any other hardware that
could function similarly to update driver code accordingly.
I'm hoping folks with more of an idea about xfrm have some thoughts on
ways to make this cleaner, and possibly support more bonding modes, but
I'm reasonably happy I've made it this far. :)
Jarod Wilson (3):
xfrm: bail early on slave pass over skb
ixgbe_ipsec: become aware of when running as a bonding slave
bonding: support hardware encryption offload to slaves
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
drivers/net/bonding/bond_main.c | 103 +++++++++++++++++-
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 +++++--
include/net/bonding.h | 1 +
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++---
5 files changed, 150 insertions(+), 28 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next 0/3] bonding: support hardware crypto offload
@ 2020-05-04 14:59 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: intel-wired-lan
This is an initial "proof of concept" functional implementation for doing
pass-through of hardware encryption from bonding device to capable slaves.
This was tested using an ixgbe-driven Intel x520 NIC with libreswan and a
transport mode connection, on top of an active-backup bond, using netperf
and downing an interface during. Failover takes a moment, but does work,
and overall performance is right on par with offload when running on a
bare interface.
Caveats: this is ONLY enabled for active-backup, because I'm not sure
how one would manage multiple offload handles for different devices all
running at the same time in the same xfrm, and it relies on some minor
changes to both the xfrm code and slave device driver code to get things
to behave, and I don't have immediate access to any other hardware that
could function similarly to update driver code accordingly.
I'm hoping folks with more of an idea about xfrm have some thoughts on
ways to make this cleaner, and possibly support more bonding modes, but
I'm reasonably happy I've made it this far. :)
Jarod Wilson (3):
xfrm: bail early on slave pass over skb
ixgbe_ipsec: become aware of when running as a bonding slave
bonding: support hardware encryption offload to slaves
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
drivers/net/bonding/bond_main.c | 103 +++++++++++++++++-
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 +++++--
include/net/bonding.h | 1 +
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++---
5 files changed, 150 insertions(+), 28 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH net-next 1/3] xfrm: bail early on slave pass over skb
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-04 14:59 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
This is prep work for initial support of bonding hardware encryption
pass-through support. The bonding driver will fill in the slave_dev
pointer, and we use that to know not to skb_push() again on a given
skb that was already processed on the bond device.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++++++++++++++++-----------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 8f71c111e65a..a6ec341cd9f0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -127,6 +127,7 @@ struct xfrm_state_walk {
struct xfrm_state_offload {
struct net_device *dev;
+ struct net_device *slave_dev;
unsigned long offload_handle;
unsigned int num_exthdrs;
u8 flags;
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 6cc7f7f1dd68..1cd31dcf59da 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -108,6 +108,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
struct sk_buff *skb2, *nskb, *pskb = NULL;
netdev_features_t esp_features = features;
struct xfrm_offload *xo = xfrm_offload(skb);
+ struct net_device *dev = skb->dev;
struct sec_path *sp;
if (!xo)
@@ -121,6 +122,10 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
return skb;
+ /* This skb was already validated on the master dev */
+ if ((x->xso.dev != dev) && (x->xso.slave_dev == dev))
+ return skb;
+
local_irq_save(flags);
sd = this_cpu_ptr(&softnet_data);
err = !skb_queue_empty(&sd->xfrm_backlog);
@@ -131,25 +136,20 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
return skb;
}
- if (skb_is_gso(skb)) {
- struct net_device *dev = skb->dev;
-
- if (unlikely(x->xso.dev != dev)) {
- struct sk_buff *segs;
+ if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
+ struct sk_buff *segs;
- /* Packet got rerouted, fixup features and segment it. */
- esp_features = esp_features & ~(NETIF_F_HW_ESP
- | NETIF_F_GSO_ESP);
+ /* Packet got rerouted, fixup features and segment it. */
+ esp_features = esp_features & ~(NETIF_F_HW_ESP | NETIF_F_GSO_ESP);
- segs = skb_gso_segment(skb, esp_features);
- if (IS_ERR(segs)) {
- kfree_skb(skb);
- atomic_long_inc(&dev->tx_dropped);
- return NULL;
- } else {
- consume_skb(skb);
- skb = segs;
- }
+ segs = skb_gso_segment(skb, esp_features);
+ if (IS_ERR(segs)) {
+ kfree_skb(skb);
+ atomic_long_inc(&dev->tx_dropped);
+ return NULL;
+ } else {
+ consume_skb(skb);
+ skb = segs;
}
}
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next 1/3] xfrm: bail early on slave pass over skb
@ 2020-05-04 14:59 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: intel-wired-lan
This is prep work for initial support of bonding hardware encryption
pass-through support. The bonding driver will fill in the slave_dev
pointer, and we use that to know not to skb_push() again on a given
skb that was already processed on the bond device.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++++++++++++++++-----------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 8f71c111e65a..a6ec341cd9f0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -127,6 +127,7 @@ struct xfrm_state_walk {
struct xfrm_state_offload {
struct net_device *dev;
+ struct net_device *slave_dev;
unsigned long offload_handle;
unsigned int num_exthdrs;
u8 flags;
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 6cc7f7f1dd68..1cd31dcf59da 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -108,6 +108,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
struct sk_buff *skb2, *nskb, *pskb = NULL;
netdev_features_t esp_features = features;
struct xfrm_offload *xo = xfrm_offload(skb);
+ struct net_device *dev = skb->dev;
struct sec_path *sp;
if (!xo)
@@ -121,6 +122,10 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
return skb;
+ /* This skb was already validated on the master dev */
+ if ((x->xso.dev != dev) && (x->xso.slave_dev == dev))
+ return skb;
+
local_irq_save(flags);
sd = this_cpu_ptr(&softnet_data);
err = !skb_queue_empty(&sd->xfrm_backlog);
@@ -131,25 +136,20 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
return skb;
}
- if (skb_is_gso(skb)) {
- struct net_device *dev = skb->dev;
-
- if (unlikely(x->xso.dev != dev)) {
- struct sk_buff *segs;
+ if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
+ struct sk_buff *segs;
- /* Packet got rerouted, fixup features and segment it. */
- esp_features = esp_features & ~(NETIF_F_HW_ESP
- | NETIF_F_GSO_ESP);
+ /* Packet got rerouted, fixup features and segment it. */
+ esp_features = esp_features & ~(NETIF_F_HW_ESP | NETIF_F_GSO_ESP);
- segs = skb_gso_segment(skb, esp_features);
- if (IS_ERR(segs)) {
- kfree_skb(skb);
- atomic_long_inc(&dev->tx_dropped);
- return NULL;
- } else {
- consume_skb(skb);
- skb = segs;
- }
+ segs = skb_gso_segment(skb, esp_features);
+ if (IS_ERR(segs)) {
+ kfree_skb(skb);
+ atomic_long_inc(&dev->tx_dropped);
+ return NULL;
+ } else {
+ consume_skb(skb);
+ skb = segs;
}
}
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH net-next 2/3] ixgbe_ipsec: become aware of when running as a bonding slave
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-04 14:59 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
Slave devices in a bond doing hardware encryption also need to be aware
that they're slaves, so we operate on the slave instead of the bonding
master to do the actual hardware encryption offload bits.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 +++++++++++++++----
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 113f6087c7c9..26b0a58a064d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -432,6 +432,9 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
char *alg_name = NULL;
int key_len;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
if (!xs->aead) {
netdev_err(dev, "Unsupported IPsec algorithm\n");
return -EINVAL;
@@ -478,8 +481,8 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
{
struct net_device *dev = xs->xso.dev;
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
u32 mfval, manc, reg;
int num_filters = 4;
bool manc_ipv4;
@@ -497,6 +500,12 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
#define BMCIP_V6 0x3
#define BMCIP_MASK 0x3
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ hw = &adapter->hw;
+
manc = IXGBE_READ_REG(hw, IXGBE_MANC);
manc_ipv4 = !!(manc & MANC_EN_IPV4_FILTER);
mfval = IXGBE_READ_REG(hw, IXGBE_MFVAL);
@@ -561,14 +570,21 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
int checked, match, first;
u16 sa_idx;
int ret;
int i;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
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);
@@ -746,12 +762,19 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
u32 zerobuf[4] = {0, 0, 0, 0};
u16 sa_idx;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa *rsa;
u8 ipi;
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next 2/3] ixgbe_ipsec: become aware of when running as a bonding slave
@ 2020-05-04 14:59 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: intel-wired-lan
Slave devices in a bond doing hardware encryption also need to be aware
that they're slaves, so we operate on the slave instead of the bonding
master to do the actual hardware encryption offload bits.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 +++++++++++++++----
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 113f6087c7c9..26b0a58a064d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -432,6 +432,9 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
char *alg_name = NULL;
int key_len;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
if (!xs->aead) {
netdev_err(dev, "Unsupported IPsec algorithm\n");
return -EINVAL;
@@ -478,8 +481,8 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
{
struct net_device *dev = xs->xso.dev;
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
u32 mfval, manc, reg;
int num_filters = 4;
bool manc_ipv4;
@@ -497,6 +500,12 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
#define BMCIP_V6 0x3
#define BMCIP_MASK 0x3
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ hw = &adapter->hw;
+
manc = IXGBE_READ_REG(hw, IXGBE_MANC);
manc_ipv4 = !!(manc & MANC_EN_IPV4_FILTER);
mfval = IXGBE_READ_REG(hw, IXGBE_MFVAL);
@@ -561,14 +570,21 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
int checked, match, first;
u16 sa_idx;
int ret;
int i;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
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);
@@ -746,12 +762,19 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
u32 zerobuf[4] = {0, 0, 0, 0};
u16 sa_idx;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa *rsa;
u8 ipi;
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH net-next 3/3] bonding: support hardware encryption offload to slaves
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-04 14:59 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
Currently, this support is limited to active-backup mode, as I'm not sure
about the feasilibity of mapping an xfrm_state's offload handle to
multiple hardware devices simultaneously, and we rely on being able to
pass some hints to both the xfrm and NIC driver about whether or not
they're operating on a slave device.
I've tested this atop an Intel x520 device (ixgbe) using libreswan in
transport mode, succesfully achieving ~4.3Gbps throughput with netperf
(more or less identical to throughput on a bare NIC in this system),
as well as successful failover and recovery mid-netperf.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/net/bonding/bond_main.c | 103 +++++++++++++++++++++++++++++++-
include/net/bonding.h | 1 +
2 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2e70e43c5df5..781da5beb484 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_dissector.h>
+#include <net/xfrm.h>
#include <net/bonding.h>
#include <net/bond_3ad.h>
#include <net/bond_alb.h>
@@ -278,8 +279,6 @@ const char *bond_mode_name(int mode)
return names[mode];
}
-/*---------------------------------- VLAN -----------------------------------*/
-
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
@@ -302,6 +301,8 @@ void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
dev_queue_xmit(skb);
}
+/*---------------------------------- VLAN -----------------------------------*/
+
/* In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
* We don't protect the slave list iteration with a lock because:
* a. This operation is performed in IOCTL context,
@@ -372,6 +373,82 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
return 0;
}
+/*---------------------------------- XFRM -----------------------------------*/
+
+/**
+ * bond_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int bond_ipsec_add_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ xs->xso.slave_dev = slave->dev;
+ bond->xs = xs;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
+ slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+ return -EINVAL;
+ }
+
+ return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+}
+
+/**
+ * bond_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void bond_ipsec_del_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ if (!slave)
+ return;
+
+ xs->xso.slave_dev = slave->dev;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
+ slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+ return;
+ }
+
+ slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+}
+
+/**
+ * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
+ struct net_device *slave_dev = curr_active->dev;
+
+ if (!(slave_dev->xfrmdev_ops
+ && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
+ slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
+ return false;
+ }
+
+ xs->xso.slave_dev = slave_dev;
+ return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+}
+
+static const struct xfrmdev_ops bond_xfrmdev_ops = {
+ .xdo_dev_state_add = bond_ipsec_add_sa,
+ .xdo_dev_state_delete = bond_ipsec_del_sa,
+ .xdo_dev_offload_ok = bond_ipsec_offload_ok,
+};
+
/*------------------------------- Link status -------------------------------*/
/* Set the carrier state for the master according to the state of its
@@ -878,6 +955,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (old_active == new_active)
return;
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) && bond->xs)
+ bond_ipsec_del_sa(bond->xs);
+
if (new_active) {
new_active->last_link_up = jiffies;
@@ -941,6 +1021,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_should_notify_peers(bond);
}
+ if (old_active && bond->xs) {
+ xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true);
+ bond_ipsec_add_sa(bond->xs);
+ }
+
call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
if (should_notify_peers) {
bond->send_peer_notif--;
@@ -1125,7 +1210,9 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
NETIF_F_HIGHDMA | NETIF_F_LRO)
#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
- NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
+ NETIF_F_RXCSUM | NETIF_F_ALL_TSO | \
+ NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \
+ NETIF_F_GSO_ESP)
#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_ALL_TSO)
@@ -1464,6 +1551,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
slave_dbg(bond_dev, slave_dev, "is !NETIF_F_VLAN_CHALLENGED\n");
}
+ if (slave_dev->features & NETIF_F_HW_ESP)
+ slave_dbg(bond_dev, slave_dev, "is esp-hw-offload capable\n");
+
/* Old ifenslave binaries are no longer supported. These can
* be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
@@ -4444,6 +4534,11 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT | IFF_NO_QUEUE;
bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+ /* set up xfrm device ops (only supported in active-backup right now */
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
+ bond->xs = NULL;
+
/* don't acquire bond device's netif_tx_lock when transmitting */
bond_dev->features |= NETIF_F_LLTX;
@@ -4462,6 +4557,8 @@ void bond_setup(struct net_device *bond_dev)
NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->hw_features |= BOND_ENC_FEATURES;
bond_dev->features |= bond_dev->hw_features;
bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
}
diff --git a/include/net/bonding.h b/include/net/bonding.h
index dc2ce31a1f52..854b46511bd8 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -238,6 +238,7 @@ struct bonding {
#endif /* CONFIG_DEBUG_FS */
struct rtnl_link_stats64 bond_stats;
struct lock_class_key stats_lock_key;
+ struct xfrm_state *xs;
};
#define bond_slave_get_rcu(dev) \
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next 3/3] bonding: support hardware encryption offload to slaves
@ 2020-05-04 14:59 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-04 14:59 UTC (permalink / raw)
To: intel-wired-lan
Currently, this support is limited to active-backup mode, as I'm not sure
about the feasilibity of mapping an xfrm_state's offload handle to
multiple hardware devices simultaneously, and we rely on being able to
pass some hints to both the xfrm and NIC driver about whether or not
they're operating on a slave device.
I've tested this atop an Intel x520 device (ixgbe) using libreswan in
transport mode, succesfully achieving ~4.3Gbps throughput with netperf
(more or less identical to throughput on a bare NIC in this system),
as well as successful failover and recovery mid-netperf.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/net/bonding/bond_main.c | 103 +++++++++++++++++++++++++++++++-
include/net/bonding.h | 1 +
2 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2e70e43c5df5..781da5beb484 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_dissector.h>
+#include <net/xfrm.h>
#include <net/bonding.h>
#include <net/bond_3ad.h>
#include <net/bond_alb.h>
@@ -278,8 +279,6 @@ const char *bond_mode_name(int mode)
return names[mode];
}
-/*---------------------------------- VLAN -----------------------------------*/
-
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
@@ -302,6 +301,8 @@ void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
dev_queue_xmit(skb);
}
+/*---------------------------------- VLAN -----------------------------------*/
+
/* In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
* We don't protect the slave list iteration with a lock because:
* a. This operation is performed in IOCTL context,
@@ -372,6 +373,82 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
return 0;
}
+/*---------------------------------- XFRM -----------------------------------*/
+
+/**
+ * bond_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int bond_ipsec_add_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ xs->xso.slave_dev = slave->dev;
+ bond->xs = xs;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
+ slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+ return -EINVAL;
+ }
+
+ return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+}
+
+/**
+ * bond_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void bond_ipsec_del_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ if (!slave)
+ return;
+
+ xs->xso.slave_dev = slave->dev;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
+ slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+ return;
+ }
+
+ slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+}
+
+/**
+ * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
+ struct net_device *slave_dev = curr_active->dev;
+
+ if (!(slave_dev->xfrmdev_ops
+ && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
+ slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
+ return false;
+ }
+
+ xs->xso.slave_dev = slave_dev;
+ return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+}
+
+static const struct xfrmdev_ops bond_xfrmdev_ops = {
+ .xdo_dev_state_add = bond_ipsec_add_sa,
+ .xdo_dev_state_delete = bond_ipsec_del_sa,
+ .xdo_dev_offload_ok = bond_ipsec_offload_ok,
+};
+
/*------------------------------- Link status -------------------------------*/
/* Set the carrier state for the master according to the state of its
@@ -878,6 +955,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (old_active == new_active)
return;
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) && bond->xs)
+ bond_ipsec_del_sa(bond->xs);
+
if (new_active) {
new_active->last_link_up = jiffies;
@@ -941,6 +1021,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_should_notify_peers(bond);
}
+ if (old_active && bond->xs) {
+ xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true);
+ bond_ipsec_add_sa(bond->xs);
+ }
+
call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
if (should_notify_peers) {
bond->send_peer_notif--;
@@ -1125,7 +1210,9 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
NETIF_F_HIGHDMA | NETIF_F_LRO)
#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
- NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
+ NETIF_F_RXCSUM | NETIF_F_ALL_TSO | \
+ NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \
+ NETIF_F_GSO_ESP)
#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_ALL_TSO)
@@ -1464,6 +1551,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
slave_dbg(bond_dev, slave_dev, "is !NETIF_F_VLAN_CHALLENGED\n");
}
+ if (slave_dev->features & NETIF_F_HW_ESP)
+ slave_dbg(bond_dev, slave_dev, "is esp-hw-offload capable\n");
+
/* Old ifenslave binaries are no longer supported. These can
* be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
@@ -4444,6 +4534,11 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT | IFF_NO_QUEUE;
bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+ /* set up xfrm device ops (only supported in active-backup right now */
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
+ bond->xs = NULL;
+
/* don't acquire bond device's netif_tx_lock when transmitting */
bond_dev->features |= NETIF_F_LLTX;
@@ -4462,6 +4557,8 @@ void bond_setup(struct net_device *bond_dev)
NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->hw_features |= BOND_ENC_FEATURES;
bond_dev->features |= bond_dev->hw_features;
bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
}
diff --git a/include/net/bonding.h b/include/net/bonding.h
index dc2ce31a1f52..854b46511bd8 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -238,6 +238,7 @@ struct bonding {
#endif /* CONFIG_DEBUG_FS */
struct rtnl_link_stats64 bond_stats;
struct lock_class_key stats_lock_key;
+ struct xfrm_state *xs;
};
#define bond_slave_get_rcu(dev) \
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [RFC PATCH net-next 3/3] bonding: support hardware encryption offload to slaves
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
(?)
@ 2020-05-05 13:30 ` kbuild test robot
-1 siblings, 0 replies; 18+ messages in thread
From: kbuild test robot @ 2020-05-05 13:30 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 8949 bytes --]
Hi Jarod,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on ipsec-next/master]
[also build test ERROR on ipsec/master linus/master linux/master v5.7-rc4]
[cannot apply to net-next/master next-20200505]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Jarod-Wilson/bonding-support-hardware-crypto-offload/20200505-075314
base: https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
config: x86_64-rhel (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_add_sa':
>> drivers/net/bonding/bond_main.c:391:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c:392:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c:397:21: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_del_sa':
drivers/net/bonding/bond_main.c:415:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c:416:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c:421:14: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_offload_ok':
drivers/net/bonding/bond_main.c:436:19: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave_dev->xfrmdev_ops
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c:437:22: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c:443:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c: At top level:
>> drivers/net/bonding/bond_main.c:446:21: error: variable 'bond_xfrmdev_ops' has initializer but incomplete type
static const struct xfrmdev_ops bond_xfrmdev_ops = {
^~~~~~~~~~~
>> drivers/net/bonding/bond_main.c:447:3: error: 'const struct xfrmdev_ops' has no member named 'xdo_dev_state_add'
.xdo_dev_state_add = bond_ipsec_add_sa,
^~~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:447:23: warning: excess elements in struct initializer
.xdo_dev_state_add = bond_ipsec_add_sa,
^~~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:447:23: note: (near initialization for 'bond_xfrmdev_ops')
>> drivers/net/bonding/bond_main.c:448:3: error: 'const struct xfrmdev_ops' has no member named 'xdo_dev_state_delete'
.xdo_dev_state_delete = bond_ipsec_del_sa,
^~~~~~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:448:26: warning: excess elements in struct initializer
.xdo_dev_state_delete = bond_ipsec_del_sa,
^~~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:448:26: note: (near initialization for 'bond_xfrmdev_ops')
>> drivers/net/bonding/bond_main.c:449:3: error: 'const struct xfrmdev_ops' has no member named 'xdo_dev_offload_ok'
.xdo_dev_offload_ok = bond_ipsec_offload_ok,
^~~~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:449:24: warning: excess elements in struct initializer
.xdo_dev_offload_ok = bond_ipsec_offload_ok,
^~~~~~~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:449:24: note: (near initialization for 'bond_xfrmdev_ops')
drivers/net/bonding/bond_main.c: In function 'bond_setup':
drivers/net/bonding/bond_main.c:4539:13: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
^~~~~~~~~~~
l3mdev_ops
drivers/net/bonding/bond_main.c: At top level:
>> drivers/net/bonding/bond_main.c:446:33: error: storage size of 'bond_xfrmdev_ops' isn't known
static const struct xfrmdev_ops bond_xfrmdev_ops = {
^~~~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_add_sa':
>> drivers/net/bonding/bond_main.c:398:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
vim +391 drivers/net/bonding/bond_main.c
377
378 /**
379 * bond_ipsec_add_sa - program device with a security association
380 * @xs: pointer to transformer state struct
381 **/
382 static int bond_ipsec_add_sa(struct xfrm_state *xs)
383 {
384 struct net_device *bond_dev = xs->xso.dev;
385 struct bonding *bond = netdev_priv(bond_dev);
386 struct slave *slave = rtnl_dereference(bond->curr_active_slave);
387
388 xs->xso.slave_dev = slave->dev;
389 bond->xs = xs;
390
> 391 if (!(slave->dev->xfrmdev_ops
392 && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
393 slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
394 return -EINVAL;
395 }
396
397 return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
> 398 }
399
400 /**
401 * bond_ipsec_del_sa - clear out this specific SA
402 * @xs: pointer to transformer state struct
403 **/
404 static void bond_ipsec_del_sa(struct xfrm_state *xs)
405 {
406 struct net_device *bond_dev = xs->xso.dev;
407 struct bonding *bond = netdev_priv(bond_dev);
408 struct slave *slave = rtnl_dereference(bond->curr_active_slave);
409
410 if (!slave)
411 return;
412
413 xs->xso.slave_dev = slave->dev;
414
415 if (!(slave->dev->xfrmdev_ops
416 && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
417 slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
418 return;
419 }
420
421 slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
422 }
423
424 /**
425 * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
426 * @skb: current data packet
427 * @xs: pointer to transformer state struct
428 **/
429 static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
430 {
431 struct net_device *bond_dev = xs->xso.dev;
432 struct bonding *bond = netdev_priv(bond_dev);
433 struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
434 struct net_device *slave_dev = curr_active->dev;
435
436 if (!(slave_dev->xfrmdev_ops
> 437 && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
438 slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
439 return false;
440 }
441
442 xs->xso.slave_dev = slave_dev;
> 443 return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
444 }
445
> 446 static const struct xfrmdev_ops bond_xfrmdev_ops = {
> 447 .xdo_dev_state_add = bond_ipsec_add_sa,
> 448 .xdo_dev_state_delete = bond_ipsec_del_sa,
> 449 .xdo_dev_offload_ok = bond_ipsec_offload_ok,
450 };
451
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 44868 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [RFC PATCH net-next 3/3] bonding: support hardware encryption offload to slaves
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
(?)
(?)
@ 2020-05-05 14:36 ` kbuild test robot
-1 siblings, 0 replies; 18+ messages in thread
From: kbuild test robot @ 2020-05-05 14:36 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 11960 bytes --]
Hi Jarod,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on ipsec-next/master]
[also build test WARNING on ipsec/master linus/master linux/master v5.7-rc4]
[cannot apply to net-next/master next-20200505]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Jarod-Wilson/bonding-support-hardware-crypto-offload/20200505-075314
base: https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
config: x86_64-randconfig-d002-20200503 (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
In file included from include/linux/export.h:43:0,
from include/linux/linkage.h:7,
from include/linux/kernel.h:8,
from drivers/net/bonding/bond_main.c:34:
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_add_sa':
drivers/net/bonding/bond_main.c:391:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
>> drivers/net/bonding/bond_main.c:391:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:392:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
^
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
>> drivers/net/bonding/bond_main.c:391:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:391:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^
include/linux/compiler.h:58:61: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
>> drivers/net/bonding/bond_main.c:391:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:392:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
^
include/linux/compiler.h:58:61: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
>> drivers/net/bonding/bond_main.c:391:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:391:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^
include/linux/compiler.h:69:3: note: in definition of macro '__trace_if_value'
(cond) ? \
^~~~
include/linux/compiler.h:56:28: note: in expansion of macro '__trace_if_var'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~~~~~~~~~~~
>> drivers/net/bonding/bond_main.c:391:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:392:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
^
include/linux/compiler.h:69:3: note: in definition of macro '__trace_if_value'
(cond) ? \
^~~~
include/linux/compiler.h:56:28: note: in expansion of macro '__trace_if_var'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~~~~~~~~~~~
>> drivers/net/bonding/bond_main.c:391:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:397:21: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
^~~~~~~~~~~
l3mdev_ops
In file included from include/linux/export.h:43:0,
from include/linux/linkage.h:7,
from include/linux/kernel.h:8,
from drivers/net/bonding/bond_main.c:34:
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_del_sa':
drivers/net/bonding/bond_main.c:415:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
drivers/net/bonding/bond_main.c:415:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:416:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
^
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
drivers/net/bonding/bond_main.c:415:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:415:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^
include/linux/compiler.h:58:61: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
drivers/net/bonding/bond_main.c:415:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:416:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
^
include/linux/compiler.h:58:61: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
drivers/net/bonding/bond_main.c:415:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:415:20: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave->dev->xfrmdev_ops
^
include/linux/compiler.h:69:3: note: in definition of macro '__trace_if_value'
(cond) ? \
^~~~
include/linux/compiler.h:56:28: note: in expansion of macro '__trace_if_var'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:415:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:416:23: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
^
include/linux/compiler.h:69:3: note: in definition of macro '__trace_if_value'
(cond) ? \
^~~~
include/linux/compiler.h:56:28: note: in expansion of macro '__trace_if_var'
#define if(cond, ...) if ( __trace_if_var( !!(cond , ## __VA_ARGS__) ) )
^~~~~~~~~~~~~~
drivers/net/bonding/bond_main.c:415:2: note: in expansion of macro 'if'
if (!(slave->dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:421:14: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
^~~~~~~~~~~
l3mdev_ops
In file included from include/linux/export.h:43:0,
from include/linux/linkage.h:7,
from include/linux/kernel.h:8,
from drivers/net/bonding/bond_main.c:34:
drivers/net/bonding/bond_main.c: In function 'bond_ipsec_offload_ok':
drivers/net/bonding/bond_main.c:436:19: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave_dev->xfrmdev_ops
^
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
drivers/net/bonding/bond_main.c:436:2: note: in expansion of macro 'if'
if (!(slave_dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:437:22: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
&& slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
^
include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
#define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
^~~~
drivers/net/bonding/bond_main.c:436:2: note: in expansion of macro 'if'
if (!(slave_dev->xfrmdev_ops
^~
drivers/net/bonding/bond_main.c:436:19: error: 'struct net_device' has no member named 'xfrmdev_ops'; did you mean 'l3mdev_ops'?
if (!(slave_dev->xfrmdev_ops
vim +/if +391 drivers/net/bonding/bond_main.c
377
378 /**
379 * bond_ipsec_add_sa - program device with a security association
380 * @xs: pointer to transformer state struct
381 **/
382 static int bond_ipsec_add_sa(struct xfrm_state *xs)
383 {
384 struct net_device *bond_dev = xs->xso.dev;
385 struct bonding *bond = netdev_priv(bond_dev);
386 struct slave *slave = rtnl_dereference(bond->curr_active_slave);
387
388 xs->xso.slave_dev = slave->dev;
389 bond->xs = xs;
390
> 391 if (!(slave->dev->xfrmdev_ops
392 && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
393 slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
394 return -EINVAL;
395 }
396
397 return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
398 }
399
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 40633 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH net-next v2 0/3] bonding: support hardware crypto offload
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-05 22:58 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
This is an initial "proof of concept" functional implementation for doing
pass-through of hardware encryption from bonding device to capable slaves.
This was tested using an ixgbe-driven Intel x520 NIC with libreswan and a
transport mode connection, on top of an active-backup bond, using netperf
and downing an interface during. Failover takes a moment, but does work,
and overall performance is right on par with offload when running on a
bare interface.
Caveats: this is ONLY enabled for active-backup, because I'm not sure
how one would manage multiple offload handles for different devices all
running at the same time in the same xfrm, and it relies on some minor
changes to both the xfrm code and slave device driver code to get things
to behave, and I don't have immediate access to any other hardware that
could function similarly to update driver code accordingly.
I'm hoping folks with more of an idea about xfrm have some thoughts on
ways to make this cleaner, and possibly support more bonding modes, but
I'm reasonably happy I've made it this far. :)
v2: fix build with CONFIG_XFRM_OFFLOAD disabled and rebase on latest
net-next tree bonding changes
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Jarod Wilson (3):
xfrm: bail early on slave pass over skb
ixgbe_ipsec: become aware of when running as a bonding slave
bonding: support hardware encryption offload to slaves
drivers/net/bonding/bond_main.c | 111 +++++++++++++++++-
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 ++++--
include/net/bonding.h | 3 +
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++---
5 files changed, 160 insertions(+), 28 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next v2 0/3] bonding: support hardware crypto offload
@ 2020-05-05 22:58 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: intel-wired-lan
This is an initial "proof of concept" functional implementation for doing
pass-through of hardware encryption from bonding device to capable slaves.
This was tested using an ixgbe-driven Intel x520 NIC with libreswan and a
transport mode connection, on top of an active-backup bond, using netperf
and downing an interface during. Failover takes a moment, but does work,
and overall performance is right on par with offload when running on a
bare interface.
Caveats: this is ONLY enabled for active-backup, because I'm not sure
how one would manage multiple offload handles for different devices all
running at the same time in the same xfrm, and it relies on some minor
changes to both the xfrm code and slave device driver code to get things
to behave, and I don't have immediate access to any other hardware that
could function similarly to update driver code accordingly.
I'm hoping folks with more of an idea about xfrm have some thoughts on
ways to make this cleaner, and possibly support more bonding modes, but
I'm reasonably happy I've made it this far. :)
v2: fix build with CONFIG_XFRM_OFFLOAD disabled and rebase on latest
net-next tree bonding changes
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Jarod Wilson (3):
xfrm: bail early on slave pass over skb
ixgbe_ipsec: become aware of when running as a bonding slave
bonding: support hardware encryption offload to slaves
drivers/net/bonding/bond_main.c | 111 +++++++++++++++++-
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 ++++--
include/net/bonding.h | 3 +
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++---
5 files changed, 160 insertions(+), 28 deletions(-)
--
2.20.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [RFC PATCH net-next v2 1/3] xfrm: bail early on slave pass over skb
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-05 22:58 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
This is prep work for initial support of bonding hardware encryption
pass-through support. The bonding driver will fill in the slave_dev
pointer, and we use that to know not to skb_push() again on a given
skb that was already processed on the bond device.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++++++++++++++++-----------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 8f71c111e65a..a6ec341cd9f0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -127,6 +127,7 @@ struct xfrm_state_walk {
struct xfrm_state_offload {
struct net_device *dev;
+ struct net_device *slave_dev;
unsigned long offload_handle;
unsigned int num_exthdrs;
u8 flags;
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 6cc7f7f1dd68..1cd31dcf59da 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -108,6 +108,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
struct sk_buff *skb2, *nskb, *pskb = NULL;
netdev_features_t esp_features = features;
struct xfrm_offload *xo = xfrm_offload(skb);
+ struct net_device *dev = skb->dev;
struct sec_path *sp;
if (!xo)
@@ -121,6 +122,10 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
return skb;
+ /* This skb was already validated on the master dev */
+ if ((x->xso.dev != dev) && (x->xso.slave_dev == dev))
+ return skb;
+
local_irq_save(flags);
sd = this_cpu_ptr(&softnet_data);
err = !skb_queue_empty(&sd->xfrm_backlog);
@@ -131,25 +136,20 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
return skb;
}
- if (skb_is_gso(skb)) {
- struct net_device *dev = skb->dev;
-
- if (unlikely(x->xso.dev != dev)) {
- struct sk_buff *segs;
+ if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
+ struct sk_buff *segs;
- /* Packet got rerouted, fixup features and segment it. */
- esp_features = esp_features & ~(NETIF_F_HW_ESP
- | NETIF_F_GSO_ESP);
+ /* Packet got rerouted, fixup features and segment it. */
+ esp_features = esp_features & ~(NETIF_F_HW_ESP | NETIF_F_GSO_ESP);
- segs = skb_gso_segment(skb, esp_features);
- if (IS_ERR(segs)) {
- kfree_skb(skb);
- atomic_long_inc(&dev->tx_dropped);
- return NULL;
- } else {
- consume_skb(skb);
- skb = segs;
- }
+ segs = skb_gso_segment(skb, esp_features);
+ if (IS_ERR(segs)) {
+ kfree_skb(skb);
+ atomic_long_inc(&dev->tx_dropped);
+ return NULL;
+ } else {
+ consume_skb(skb);
+ skb = segs;
}
}
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next v2 1/3] xfrm: bail early on slave pass over skb
@ 2020-05-05 22:58 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: intel-wired-lan
This is prep work for initial support of bonding hardware encryption
pass-through support. The bonding driver will fill in the slave_dev
pointer, and we use that to know not to skb_push() again on a given
skb that was already processed on the bond device.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
include/net/xfrm.h | 1 +
net/xfrm/xfrm_device.c | 34 +++++++++++++++++-----------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 8f71c111e65a..a6ec341cd9f0 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -127,6 +127,7 @@ struct xfrm_state_walk {
struct xfrm_state_offload {
struct net_device *dev;
+ struct net_device *slave_dev;
unsigned long offload_handle;
unsigned int num_exthdrs;
u8 flags;
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 6cc7f7f1dd68..1cd31dcf59da 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -108,6 +108,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
struct sk_buff *skb2, *nskb, *pskb = NULL;
netdev_features_t esp_features = features;
struct xfrm_offload *xo = xfrm_offload(skb);
+ struct net_device *dev = skb->dev;
struct sec_path *sp;
if (!xo)
@@ -121,6 +122,10 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND)
return skb;
+ /* This skb was already validated on the master dev */
+ if ((x->xso.dev != dev) && (x->xso.slave_dev == dev))
+ return skb;
+
local_irq_save(flags);
sd = this_cpu_ptr(&softnet_data);
err = !skb_queue_empty(&sd->xfrm_backlog);
@@ -131,25 +136,20 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
return skb;
}
- if (skb_is_gso(skb)) {
- struct net_device *dev = skb->dev;
-
- if (unlikely(x->xso.dev != dev)) {
- struct sk_buff *segs;
+ if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
+ struct sk_buff *segs;
- /* Packet got rerouted, fixup features and segment it. */
- esp_features = esp_features & ~(NETIF_F_HW_ESP
- | NETIF_F_GSO_ESP);
+ /* Packet got rerouted, fixup features and segment it. */
+ esp_features = esp_features & ~(NETIF_F_HW_ESP | NETIF_F_GSO_ESP);
- segs = skb_gso_segment(skb, esp_features);
- if (IS_ERR(segs)) {
- kfree_skb(skb);
- atomic_long_inc(&dev->tx_dropped);
- return NULL;
- } else {
- consume_skb(skb);
- skb = segs;
- }
+ segs = skb_gso_segment(skb, esp_features);
+ if (IS_ERR(segs)) {
+ kfree_skb(skb);
+ atomic_long_inc(&dev->tx_dropped);
+ return NULL;
+ } else {
+ consume_skb(skb);
+ skb = segs;
}
}
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH net-next v2 2/3] ixgbe_ipsec: become aware of when running as a bonding slave
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-05 22:58 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
Slave devices in a bond doing hardware encryption also need to be aware
that they're slaves, so we operate on the slave instead of the bonding
master to do the actual hardware encryption offload bits.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 +++++++++++++++----
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 113f6087c7c9..26b0a58a064d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -432,6 +432,9 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
char *alg_name = NULL;
int key_len;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
if (!xs->aead) {
netdev_err(dev, "Unsupported IPsec algorithm\n");
return -EINVAL;
@@ -478,8 +481,8 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
{
struct net_device *dev = xs->xso.dev;
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
u32 mfval, manc, reg;
int num_filters = 4;
bool manc_ipv4;
@@ -497,6 +500,12 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
#define BMCIP_V6 0x3
#define BMCIP_MASK 0x3
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ hw = &adapter->hw;
+
manc = IXGBE_READ_REG(hw, IXGBE_MANC);
manc_ipv4 = !!(manc & MANC_EN_IPV4_FILTER);
mfval = IXGBE_READ_REG(hw, IXGBE_MFVAL);
@@ -561,14 +570,21 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
int checked, match, first;
u16 sa_idx;
int ret;
int i;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
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);
@@ -746,12 +762,19 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
u32 zerobuf[4] = {0, 0, 0, 0};
u16 sa_idx;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa *rsa;
u8 ipi;
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next v2 2/3] ixgbe_ipsec: become aware of when running as a bonding slave
@ 2020-05-05 22:58 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: intel-wired-lan
Slave devices in a bond doing hardware encryption also need to be aware
that they're slaves, so we operate on the slave instead of the bonding
master to do the actual hardware encryption offload bits.
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
.../net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 39 +++++++++++++++----
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 113f6087c7c9..26b0a58a064d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -432,6 +432,9 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
char *alg_name = NULL;
int key_len;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
if (!xs->aead) {
netdev_err(dev, "Unsupported IPsec algorithm\n");
return -EINVAL;
@@ -478,8 +481,8 @@ static int ixgbe_ipsec_parse_proto_keys(struct xfrm_state *xs,
static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
{
struct net_device *dev = xs->xso.dev;
- struct ixgbe_adapter *adapter = netdev_priv(dev);
- struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
u32 mfval, manc, reg;
int num_filters = 4;
bool manc_ipv4;
@@ -497,6 +500,12 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
#define BMCIP_V6 0x3
#define BMCIP_MASK 0x3
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ hw = &adapter->hw;
+
manc = IXGBE_READ_REG(hw, IXGBE_MANC);
manc_ipv4 = !!(manc & MANC_EN_IPV4_FILTER);
mfval = IXGBE_READ_REG(hw, IXGBE_MFVAL);
@@ -561,14 +570,21 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
int checked, match, first;
u16 sa_idx;
int ret;
int i;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
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);
@@ -746,12 +762,19 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
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;
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_ipsec *ipsec;
+ struct ixgbe_hw *hw;
u32 zerobuf[4] = {0, 0, 0, 0};
u16 sa_idx;
+ if (xs->xso.slave_dev)
+ dev = xs->xso.slave_dev;
+
+ adapter = netdev_priv(dev);
+ ipsec = adapter->ipsec;
+ hw = &adapter->hw;
+
if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
struct rx_sa *rsa;
u8 ipi;
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [RFC PATCH net-next v2 3/3] bonding: support hardware encryption offload to slaves
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
@ 2020-05-05 22:58 ` Jarod Wilson
-1 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: linux-kernel
Cc: Jarod Wilson, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, Jeff Kirsher, Jakub Kicinski, Steffen Klassert,
Herbert Xu, netdev, intel-wired-lan
Currently, this support is limited to active-backup mode, as I'm not sure
about the feasilibity of mapping an xfrm_state's offload handle to
multiple hardware devices simultaneously, and we rely on being able to
pass some hints to both the xfrm and NIC driver about whether or not
they're operating on a slave device.
I've tested this atop an Intel x520 device (ixgbe) using libreswan in
transport mode, succesfully achieving ~4.3Gbps throughput with netperf
(more or less identical to throughput on a bare NIC in this system),
as well as successful failover and recovery mid-netperf.
v2: rebase on latest net-next and wrap with #ifdef CONFIG_XFRM_OFFLOAD
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev@vger.kernel.org
CC: intel-wired-lan@lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/net/bonding/bond_main.c | 111 +++++++++++++++++++++++++++++++-
include/net/bonding.h | 3 +
2 files changed, 111 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index baa93191dfdd..b90a86029df5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_dissector.h>
+#include <net/xfrm.h>
#include <net/bonding.h>
#include <net/bond_3ad.h>
#include <net/bond_alb.h>
@@ -278,8 +279,6 @@ const char *bond_mode_name(int mode)
return names[mode];
}
-/*---------------------------------- VLAN -----------------------------------*/
-
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
@@ -302,6 +301,8 @@ void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
dev_queue_xmit(skb);
}
+/*---------------------------------- VLAN -----------------------------------*/
+
/* In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
* We don't protect the slave list iteration with a lock because:
* a. This operation is performed in IOCTL context,
@@ -372,6 +373,84 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
return 0;
}
+/*---------------------------------- XFRM -----------------------------------*/
+
+#ifdef CONFIG_XFRM_OFFLOAD
+/**
+ * bond_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int bond_ipsec_add_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ xs->xso.slave_dev = slave->dev;
+ bond->xs = xs;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
+ slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+ return -EINVAL;
+ }
+
+ return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+}
+
+/**
+ * bond_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void bond_ipsec_del_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ if (!slave)
+ return;
+
+ xs->xso.slave_dev = slave->dev;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
+ slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+ return;
+ }
+
+ slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+}
+
+/**
+ * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
+ struct net_device *slave_dev = curr_active->dev;
+
+ if (!(slave_dev->xfrmdev_ops
+ && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
+ slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
+ return false;
+ }
+
+ xs->xso.slave_dev = slave_dev;
+ return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+}
+
+static const struct xfrmdev_ops bond_xfrmdev_ops = {
+ .xdo_dev_state_add = bond_ipsec_add_sa,
+ .xdo_dev_state_delete = bond_ipsec_del_sa,
+ .xdo_dev_offload_ok = bond_ipsec_offload_ok,
+};
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/*------------------------------- Link status -------------------------------*/
/* Set the carrier state for the master according to the state of its
@@ -878,6 +957,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (old_active == new_active)
return;
+#ifdef CONFIG_XFRM_OFFLOAD
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) && bond->xs)
+ bond_ipsec_del_sa(bond->xs);
+#endif /* CONFIG_XFRM_OFFLOAD */
+
if (new_active) {
new_active->last_link_up = jiffies;
@@ -941,6 +1025,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_should_notify_peers(bond);
}
+#ifdef CONFIG_XFRM_OFFLOAD
+ if (old_active && bond->xs) {
+ xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true);
+ bond_ipsec_add_sa(bond->xs);
+ }
+#endif /* CONFIG_XFRM_OFFLOAD */
+
call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
if (should_notify_peers) {
bond->send_peer_notif--;
@@ -1125,7 +1216,9 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
NETIF_F_HIGHDMA | NETIF_F_LRO)
#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
- NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
+ NETIF_F_RXCSUM | NETIF_F_ALL_TSO | \
+ NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \
+ NETIF_F_GSO_ESP)
#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_ALL_TSO)
@@ -1464,6 +1557,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
slave_dbg(bond_dev, slave_dev, "is !NETIF_F_VLAN_CHALLENGED\n");
}
+ if (slave_dev->features & NETIF_F_HW_ESP)
+ slave_dbg(bond_dev, slave_dev, "is esp-hw-offload capable\n");
+
/* Old ifenslave binaries are no longer supported. These can
* be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
@@ -4444,6 +4540,13 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT | IFF_NO_QUEUE;
bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+#ifdef CONFIG_XFRM_OFFLOAD
+ /* set up xfrm device ops (only supported in active-backup right now */
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
+ bond->xs = NULL;
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/* don't acquire bond device's netif_tx_lock when transmitting */
bond_dev->features |= NETIF_F_LLTX;
@@ -4462,6 +4565,8 @@ void bond_setup(struct net_device *bond_dev)
NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->hw_features |= BOND_ENC_FEATURES;
bond_dev->features |= bond_dev->hw_features;
bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
}
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 0b696da5c115..4ca178b2d0e2 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -237,6 +237,9 @@ struct bonding {
struct dentry *debug_dir;
#endif /* CONFIG_DEBUG_FS */
struct rtnl_link_stats64 bond_stats;
+#ifdef CONFIG_XFRM_OFFLOAD
+ struct xfrm_state *xs;
+#endif /* CONFIG_XFRM_OFFLOAD */
};
#define bond_slave_get_rcu(dev) \
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Intel-wired-lan] [RFC PATCH net-next v2 3/3] bonding: support hardware encryption offload to slaves
@ 2020-05-05 22:58 ` Jarod Wilson
0 siblings, 0 replies; 18+ messages in thread
From: Jarod Wilson @ 2020-05-05 22:58 UTC (permalink / raw)
To: intel-wired-lan
Currently, this support is limited to active-backup mode, as I'm not sure
about the feasilibity of mapping an xfrm_state's offload handle to
multiple hardware devices simultaneously, and we rely on being able to
pass some hints to both the xfrm and NIC driver about whether or not
they're operating on a slave device.
I've tested this atop an Intel x520 device (ixgbe) using libreswan in
transport mode, succesfully achieving ~4.3Gbps throughput with netperf
(more or less identical to throughput on a bare NIC in this system),
as well as successful failover and recovery mid-netperf.
v2: rebase on latest net-next and wrap with #ifdef CONFIG_XFRM_OFFLOAD
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Jakub Kicinski <kuba@kernel.org>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Herbert Xu <herbert@gondor.apana.org.au>
CC: netdev at vger.kernel.org
CC: intel-wired-lan at lists.osuosl.org
Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/net/bonding/bond_main.c | 111 +++++++++++++++++++++++++++++++-
include/net/bonding.h | 3 +
2 files changed, 111 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index baa93191dfdd..b90a86029df5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
#include <net/pkt_sched.h>
#include <linux/rculist.h>
#include <net/flow_dissector.h>
+#include <net/xfrm.h>
#include <net/bonding.h>
#include <net/bond_3ad.h>
#include <net/bond_alb.h>
@@ -278,8 +279,6 @@ const char *bond_mode_name(int mode)
return names[mode];
}
-/*---------------------------------- VLAN -----------------------------------*/
-
/**
* bond_dev_queue_xmit - Prepare skb for xmit.
*
@@ -302,6 +301,8 @@ void bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
dev_queue_xmit(skb);
}
+/*---------------------------------- VLAN -----------------------------------*/
+
/* In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
* We don't protect the slave list iteration with a lock because:
* a. This operation is performed in IOCTL context,
@@ -372,6 +373,84 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
return 0;
}
+/*---------------------------------- XFRM -----------------------------------*/
+
+#ifdef CONFIG_XFRM_OFFLOAD
+/**
+ * bond_ipsec_add_sa - program device with a security association
+ * @xs: pointer to transformer state struct
+ **/
+static int bond_ipsec_add_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ xs->xso.slave_dev = slave->dev;
+ bond->xs = xs;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_add)) {
+ slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+ return -EINVAL;
+ }
+
+ return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+}
+
+/**
+ * bond_ipsec_del_sa - clear out this specific SA
+ * @xs: pointer to transformer state struct
+ **/
+static void bond_ipsec_del_sa(struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *slave = rtnl_dereference(bond->curr_active_slave);
+
+ if (!slave)
+ return;
+
+ xs->xso.slave_dev = slave->dev;
+
+ if (!(slave->dev->xfrmdev_ops
+ && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) {
+ slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+ return;
+ }
+
+ slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+}
+
+/**
+ * bond_ipsec_offload_ok - can this packet use the xfrm hw offload
+ * @skb: current data packet
+ * @xs: pointer to transformer state struct
+ **/
+static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
+{
+ struct net_device *bond_dev = xs->xso.dev;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct slave *curr_active = rtnl_dereference(bond->curr_active_slave);
+ struct net_device *slave_dev = curr_active->dev;
+
+ if (!(slave_dev->xfrmdev_ops
+ && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) {
+ slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__);
+ return false;
+ }
+
+ xs->xso.slave_dev = slave_dev;
+ return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+}
+
+static const struct xfrmdev_ops bond_xfrmdev_ops = {
+ .xdo_dev_state_add = bond_ipsec_add_sa,
+ .xdo_dev_state_delete = bond_ipsec_del_sa,
+ .xdo_dev_offload_ok = bond_ipsec_offload_ok,
+};
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/*------------------------------- Link status -------------------------------*/
/* Set the carrier state for the master according to the state of its
@@ -878,6 +957,11 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (old_active == new_active)
return;
+#ifdef CONFIG_XFRM_OFFLOAD
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) && bond->xs)
+ bond_ipsec_del_sa(bond->xs);
+#endif /* CONFIG_XFRM_OFFLOAD */
+
if (new_active) {
new_active->last_link_up = jiffies;
@@ -941,6 +1025,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
bond_should_notify_peers(bond);
}
+#ifdef CONFIG_XFRM_OFFLOAD
+ if (old_active && bond->xs) {
+ xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true);
+ bond_ipsec_add_sa(bond->xs);
+ }
+#endif /* CONFIG_XFRM_OFFLOAD */
+
call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev);
if (should_notify_peers) {
bond->send_peer_notif--;
@@ -1125,7 +1216,9 @@ static netdev_features_t bond_fix_features(struct net_device *dev,
NETIF_F_HIGHDMA | NETIF_F_LRO)
#define BOND_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
- NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
+ NETIF_F_RXCSUM | NETIF_F_ALL_TSO | \
+ NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \
+ NETIF_F_GSO_ESP)
#define BOND_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
NETIF_F_ALL_TSO)
@@ -1464,6 +1557,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
slave_dbg(bond_dev, slave_dev, "is !NETIF_F_VLAN_CHALLENGED\n");
}
+ if (slave_dev->features & NETIF_F_HW_ESP)
+ slave_dbg(bond_dev, slave_dev, "is esp-hw-offload capable\n");
+
/* Old ifenslave binaries are no longer supported. These can
* be identified with moderate accuracy by the state of the slave:
* the current ifenslave will set the interface down prior to
@@ -4444,6 +4540,13 @@ void bond_setup(struct net_device *bond_dev)
bond_dev->priv_flags |= IFF_BONDING | IFF_UNICAST_FLT | IFF_NO_QUEUE;
bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+#ifdef CONFIG_XFRM_OFFLOAD
+ /* set up xfrm device ops (only supported in active-backup right now */
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
+ bond->xs = NULL;
+#endif /* CONFIG_XFRM_OFFLOAD */
+
/* don't acquire bond device's netif_tx_lock when transmitting */
bond_dev->features |= NETIF_F_LLTX;
@@ -4462,6 +4565,8 @@ void bond_setup(struct net_device *bond_dev)
NETIF_F_HW_VLAN_CTAG_FILTER;
bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
+ if ((BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP))
+ bond_dev->hw_features |= BOND_ENC_FEATURES;
bond_dev->features |= bond_dev->hw_features;
bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
}
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 0b696da5c115..4ca178b2d0e2 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -237,6 +237,9 @@ struct bonding {
struct dentry *debug_dir;
#endif /* CONFIG_DEBUG_FS */
struct rtnl_link_stats64 bond_stats;
+#ifdef CONFIG_XFRM_OFFLOAD
+ struct xfrm_state *xs;
+#endif /* CONFIG_XFRM_OFFLOAD */
};
#define bond_slave_get_rcu(dev) \
--
2.20.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
end of thread, other threads:[~2020-05-05 22:59 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-04 14:59 [RFC PATCH net-next 0/3] bonding: support hardware crypto offload Jarod Wilson
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
2020-05-04 14:59 ` [RFC PATCH net-next 1/3] xfrm: bail early on slave pass over skb Jarod Wilson
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
2020-05-04 14:59 ` [RFC PATCH net-next 2/3] ixgbe_ipsec: become aware of when running as a bonding slave Jarod Wilson
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
2020-05-04 14:59 ` [RFC PATCH net-next 3/3] bonding: support hardware encryption offload to slaves Jarod Wilson
2020-05-04 14:59 ` [Intel-wired-lan] " Jarod Wilson
2020-05-05 13:30 ` kbuild test robot
2020-05-05 14:36 ` kbuild test robot
2020-05-05 22:58 ` [RFC PATCH net-next v2 0/3] bonding: support hardware crypto offload Jarod Wilson
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
2020-05-05 22:58 ` [RFC PATCH net-next v2 1/3] xfrm: bail early on slave pass over skb Jarod Wilson
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
2020-05-05 22:58 ` [RFC PATCH net-next v2 2/3] ixgbe_ipsec: become aware of when running as a bonding slave Jarod Wilson
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
2020-05-05 22:58 ` [RFC PATCH net-next v2 3/3] bonding: support hardware encryption offload to slaves Jarod Wilson
2020-05-05 22:58 ` [Intel-wired-lan] " Jarod Wilson
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.