{"id":808548,"url":"http://patchwork.ozlabs.org/api/patches/808548/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/1504251046-17106-2-git-send-email-steffen.klassert@secunet.com/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1504251046-17106-2-git-send-email-steffen.klassert@secunet.com>","list_archive_url":null,"date":"2017-09-01T07:30:45","name":"[1/2] xfrm: Add support for network devices capable of removing the ESP trailer","commit_ref":null,"pull_url":null,"state":"accepted","archived":true,"hash":"3438041f6ab208fc95a02335cc4cbc243d3f0398","submitter":{"id":1442,"url":"http://patchwork.ozlabs.org/api/people/1442/?format=json","name":"Steffen Klassert","email":"steffen.klassert@secunet.com"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/1504251046-17106-2-git-send-email-steffen.klassert@secunet.com/mbox/","series":[{"id":963,"url":"http://patchwork.ozlabs.org/api/series/963/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=963","date":"2017-09-01T07:30:45","name":"[1/2] xfrm: Add support for network devices capable of removing the ESP trailer","version":1,"mbox":"http://patchwork.ozlabs.org/series/963/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/808548/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/808548/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":"ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xk9rz0hMDz9sMN\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri,  1 Sep 2017 17:30:59 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751545AbdIAHaz (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 1 Sep 2017 03:30:55 -0400","from a.mx.secunet.com ([62.96.220.36]:50304 \"EHLO a.mx.secunet.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1751498AbdIAHax (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tFri, 1 Sep 2017 03:30:53 -0400","from localhost (localhost [127.0.0.1])\n\tby a.mx.secunet.com (Postfix) with ESMTP id BCB5D2018C;\n\tFri,  1 Sep 2017 09:30:52 +0200 (CEST)","from a.mx.secunet.com ([127.0.0.1])\n\tby localhost (a.mx.secunet.com [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id YbqZMt6K2JKp; Fri,  1 Sep 2017 09:30:51 +0200 (CEST)","from mail-essen-01.secunet.de (mail-essen-01.secunet.de\n\t[10.53.40.204])\n\t(using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby a.mx.secunet.com (Postfix) with ESMTPS id 0754720189;\n\tFri,  1 Sep 2017 09:30:51 +0200 (CEST)","from gauss2.secunet.de (10.182.7.193) by mail-essen-01.secunet.de\n\t(10.53.40.204) with Microsoft SMTP Server id 14.3.361.1;\n\tFri, 1 Sep 2017 09:30:50 +0200","by gauss2.secunet.de (Postfix, from userid 1000) id 51366140299;\n\tFri,  1 Sep 2017 09:30:50 +0200 (CEST)"],"X-Virus-Scanned":"by secunet","From":"Steffen Klassert <steffen.klassert@secunet.com>","To":"David Miller <davem@davemloft.net>","CC":"Herbert Xu <herbert@gondor.apana.org.au>,\n\tSteffen Klassert <steffen.klassert@secunet.com>, <netdev@vger.kernel.org>","Subject":"[PATCH 1/2] xfrm: Add support for network devices capable of\n\tremoving the ESP trailer","Date":"Fri, 1 Sep 2017 09:30:45 +0200","Message-ID":"<1504251046-17106-2-git-send-email-steffen.klassert@secunet.com>","X-Mailer":"git-send-email 2.7.4","In-Reply-To":"<1504251046-17106-1-git-send-email-steffen.klassert@secunet.com>","References":"<1504251046-17106-1-git-send-email-steffen.klassert@secunet.com>","MIME-Version":"1.0","Content-Type":"text/plain","X-G-Data-MailSecurity-for-Exchange-State":"0","X-G-Data-MailSecurity-for-Exchange-Error":"0","X-G-Data-MailSecurity-for-Exchange-Sender":"23","X-G-Data-MailSecurity-for-Exchange-Server":"d65e63f7-5c15-413f-8f63-c0d707471c93","X-EXCLAIMER-MD-CONFIG":"2c86f778-e09b-4440-8b15-867914633a10","X-G-Data-MailSecurity-for-Exchange-Guid":"0F48F4C9-02FD-4504-BF0B-09919E00FB20","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"From: Yossi Kuperman <yossiku@mellanox.com>\n\nIn conjunction with crypto offload [1], removing the ESP trailer by\nhardware can potentially improve the performance by avoiding (1) a\ncache miss incurred by reading the nexthdr field and (2) the necessity\nto calculate the csum value of the trailer in order to keep skb->csum\nvalid.\n\nThis patch introduces the changes to the xfrm stack and merely serves\nas an infrastructure. Subsequent patch to mlx5 driver will put this to\na good use.\n\n[1] https://www.mail-archive.com/netdev@vger.kernel.org/msg175733.html\n\nSigned-off-by: Yossi Kuperman <yossiku@mellanox.com>\nSigned-off-by: Steffen Klassert <steffen.klassert@secunet.com>\n---\n include/net/xfrm.h    |  1 +\n net/ipv4/esp4.c       | 70 ++++++++++++++++++++++++++++++++++-----------------\n net/ipv6/esp6.c       | 51 ++++++++++++++++++++++++++-----------\n net/xfrm/xfrm_input.c |  5 ++++\n 4 files changed, 89 insertions(+), 38 deletions(-)","diff":"diff --git a/include/net/xfrm.h b/include/net/xfrm.h\nindex 9c7b70c..f002a2c 100644\n--- a/include/net/xfrm.h\n+++ b/include/net/xfrm.h\n@@ -1019,6 +1019,7 @@ struct xfrm_offload {\n #define\tCRYPTO_FALLBACK\t\t8\n #define\tXFRM_GSO_SEGMENT\t16\n #define\tXFRM_GRO\t\t32\n+#define\tXFRM_ESP_NO_TRAILER\t64\n \n \t__u32\t\t\tstatus;\n #define CRYPTO_SUCCESS\t\t\t\t1\ndiff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c\nindex 741acd7..3190005 100644\n--- a/net/ipv4/esp4.c\n+++ b/net/ipv4/esp4.c\n@@ -499,19 +499,59 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)\n \treturn esp_output_tail(x, skb, &esp);\n }\n \n+static inline int esp_remove_trailer(struct sk_buff *skb)\n+{\n+\tstruct xfrm_state *x = xfrm_input_state(skb);\n+\tstruct xfrm_offload *xo = xfrm_offload(skb);\n+\tstruct crypto_aead *aead = x->data;\n+\tint alen, hlen, elen;\n+\tint padlen, trimlen;\n+\t__wsum csumdiff;\n+\tu8 nexthdr[2];\n+\tint ret;\n+\n+\talen = crypto_aead_authsize(aead);\n+\thlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);\n+\telen = skb->len - hlen;\n+\n+\tif (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) {\n+\t\tret = xo->proto;\n+\t\tgoto out;\n+\t}\n+\n+\tif (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2))\n+\t\tBUG();\n+\n+\tret = -EINVAL;\n+\tpadlen = nexthdr[0];\n+\tif (padlen + 2 + alen >= elen) {\n+\t\tnet_dbg_ratelimited(\"ipsec esp packet is garbage padlen=%d, elen=%d\\n\",\n+\t\t\t\t    padlen + 2, elen - alen);\n+\t\tgoto out;\n+\t}\n+\n+\ttrimlen = alen + padlen + 2;\n+\tif (skb->ip_summed == CHECKSUM_COMPLETE) {\n+\t\tcsumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0);\n+\t\tskb->csum = csum_block_sub(skb->csum, csumdiff,\n+\t\t\t\t\t   skb->len - trimlen);\n+\t}\n+\tpskb_trim(skb, skb->len - trimlen);\n+\n+\tret = nexthdr[1];\n+\n+out:\n+\treturn ret;\n+}\n+\n int esp_input_done2(struct sk_buff *skb, int err)\n {\n \tconst struct iphdr *iph;\n \tstruct xfrm_state *x = xfrm_input_state(skb);\n \tstruct xfrm_offload *xo = xfrm_offload(skb);\n \tstruct crypto_aead *aead = x->data;\n-\tint alen = crypto_aead_authsize(aead);\n \tint hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);\n-\tint elen = skb->len - hlen;\n \tint ihl;\n-\tu8 nexthdr[2];\n-\tint padlen, trimlen;\n-\t__wsum csumdiff;\n \n \tif (!xo || (xo && !(xo->flags & CRYPTO_DONE)))\n \t\tkfree(ESP_SKB_CB(skb)->tmp);\n@@ -519,16 +559,10 @@ int esp_input_done2(struct sk_buff *skb, int err)\n \tif (unlikely(err))\n \t\tgoto out;\n \n-\tif (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))\n-\t\tBUG();\n-\n-\terr = -EINVAL;\n-\tpadlen = nexthdr[0];\n-\tif (padlen + 2 + alen >= elen)\n+\terr = esp_remove_trailer(skb);\n+\tif (unlikely(err < 0))\n \t\tgoto out;\n \n-\t/* ... check padding bits here. Silly. :-) */\n-\n \tiph = ip_hdr(skb);\n \tihl = iph->ihl * 4;\n \n@@ -569,22 +603,12 @@ int esp_input_done2(struct sk_buff *skb, int err)\n \t\t\tskb->ip_summed = CHECKSUM_UNNECESSARY;\n \t}\n \n-\ttrimlen = alen + padlen + 2;\n-\tif (skb->ip_summed == CHECKSUM_COMPLETE) {\n-\t\tcsumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0);\n-\t\tskb->csum = csum_block_sub(skb->csum, csumdiff,\n-\t\t\t\t\t   skb->len - trimlen);\n-\t}\n-\tpskb_trim(skb, skb->len - trimlen);\n-\n \tskb_pull_rcsum(skb, hlen);\n \tif (x->props.mode == XFRM_MODE_TUNNEL)\n \t\tskb_reset_transport_header(skb);\n \telse\n \t\tskb_set_transport_header(skb, -ihl);\n \n-\terr = nexthdr[1];\n-\n \t/* RFC4303: Drop dummy packets without any error */\n \tif (err == IPPROTO_NONE)\n \t\terr = -EINVAL;\ndiff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c\nindex 74bde20..7fb41b0 100644\n--- a/net/ipv6/esp6.c\n+++ b/net/ipv6/esp6.c\n@@ -461,29 +461,30 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)\n \treturn esp6_output_tail(x, skb, &esp);\n }\n \n-int esp6_input_done2(struct sk_buff *skb, int err)\n+static inline int esp_remove_trailer(struct sk_buff *skb)\n {\n \tstruct xfrm_state *x = xfrm_input_state(skb);\n \tstruct xfrm_offload *xo = xfrm_offload(skb);\n \tstruct crypto_aead *aead = x->data;\n-\tint alen = crypto_aead_authsize(aead);\n-\tint hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);\n-\tint elen = skb->len - hlen;\n-\tint hdr_len = skb_network_header_len(skb);\n+\tint alen, hlen, elen;\n \tint padlen, trimlen;\n \t__wsum csumdiff;\n \tu8 nexthdr[2];\n+\tint ret;\n \n-\tif (!xo || (xo && !(xo->flags & CRYPTO_DONE)))\n-\t\tkfree(ESP_SKB_CB(skb)->tmp);\n+\talen = crypto_aead_authsize(aead);\n+\thlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);\n+\telen = skb->len - hlen;\n \n-\tif (unlikely(err))\n+\tif (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) {\n+\t\tret = xo->proto;\n \t\tgoto out;\n+\t}\n \n \tif (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2))\n \t\tBUG();\n \n-\terr = -EINVAL;\n+\tret = -EINVAL;\n \tpadlen = nexthdr[0];\n \tif (padlen + 2 + alen >= elen) {\n \t\tnet_dbg_ratelimited(\"ipsec esp packet is garbage padlen=%d, elen=%d\\n\",\n@@ -491,26 +492,46 @@ int esp6_input_done2(struct sk_buff *skb, int err)\n \t\tgoto out;\n \t}\n \n-\t/* ... check padding bits here. Silly. :-) */\n-\n \ttrimlen = alen + padlen + 2;\n \tif (skb->ip_summed == CHECKSUM_COMPLETE) {\n-\t\tskb_postpull_rcsum(skb, skb_network_header(skb),\n-\t\t\t\t   skb_network_header_len(skb));\n \t\tcsumdiff = skb_checksum(skb, skb->len - trimlen, trimlen, 0);\n \t\tskb->csum = csum_block_sub(skb->csum, csumdiff,\n \t\t\t\t\t   skb->len - trimlen);\n \t}\n \tpskb_trim(skb, skb->len - trimlen);\n \n+\tret = nexthdr[1];\n+\n+out:\n+\treturn ret;\n+}\n+\n+int esp6_input_done2(struct sk_buff *skb, int err)\n+{\n+\tstruct xfrm_state *x = xfrm_input_state(skb);\n+\tstruct xfrm_offload *xo = xfrm_offload(skb);\n+\tstruct crypto_aead *aead = x->data;\n+\tint hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead);\n+\tint hdr_len = skb_network_header_len(skb);\n+\n+\tif (!xo || (xo && !(xo->flags & CRYPTO_DONE)))\n+\t\tkfree(ESP_SKB_CB(skb)->tmp);\n+\n+\tif (unlikely(err))\n+\t\tgoto out;\n+\n+\terr = esp_remove_trailer(skb);\n+\tif (unlikely(err < 0))\n+\t\tgoto out;\n+\n+\tskb_postpull_rcsum(skb, skb_network_header(skb),\n+\t\t\t   skb_network_header_len(skb));\n \tskb_pull_rcsum(skb, hlen);\n \tif (x->props.mode == XFRM_MODE_TUNNEL)\n \t\tskb_reset_transport_header(skb);\n \telse\n \t\tskb_set_transport_header(skb, -hdr_len);\n \n-\terr = nexthdr[1];\n-\n \t/* RFC4303: Drop dummy packets without any error */\n \tif (err == IPPROTO_NONE)\n \t\terr = -EINVAL;\ndiff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c\nindex f07eec5..2515cd2 100644\n--- a/net/xfrm/xfrm_input.c\n+++ b/net/xfrm/xfrm_input.c\n@@ -247,6 +247,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)\n \t\t\t\t\tgoto drop;\n \t\t\t\t}\n \n+\t\t\t\tif (xo->status & CRYPTO_INVALID_PROTOCOL) {\n+\t\t\t\t\tXFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);\n+\t\t\t\t\tgoto drop;\n+\t\t\t\t}\n+\n \t\t\t\tXFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);\n \t\t\t\tgoto drop;\n \t\t\t}\n","prefixes":["1/2"]}