Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751827AbdH3IbD (ORCPT ); Wed, 30 Aug 2017 04:31:03 -0400 Received: from mail-eopbgr30079.outbound.protection.outlook.com ([40.107.3.79]:60672 "EHLO EUR03-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751747AbdH3IbA (ORCPT ); Wed, 30 Aug 2017 04:31:00 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=yossiku@mellanox.com; From: yossiku@mellanox.com To: Steffen Klassert , Herbert Xu , "David S. Miller" , Alexey Kuznetsov , Hideaki YOSHIFUJI , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: borisp@mellanox.com, kliteyn@mellanox.com, Yossi Kuperman Subject: [PATCH net-next] xfrm: Add support for network devices capable of removing the ESP trailer Date: Wed, 30 Aug 2017 11:30:39 +0300 Message-Id: <1504081839-22019-1-git-send-email-yossiku@mellanox.com> X-Mailer: git-send-email 2.8.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [82.166.227.17] X-ClientProxiedBy: AM5PR0602CA0012.eurprd06.prod.outlook.com (2603:10a6:203:a3::22) To AM4PR0501MB2273.eurprd05.prod.outlook.com (2603:10a6:200:53::10) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: aa6f7fbb-eeb4-4372-c3bb-08d4ef816f61 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(22001)(300000502095)(300135100095)(2017030254152)(300000503095)(300135400095)(48565401081)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095);SRVR:AM4PR0501MB2273; X-Microsoft-Exchange-Diagnostics: 1;AM4PR0501MB2273;3:STRM62uW5t65MwK14DPNvra9Q04hzmv7ecnV7Ho5vpcX3fY7vRqEcquVX7YsUspDLVAjLP/aVj3Wd72ZCSvz37ALbeKZ3OQnOMiadbiu1xWBbKwY81G7UTluvl6uAjJacbb+JfcDAsjnIwx5lKp5fDI8aPH//l70/ZB9LNihT6sCgd7JT21Gkb6cqMmRqBsamfEd3SO19SCufxnfWbd3cXZW5k8w9cK/JMmQonh+6/rce6AHSYl7FGMHSlJiL+PN;25:PlgLTbNUoKocs47oxRFsUI0LZfCPXAKQplS+GsPFRb2hYFyRRk6RooUTu1TdPBYDUSn/R8COOUFRJ6X7goNZ68eiG8LLu8TxMqmB7IDYIJ+yBTWnJF6POtoq/YA1bO+GQPAtlzoIS911ndBDizIVzYtbBKYyXOGRGVKRfh3Hu4K2s109nyRpAp+T6BjRIOzemeB3LOQksIb5s55PRC27iPb1rUP88UiACd0j1OjIKYPrJds4VwJZlTkyrKI5nLGgdag5VGOEWzt6S9S4dWxFWlr5xzqj3gW0QciRWaZpBN4grHQIXqIBYJc4T4WPL+oDEmrVkoiIsQ7Iip3OomCVtQ==;31:lhP4MT4LwUueTJz+/HeBRV9vCEwyEKdIejtfdNepSttZ6kcqVQTHNuxKN3IroxPBbrx7YusItr+iFe2DNU8S0EwQq/TZcju3CcGe2on4iuwSP3Nl2E6gap6ErPiQM/s9/LdDIlUlLkhcnhcfmvXlwbTBleECWeXfOpruae6mPZrlcCceUroyD2TIjfnqO/YJ0jlJce8dmwYN5ICjPcwLzyvYbps1ksbTjM8hn91W+r0= X-MS-TrafficTypeDiagnostic: AM4PR0501MB2273: X-Microsoft-Exchange-Diagnostics: 1;AM4PR0501MB2273;20:ato7UDfm+Hyih4BHr53yRtE+D0iq6lvxeD/eGEeFA6QvOq3RAwRkwxubHZBz6O/qEp7WGBZ5rRNLErla5ddW2qEK1ByRWwFABKoKdmE3e7uwGE9mPGsMUA1zZVQdp9we9Gl0gKW2RtAEqrMaG2u1g6EejZ/zrYxkvVhv9PIG0javBC24cOffkC0LbXGruykkOLP17HnOnfXIdzmtRM6eyVwhSwb6b7jf1FvdQp+bMCirXQ2YjwwdqrEAv5cahLvN/7ojM9HFK9Gqhv5PueRxapQu5EOanUHklcZAfVfw86BG0MxYspYFT2vnf1GvwvPWURvtWvoyFVp6MeYRl1AM4FiCIvAq657cbnwO7+Xwo1xIQoSjf41KYTJ1rrmRbz3VX0RneKYzRU0KmkKplP/DRyVqsDFIzQTwv1JtkbLgUeImTo8932Tc1v2DjA7j03p5HRzU4YsehjZUE7RattuK5SCa9vKggLTm3PMgVjD66tXmnI+ngm8GNqpnh4eIIn93;4:QDQ952W918Z1S8S1fENWdgP2NJQBgxnIeimICIelal50pXWxQegCDejwD3V428tj88+ZH9a9Vpu2mDxClTWhH963VN/4NcuI5mjlaYVzLieGybgWBSW4XIQKB5wqEaWo5J5Qf1U8sWDESE4ahB0C7ABXJDWmhCKUDIkb4Pbt6q1SZbBzxbdAOfUptQdkePpScarY5Offs2ZGCqICE3cFepGNDHzzrcEAGUPu5EfK81xODFMNhP0zYYP3a8xquyF1fido8NBzxN73vQ91F2VrsmFuVoW4e0mSH5D6CtNybHjXqcPe9fEVU5R489x7YMBimSIZ+PTNVAGZy1pgperlEQ== X-Exchange-Antispam-Report-Test: UriScan:(9452136761055)(278021516957215); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(5005006)(8121501046)(10201501046)(100000703101)(100105400095)(93006095)(93001095)(3002001)(6055026)(6041248)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123564025)(20161123558100)(20161123560025)(20161123555025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:AM4PR0501MB2273;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:AM4PR0501MB2273; X-Forefront-PRVS: 041517DFAB X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(7370300001)(4630300001)(6009001)(189002)(199003)(105586002)(33646002)(50986999)(47776003)(101416001)(4326008)(25786009)(106356001)(3846002)(6116002)(42186005)(50466002)(48376002)(81166006)(8676002)(53936002)(9686003)(50226002)(478600001)(81156014)(6306002)(6486002)(6666003)(97736004)(68736007)(6512007)(5003940100001)(305945005)(7736002)(7350300001)(2906002)(107886003)(189998001)(66066001)(966005)(36756003)(86362001)(85782001)(5660300001)(85772001);DIR:OUT;SFP:1101;SCL:1;SRVR:AM4PR0501MB2273;H:dev-l-vrt-187.mtl.labs.mlnx;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM4PR0501MB2273;23:1K/mWZkQHH2kHV6KAaTmnwPNfkbyZc8+Y7zxFVk?= =?us-ascii?Q?W05RR8vNIlGtGqkg3f/9ejKncPy4Wj4EdoQWa6mj5KNgl9oypOCAuJ16aVjt?= =?us-ascii?Q?R3M0Bam84iim/ODdyZ47IP+2ymdPTPfzbXh00Ppec6TQXsIPpnv/KJS2uLju?= =?us-ascii?Q?+NkXp4fNlpH1HfYAZqvR0krvcimFo1VeXTxUgv2kJVNLn6AFuEix7OuiKUhC?= =?us-ascii?Q?BCsPzipDIFHmh2TmxjrJ/ce6YXlBxUVvbq87l77HkMTw37ZC1fkl67pHMTny?= =?us-ascii?Q?M+7hJf35Sbj1zbyYcaN/QAZ8yl301w2r1UpWshGe4IEr/AVh9BkOxYbc7NDC?= =?us-ascii?Q?jgInGH5NW3G0TIcX7jw47rdnEpOgt/pXUBbfOxwzWXXhQ8cSOsIyBRKfvzcP?= =?us-ascii?Q?yipdKFvPGfRNo9DK8sAwou/sxiyYd8/moCgNHD3mO5yrbrpB4FbROb6U+3mc?= =?us-ascii?Q?0MZzM8SBO4szPhQlw8DR7nluB89+8JcAM0pSm7/O4ySR66El4Mag6+CPziPZ?= =?us-ascii?Q?cItPdrjE0Gnsgh60U88mbqMKJyn0h+dPdPXKSQeBtdl6RJ16wxLwBHTkhaFL?= =?us-ascii?Q?6E8br/UEkMGtUid1JGPv/Lh7ZtI31g2lwyvDB6uloKYjftCVMkNJlJHFgnT5?= =?us-ascii?Q?M1djWVVYVuB9vVktnkFOzW29zokmsjbMBaqsfJ3pGaibVO91rtdZHqsbQi+L?= =?us-ascii?Q?Vt/SPdkJQpNtZjgfoHQbsMVFIi5WvwVRtGQMAto4XY16a4o5nD315GkIny2C?= =?us-ascii?Q?ynYE/LXYeXPX23G8ecGgyenvA/Iig0AI6yV2TDGL229JBVA+gZp/QUUFwOFG?= =?us-ascii?Q?kn8WS/3F9S+KoGTTzjUuC+4JjnGdYnX9Obm6BZQDDIFuMPCaJEz35LOnf/ue?= =?us-ascii?Q?JsYo8Jppd52smzAvp/5tICcEsMgCZjXf2OPPA96s7DiCEOW1RfAam6Hxcdlh?= =?us-ascii?Q?D5MykxE8wLjvj51HILF7yaAb06m8Fw/VwZbPWb3KMPckOrwhHLrKpO2jxclO?= =?us-ascii?Q?mdsVxvUiYcRi/zNuCP3txvh+eCBIxtLFxJTZj3wJ6iSO2ogjtgBRLxkxC96u?= =?us-ascii?Q?dO5T1tlPXBuJMEsfh5yiWgc2XT+dWzto73E/1ZNccM97nwPJ3oA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;AM4PR0501MB2273;6:BbCm/h1KYXZqyog2phs6WND6nk6oAr1wlA7sssdVf/3RKLK/BwXWwl+0W2gjGM9GZqRG7wk1K4xPE/QYHg7L2tPsXP9qdVrM2u5iGja43NFID374n6RwDcTObwkSjVwI9JfzjWydYw7Tkqy0RprmJmOcb/YxMaU794SDajxNeU5sSkjZgsJtr0lpdMgGhv2bbNyaMcyqyIGOlghkKzKN+kT6eqSqnGDrOUTOel3hToEcFgPo5tpdNNqkHtw4HlUCnaTjF9YA4FtxOP10iHQ/BfVGVm4xZ4HEorsA04zykS30WlUPcp3Y9yjqaYS4vJNYGyvzXWxCLgEHmgkNwVPpWQ==;5:1G431J6C/aLTarKWaDZE0EY4ea/2m4wzGOxc3y9kaq3AN+aXOREt05LnHInlnEy1c863msiYZXHbfymfydZNl+6n6uYDgNjxlRcod5qXPWz6uD+MdPLXM6hI49ear3uaXecU2vjdg7aC5DtIwju7Qw==;24:nVR5uLvIXyJ/zlwSEUlDkoEFUojXuQGr1wqtDDOqnnfsND2NzxDFYmuX9tI6JhJgt6yMrrW9DKwmSvUPj4tFRY3eJ9/I0yIN2SmUiLJzuwA=;7:J7lvqwCTm8RNPiitlHZqPlX2mL62qHoUPSAF2KxTRR9E6zVZptbPVjDTw0i7qHUwqnadHmOWmf4XHqW3anNXcyWdnz8SrOs0+PCO6TeiIpzyQFYRUblMvLBNHAnwRPpPtWb5nHiaDkdVkP0P98NOX01Ua42BbhejThXawM0Z4Hrt1YbhfMMFRub8yMeiIgrKFmhgM48CmyLe16jTAeq992ipTVeSQDg+cjGfkg6EUdk= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Aug 2017 08:30:55.4736 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0501MB2273 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7378 Lines: 260 From: Yossi Kuperman In conjunction with crypto offload [1], removing the ESP trailer by hardware can potentially improve the performance by avoiding (1) a cache miss incurred by reading the nexthdr field and (2) the necessity to calculate the csum value of the trailer in order to keep skb->csum valid. This patch introduces the changes to the xfrm stack and merely serves as an infrastructure. Subsequent patch to mlx5 driver will put this to a good use. [1] https://www.mail-archive.com/netdev@vger.kernel.org/msg175733.html Signed-off-by: Yossi Kuperman --- include/net/xfrm.h | 1 + net/ipv4/esp4.c | 70 ++++++++++++++++++++++++++++++++++----------------- net/ipv6/esp6.c | 51 ++++++++++++++++++++++++++----------- net/xfrm/xfrm_input.c | 5 ++++ 4 files changed, 89 insertions(+), 38 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 9c7b70c..f002a2c 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1019,6 +1019,7 @@ struct xfrm_offload { #define CRYPTO_FALLBACK 8 #define XFRM_GSO_SEGMENT 16 #define XFRM_GRO 32 +#define XFRM_ESP_NO_TRAILER 64 __u32 status; #define CRYPTO_SUCCESS 1 diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 741acd7..3190005 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -499,19 +499,59 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) return esp_output_tail(x, skb, &esp); } +static inline int esp_remove_trailer(struct sk_buff *skb) +{ + struct xfrm_state *x = xfrm_input_state(skb); + struct xfrm_offload *xo = xfrm_offload(skb); + struct crypto_aead *aead = x->data; + int alen, hlen, elen; + int padlen, trimlen; + __wsum csumdiff; + u8 nexthdr[2]; + int ret; + + alen = crypto_aead_authsize(aead); + hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); + elen = skb->len - hlen; + + if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { + ret = xo->proto; + goto out; + } + + if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) + BUG(); + + ret = -EINVAL; + padlen = nexthdr[0]; + if (padlen + 2 + alen >= elen) { + net_dbg_ratelimited("ipsec esp packet is garbage padlen=%d, elen=%d\n", + padlen + 2, elen - alen); + goto out; + } + + trimlen = alen + padlen + 2; + if (skb->ip_summed == CHECKSUM_COMPLETE) { + csumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0); + skb->csum = csum_block_sub(skb->csum, csumdiff, + skb->len - trimlen); + } + pskb_trim(skb, skb->len - trimlen); + + ret = nexthdr[1]; + +out: + return ret; +} + int esp_input_done2(struct sk_buff *skb, int err) { const struct iphdr *iph; struct xfrm_state *x = xfrm_input_state(skb); struct xfrm_offload *xo = xfrm_offload(skb); struct crypto_aead *aead = x->data; - int alen = crypto_aead_authsize(aead); int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); - int elen = skb->len - hlen; int ihl; - u8 nexthdr[2]; - int padlen, trimlen; - __wsum csumdiff; if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) kfree(ESP_SKB_CB(skb)->tmp); @@ -519,16 +559,10 @@ int esp_input_done2(struct sk_buff *skb, int err) if (unlikely(err)) goto out; - if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) - BUG(); - - err = -EINVAL; - padlen = nexthdr[0]; - if (padlen + 2 + alen >= elen) + err = esp_remove_trailer(skb); + if (unlikely(err < 0)) goto out; - /* ... check padding bits here. Silly. :-) */ - iph = ip_hdr(skb); ihl = iph->ihl * 4; @@ -569,22 +603,12 @@ int esp_input_done2(struct sk_buff *skb, int err) skb->ip_summed = CHECKSUM_UNNECESSARY; } - trimlen = alen + padlen + 2; - if (skb->ip_summed == CHECKSUM_COMPLETE) { - csumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0); - skb->csum = csum_block_sub(skb->csum, csumdiff, - skb->len - trimlen); - } - pskb_trim(skb, skb->len - trimlen); - skb_pull_rcsum(skb, hlen); if (x->props.mode == XFRM_MODE_TUNNEL) skb_reset_transport_header(skb); else skb_set_transport_header(skb, -ihl); - err = nexthdr[1]; - /* RFC4303: Drop dummy packets without any error */ if (err == IPPROTO_NONE) err = -EINVAL; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 74bde20..7fb41b0 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -461,29 +461,30 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) return esp6_output_tail(x, skb, &esp); } -int esp6_input_done2(struct sk_buff *skb, int err) +static inline int esp_remove_trailer(struct sk_buff *skb) { struct xfrm_state *x = xfrm_input_state(skb); struct xfrm_offload *xo = xfrm_offload(skb); struct crypto_aead *aead = x->data; - int alen = crypto_aead_authsize(aead); - int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); - int elen = skb->len - hlen; - int hdr_len = skb_network_header_len(skb); + int alen, hlen, elen; int padlen, trimlen; __wsum csumdiff; u8 nexthdr[2]; + int ret; - if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) - kfree(ESP_SKB_CB(skb)->tmp); + alen = crypto_aead_authsize(aead); + hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); + elen = skb->len - hlen; - if (unlikely(err)) + if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { + ret = xo->proto; goto out; + } if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) BUG(); - err = -EINVAL; + ret = -EINVAL; padlen = nexthdr[0]; if (padlen + 2 + alen >= elen) { net_dbg_ratelimited("ipsec esp packet is garbage padlen=%d, elen=%d\n", @@ -491,26 +492,46 @@ int esp6_input_done2(struct sk_buff *skb, int err) goto out; } - /* ... check padding bits here. Silly. :-) */ - trimlen = alen + padlen + 2; if (skb->ip_summed == CHECKSUM_COMPLETE) { - skb_postpull_rcsum(skb, skb_network_header(skb), - skb_network_header_len(skb)); csumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0); skb->csum = csum_block_sub(skb->csum, csumdiff, skb->len - trimlen); } pskb_trim(skb, skb->len - trimlen); + ret = nexthdr[1]; + +out: + return ret; +} + +int esp6_input_done2(struct sk_buff *skb, int err) +{ + struct xfrm_state *x = xfrm_input_state(skb); + struct xfrm_offload *xo = xfrm_offload(skb); + struct crypto_aead *aead = x->data; + int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); + int hdr_len = skb_network_header_len(skb); + + if (!xo || (xo && !(xo->flags & CRYPTO_DONE))) + kfree(ESP_SKB_CB(skb)->tmp); + + if (unlikely(err)) + goto out; + + err = esp_remove_trailer(skb); + if (unlikely(err < 0)) + goto out; + + skb_postpull_rcsum(skb, skb_network_header(skb), + skb_network_header_len(skb)); skb_pull_rcsum(skb, hlen); if (x->props.mode == XFRM_MODE_TUNNEL) skb_reset_transport_header(skb); else skb_set_transport_header(skb, -hdr_len); - err = nexthdr[1]; - /* RFC4303: Drop dummy packets without any error */ if (err == IPPROTO_NONE) err = -EINVAL; diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index f07eec5..2515cd2 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -247,6 +247,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) goto drop; } + if (xo->status & CRYPTO_INVALID_PROTOCOL) { + XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR); + goto drop; + } + XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR); goto drop; } -- 2.8.1