From patchwork Tue Dec 12 23:37:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shannon Nelson X-Patchwork-Id: 847674 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@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; dkim=pass (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="a11HEZJE"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yxGTB1kW6z9t2W for ; Wed, 13 Dec 2017 10:37:34 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752805AbdLLXhb (ORCPT ); Tue, 12 Dec 2017 18:37:31 -0500 Received: from userp2130.oracle.com ([156.151.31.86]:59910 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752733AbdLLXh2 (ORCPT ); Tue, 12 Dec 2017 18:37:28 -0500 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.21/8.16.0.21) with SMTP id vBCNUFD0182842; Tue, 12 Dec 2017 23:37:23 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references; s=corp-2017-10-26; bh=EGHX9odxH+DvcRgexpxAJXeuAUMTfAxubtCZqhbJsaw=; b=a11HEZJEaOMXpBo2S9sTbO1CU36SjXIYlnjGrY2ldR6+RDm3yN9YrXfhVN5cTGkJatL5 KCeRU480OIhcqI0XRDxXPBJrm4S6qWMENtpN8N778kG4dj8HvOuNIY+Z+FwVb2S7fWfJ BTBtQiNNZmv4SEaWHD+Y3u5dN7mDvd1xCr28PzBsGfRWKq3+xieKQvD/nQbAJG5nR9vt RPOVcYkcoFdN7wXomuX5dY1qakZlGMgaIRmcBMJAtRAbt1N7Umi9rY1Db9nQf5g8UNNe s9dnz7N5EmmOoOOoULu/9a/5IrytVBOHNA2C4jTxDqnBtwXpLhGAahhilN4+wYmSP8VO Pg== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp2130.oracle.com with ESMTP id 2etrug80q0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 12 Dec 2017 23:37:23 +0000 Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id vBCNbMOT029373 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 12 Dec 2017 23:37:22 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id vBCNbLep024595; Tue, 12 Dec 2017 23:37:21 GMT Received: from slnelson-mint18.us.oracle.com (/10.159.225.160) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 12 Dec 2017 15:37:21 -0800 From: Shannon Nelson To: intel-wired-lan@lists.osuosl.org, jeffrey.t.kirsher@intel.com Cc: netdev@vger.kernel.org, steffen.klassert@secunet.com, sowmini.varadhan@oracle.com Subject: [PATCH v2 next-queue 07/10] ixgbe: process the Rx ipsec offload Date: Tue, 12 Dec 2017 15:37:00 -0800 Message-Id: <1513121823-27944-8-git-send-email-shannon.nelson@oracle.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513121823-27944-1-git-send-email-shannon.nelson@oracle.com> References: <1513121823-27944-1-git-send-email-shannon.nelson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=8743 signatures=668646 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 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-1711220000 definitions=main-1712120331 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If the chip sees and decrypts an ipsec offload, set up the skb sp pointer with the ralated SA info. Since the chip is rude enough to keep to itself the table index it used for the decryption, we have to do our own table lookup, using the hash for speed. Signed-off-by: Shannon Nelson --- v2: no changes drivers/net/ethernet/intel/ixgbe/ixgbe.h | 6 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 89 ++++++++++++++++++++++++++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 + 3 files changed, 98 insertions(+) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index af690c2..a094b23 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -1011,9 +1011,15 @@ s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg, void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter); void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter); void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter); +void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb); #else static inline void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) { }; static inline void ixgbe_stop_ipsec_offload(struct ixgbe_adapter *adapter) { }; static inline void ixgbe_ipsec_restore(struct ixgbe_adapter *adapter) { }; +static inline void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) { }; #endif /* CONFIG_XFRM_OFFLOAD */ #endif /* _IXGBE_H_ */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c index 049c195..7e421b8 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -374,6 +374,35 @@ static int ixgbe_ipsec_find_empty_idx(struct ixgbe_ipsec *ipsec, bool rxtable) } /** + * ixgbe_ipsec_find_rx_state - find the state that matches + * @ipsec: pointer to ipsec struct + * @daddr: inbound address to match + * @proto: protocol to match + * @spi: SPI to match + * + * Returns a pointer to the matching SA state information + **/ +static struct xfrm_state *ixgbe_ipsec_find_rx_state(struct ixgbe_ipsec *ipsec, + __be32 daddr, u8 proto, + __be32 spi) +{ + struct rx_sa *rsa; + struct xfrm_state *ret = NULL; + + rcu_read_lock(); + hash_for_each_possible_rcu(ipsec->rx_sa_list, rsa, hlist, spi) + if (spi == rsa->xs->id.spi && + daddr == rsa->xs->id.daddr.a4 && + proto == rsa->xs->id.proto) { + ret = rsa->xs; + xfrm_state_hold(ret); + break; + } + rcu_read_unlock(); + return ret; +} + +/** * ixgbe_ipsec_parse_proto_keys - find the key and salt based on the protocol * @xs: pointer to xfrm_state struct * @mykey: pointer to key array to populate @@ -672,6 +701,66 @@ static const struct xfrmdev_ops ixgbe_xfrmdev_ops = { }; /** + * ixgbe_ipsec_rx - decode ipsec bits from Rx descriptor + * @rx_ring: receiving ring + * @rx_desc: receive data descriptor + * @skb: current data packet + * + * Determine if there was an ipsec encapsulation noticed, and if so set up + * the resulting status for later in the receive stack. + **/ +void ixgbe_ipsec_rx(struct ixgbe_ring *rx_ring, + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + struct ixgbe_adapter *adapter = netdev_priv(rx_ring->netdev); + u16 pkt_info = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info); + u16 ipsec_pkt_types = IXGBE_RXDADV_PKTTYPE_IPSEC_AH | + IXGBE_RXDADV_PKTTYPE_IPSEC_ESP; + struct ixgbe_ipsec *ipsec = adapter->ipsec; + struct xfrm_offload *xo = NULL; + struct xfrm_state *xs = NULL; + struct iphdr *iph; + u8 *c_hdr; + __be32 spi; + u8 proto; + + /* we can assume no vlan header in the way, b/c the + * hw won't recognize the IPsec packet and anyway the + * currently vlan device doesn't support xfrm offload. + */ + /* TODO: not supporting IPv6 yet */ + iph = (struct iphdr *)(skb->data + ETH_HLEN); + c_hdr = (u8 *)iph + iph->ihl * 4; + switch (pkt_info & ipsec_pkt_types) { + case IXGBE_RXDADV_PKTTYPE_IPSEC_AH: + spi = ((struct ip_auth_hdr *)c_hdr)->spi; + proto = IPPROTO_AH; + break; + case IXGBE_RXDADV_PKTTYPE_IPSEC_ESP: + spi = ((struct ip_esp_hdr *)c_hdr)->spi; + proto = IPPROTO_ESP; + break; + default: + return; + } + + xs = ixgbe_ipsec_find_rx_state(ipsec, iph->daddr, proto, spi); + if (unlikely(!xs)) + return; + + skb->sp = secpath_dup(skb->sp); + if (unlikely(!skb->sp)) + return; + + skb->sp->xvec[skb->sp->len++] = xs; + skb->sp->olen++; + xo = xfrm_offload(skb); + xo->flags = CRYPTO_DONE; + xo->status = CRYPTO_SUCCESS; +} + +/** * ixgbe_init_ipsec_offload - initialize security registers for IPSec operation * @adapter: board private structure **/ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 04e8b26..0ee1e5e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1755,6 +1755,9 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, skb_record_rx_queue(skb, rx_ring->queue_index); + if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_SECP)) + ixgbe_ipsec_rx(rx_ring, rx_desc, skb); + skb->protocol = eth_type_trans(skb, dev); }