From patchwork Tue Oct 30 22:44:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shannon Nelson X-Patchwork-Id: 991167 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="ju9KTRgb"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42l63l5PSnz9s8F for ; Wed, 31 Oct 2018 09:44:51 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727520AbeJaHkJ (ORCPT ); Wed, 31 Oct 2018 03:40:09 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:50432 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726077AbeJaHkJ (ORCPT ); Wed, 31 Oct 2018 03:40:09 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w9UMiimK135981; Tue, 30 Oct 2018 22:44:44 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id; s=corp-2018-07-02; bh=4q5CelWoKRTJMfRDpL2JWOLfiiilXcCPA/h8OxPbnuo=; b=ju9KTRgbcbSK9cT5WJN5VdKmX9oWzby/ihOx5sHc9N4OjiRZhbIxp7rg7CtQU7J9nwPy A8crYoCbalFgNFvydziDFivDxz8mYlWrFBX/1d2/UQSQ8nha6d5fgw4zeAhcfZrcNyqI KnvRVMdzKiOx9Pmp4MhvN7latKh4xR4tXi2i3yvfB5aoviJKzUYbb0J4TybyURhFLX8c IYQthdBZN+hiDHRmp/WLR4hzmYacZeUG47KFX0BpkoSi/eKJv/he4Bs/pcrKdioRBltw XX561/sM0k53586ApokVNT218F4lv5skp8+WIdkUdXHyL4ss8fO8GgK9HVrscvAyJ09e +g== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp2120.oracle.com with ESMTP id 2ncgnqyers-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 30 Oct 2018 22:44:44 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w9UMihGv022192 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 30 Oct 2018 22:44:44 GMT Received: from abhmp0020.oracle.com (abhmp0020.oracle.com [141.146.116.26]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w9UMih76017482; Tue, 30 Oct 2018 22:44:43 GMT Received: from slnelson-mint18.us.oracle.com (/10.159.228.142) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 30 Oct 2018 15:44:43 -0700 From: Shannon Nelson To: netdev@vger.kernel.org Cc: shannon.lee.nelson@gmail.com Subject: [RFC PATCH] net: vlan ipsec-xfrm offload Date: Tue, 30 Oct 2018 15:44:34 -0700 Message-Id: <1540939474-15517-1-git-send-email-shannon.nelson@oracle.com> X-Mailer: git-send-email 2.7.4 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9062 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=4 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1810300190 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This is an RFC post - not working code. I welcome your comments. If the real device offers IPsec offload, why shouldn't the VLAN device also offer the offload? This essentially becomes a passthru interface to the real device by swapping out the xfrm_state's netdevice reference before calling to the real_dev. Signed-off-by: Shannon Nelson --- net/8021q/vlan_dev.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index ff720f1..a46e056 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "vlan.h" #include "vlanproc.h" @@ -546,6 +547,7 @@ static struct device_type vlan_type = { }; static const struct net_device_ops vlan_netdev_ops; +static const struct xfrmdev_ops vlan_xfrmdev_ops; static int vlan_dev_init(struct net_device *dev) { @@ -553,6 +555,7 @@ static int vlan_dev_init(struct net_device *dev) netif_carrier_off(dev); + /* copy netdev features into list of user selectable features */ /* IFF_BROADCAST|IFF_MULTICAST; ??? */ dev->flags = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_MASTER | IFF_SLAVE); @@ -564,6 +567,12 @@ static int vlan_dev_init(struct net_device *dev) NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC | NETIF_F_ALL_FCOE; +#ifdef CONFIG_XFRM_OFFLOAD + dev->hw_features |= real_dev->hw_features & (NETIF_F_HW_ESP | + NETIF_F_HW_ESP_TX_CSUM | + NETIF_F_GSO_ESP); + dev->xfrmdev_ops = &vlan_xfrmdev_ops; +#endif dev->features |= dev->hw_features | NETIF_F_LLTX; dev->gso_max_size = real_dev->gso_max_size; @@ -767,6 +776,95 @@ static int vlan_dev_get_iflink(const struct net_device *dev) return real_dev->ifindex; } +static int vlan_xdo_state_add(struct xfrm_state *xs) +{ + struct net_device *dev = xs->xso.dev; + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; + int ret; + + /* swap out the vlan dev and put a hold on the real device */ + xs->xso.dev = real_dev; + dev_hold(real_dev); + + ret = real_dev->xfrmdev_ops->xdo_dev_state_add(xs); + + /* if it wasn't successful, release the real_dev */ + if (ret) + dev_put(real_dev); + + /* put dev back before we leave */ + xs->xso.dev = dev; + + return ret; +} + +static void vlan_xdo_state_delete(struct xfrm_state *xs) +{ + struct net_device *dev = xs->xso.dev; + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; + + xs->xso.dev = real_dev; + real_dev->xfrmdev_ops->xdo_dev_state_delete(xs); + xs->xso.dev = dev; +} + +static void vlan_xdo_state_free(struct xfrm_state *xs) +{ + struct net_device *dev = xs->xso.dev; + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; + + /* check for optional interface */ + if (real_dev->xfrmdev_ops->xdo_dev_state_free) { + xs->xso.dev = real_dev; + real_dev->xfrmdev_ops->xdo_dev_state_free(xs); + xs->xso.dev = dev; + } + + /* let go of the real device, we're done with it */ + dev_put(real_dev); +} + +static bool vlan_xdo_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) +{ + struct net_device *dev = xs->xso.dev; + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; + bool ret = true; + + /* check for optional interface */ + if (likely(real_dev->xfrmdev_ops->xdo_dev_offload_ok)) { + xs->xso.dev = real_dev; + ret = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs); + xs->xso.dev = dev; + } + + if (!ret) + netdev_err(dev, "%s: real_dev %s NAKd the offload\n", + __func__, real_dev->name); + + return ret; +} + +static void vlan_xdo_advance_esn(struct xfrm_state *xs) +{ + struct net_device *dev = xs->xso.dev; + struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; + + /* check for optional interface */ + if (real_dev->xfrmdev_ops->xdo_dev_state_advance_esn) { + xs->xso.dev = real_dev; + real_dev->xfrmdev_ops->xdo_dev_state_advance_esn(xs); + xs->xso.dev = dev; + } +} + +static const struct xfrmdev_ops vlan_xfrmdev_ops = { + .xdo_dev_state_add = vlan_xdo_state_add, + .xdo_dev_state_delete = vlan_xdo_state_delete, + .xdo_dev_state_free = vlan_xdo_state_free, + .xdo_dev_offload_ok = vlan_xdo_offload_ok, + .xdo_dev_state_advance_esn = vlan_xdo_advance_esn, +}; + static const struct ethtool_ops vlan_ethtool_ops = { .get_link_ksettings = vlan_ethtool_get_link_ksettings, .get_drvinfo = vlan_ethtool_get_drvinfo,