From patchwork Tue Jun 6 17:00:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Watson X-Patchwork-Id: 9769283 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C236160364 for ; Tue, 6 Jun 2017 17:00:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BCCDF284B5 for ; Tue, 6 Jun 2017 17:00:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B10CF284C6; Tue, 6 Jun 2017 17:00:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 95FC9284BB for ; Tue, 6 Jun 2017 17:00:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751404AbdFFRAy (ORCPT ); Tue, 6 Jun 2017 13:00:54 -0400 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:32970 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751388AbdFFRAv (ORCPT ); Tue, 6 Jun 2017 13:00:51 -0400 Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v56GxTCs010766; Tue, 6 Jun 2017 10:00:37 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=date : from : to : cc : subject : message-id : references : mime-version : content-type : in-reply-to; s=facebook; bh=z2inXJPqmHc5KzUCmn3DHNLii3XEjOPNVNE9W+AkzCs=; b=XNKc3vOrBr1v845kbK2btpC2zTIHmHTeEyUcawYkj1OTn/utgvjWC7gzPC4aB1Zxg/rv 2hA/zDnNE6gLbzoprsZYgeYNQtct/kZgsqzsD7jgrHPqoFlFnR1Lvep5YfaX9VymLmoS WrMLT349l8U+nqF3RY2DTThVimh8AzelfzI= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 2awwrs0ne8-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 06 Jun 2017 10:00:37 -0700 Received: from NAM02-SN1-obe.outbound.protection.outlook.com (192.168.54.28) by o365-in.thefacebook.com (192.168.16.14) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 6 Jun 2017 10:00:33 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.onmicrosoft.com; s=selector1-fb-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=z2inXJPqmHc5KzUCmn3DHNLii3XEjOPNVNE9W+AkzCs=; b=AChX6NHa4VWwAJzRJY62oAAoEvzfsTcK0hNnjDAYw6Tv3poOcSH6WoyTEMTMUuwUj2SIk/ez5TZw3SBEpBZosVzSM92YbfhdQ/MdIl2ddJNIqlcU0f/qkDGT3TXNld+ZjNgttLOkJBBgGJbxfK8t1ih++MwHNuywaN5g0whuP08= Authentication-Results: mellanox.com; dkim=none (message not signed) header.d=none; mellanox.com; dmarc=none action=none header.from=fb.com; Received: from localhost (2620:10d:c090:200::6:701f) by DM5PR15MB1756.namprd15.prod.outlook.com (10.174.246.138) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1143.10; Tue, 6 Jun 2017 17:00:31 +0000 Date: Tue, 6 Jun 2017 10:00:20 -0700 From: Dave Watson To: Ilya Lesokhin , Aviad Yehezkel , Boris Pismenny , Liran Liss , Matan Barak , David Miller , , Tom Herbert , , , Hannes Frederic Sowa , Eric Dumazet CC: Alexei Starovoitov , , Subject: [PATCH v2 net-next 1/4] tcp: ULP infrastructure Message-ID: <20170606170020.GA19182@davejwatson-mba.local> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.6.0 (2016-04-01) X-Originating-IP: [2620:10d:c090:200::6:701f] X-ClientProxiedBy: AM5PR0402CA0004.eurprd04.prod.outlook.com (10.175.37.14) To DM5PR15MB1756.namprd15.prod.outlook.com (10.174.246.138) X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM5PR15MB1756: X-MS-Office365-Filtering-Correlation-Id: 8a8a984c-743e-4888-cbc8-08d4acfd8a82 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201703131423075)(201703031133081); SRVR:DM5PR15MB1756; X-Microsoft-Exchange-Diagnostics: 1; DM5PR15MB1756; 3:nzmKZvqLBveri78IOtZ19pB+mtMJ9nK365e7InjS5+UATgOlp3oQMy3NQTkc0o61WBHCO9eDDyLlcMYQNq2t+Wf01c2MUiggeLRMfMPydT/KPOtzSF2R/8WVCHNm72ZONqeamne5sGZb9bYzCwLn0uyux0qTdGSg2UlqfDkX9dYbGMEiTv3dyilmrzU8nkYExSNpELdji8lJk9zvfAN0uFzclcUPiUDUmgpvdO43LgI19BwYDFlphYy5MS7o2fTKBHnR8UKxAawZSZD0EaVyYp72tvvsMBjUMXnKpEZxC5/3sPm9jYQ3aX3x3S/e/sftkspLeRmOAzL7X76Xg67crA==; 25:fjWUdVSJEaAgDcSv6nQe0zbWcHCIaqbmn39al1nrl+vLldtA5sXsUCzocxBzQ1u47Z68VxpPCDbWNZ9sCDGExD45pqcOc2E0qXoXyF1ab04aedBVuRMEMCwWrnjxmWrZW32bFVvYDREBngia/EIjL/kEPmj9yoo/f+In/8WFGu0GYLuqB3jXkOClt60L+G6TvjBETiyY+EhRUnyxZnOKUv5VMDvDtWouU67O95pj8GtI+b3OBKA9GZtxHaiVKdWcPJSzfZOyvd2+lqH7hBav6FelmqnhCGYzI4zoRg3wXSaUkqxv7ZJ2DZIPqHcSVg/fI97Hf/HVQWRltLoOK/jsVF7K1P9gZNHwfwOmEhvkGNyLP2gluc1E9CDRjlJKI8D54XzZX4b6SSjsmpF3q2HIJoKplvu6w7lu9KeBLLCxDaYT+ReEr/gOLDuRnuHnFYrDJaV3ljhPOyzVPuyDpedG4XiShgQd+nPep6P+UxFJ8y8= X-Microsoft-Exchange-Diagnostics: 1; DM5PR15MB1756; 31:1ILRIZTspCxN8Fr1qjD4fjfriqf0QbMQ3wVBUM5gTHK5+iw4DhcE5bBsG2d6LAWdCr34Pm7u8D7Qgt3YrGwLAW32H/N4mWipDrUvj+X3Ze2hPnnL+LmIxJedqZStX6gXHxBuGEVxDDHiST5XKJRByd7sCHujp7NyRmqP4RrP5XVzAeMUqdNKj2Y0Sda13UqggwWejYsnbt7CjZv8FXMXRF2tXrWkmU6n1+4pMf8PXD70y56iBa6K9tQ4tMhMyBb3d6sSblYWeU/OY8kL19qgPA==; 20:6d1HA5Il9RdgTmivn2TPU8xdsNobo27Pq7W7zTB1NSxyIcEJ2lvT5vMWu4BOyeNkbMO/d4zA/QkQqKHSgXS7+Z8Vj/pQW2mMRxCHql3rna/o8BOTM3JcFfQ4OEeHxSXIbKj8F/G98qKxfGsNWvqg8WL51xSNUqOil0+2OUtkPgIEzpPBzLyaO1wy+esOTRVtSWkzObvjpIjVOyeuimNMPefFSyyLXGpYr2vIdLw+JIMic60tpdci9x+BLsM7FFzM+2gw7RKQZ5XEdLlxSRkfABoWDqtBn04cHLOBdze6HJYk3xLqzL9/m29eHfP7HuRaM+VWZLAr/9eWZO/D0OS0OOGVdv856AEtlnI3rmQdTLNiKPiOsKwWCHIXi1mHOQn2tmsYG0Z0QhpAHMPvHlt+LqyfDYk5MZbl9QF3QIkbkmWNOFNdfHRQuS93K8mst8WdAqURRtcap/DMT/s+a3J02e4OHD85qyvUx2sp/2VEC1gEKdAR76mW5tvdGIC0UWvm X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(67672495146484)(21532816269658)(266576461109395); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(100000703101)(100105400095)(93006095)(93001095)(6041248)(20161123562025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123560025)(20161123558100)(20161123555025)(6072148)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:DM5PR15MB1756; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:DM5PR15MB1756; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM5PR15MB1756; 4:0VvHo3B/WtCSI0XhxVcDveyP7oPzMxuYGrROOQqPl1?= =?us-ascii?Q?1DqUGuBRWW7cDAZn/+U354ayAKViGjmqqk2pw/P7nsRwMa9w8EDZ4eIv0t7o?= =?us-ascii?Q?z9tWXgRHDNs22h7HqTtd2YdIhYI/YsxZ1X2EmhVmvoU3xMcPS89L+W9jn/Df?= =?us-ascii?Q?2Nk09OZ9tPa9Cic/Vynr3MA+ukcFr6GJTfU2YcuZjcZIbBY4ARokZ4NKTipp?= =?us-ascii?Q?QkEOOySZm4Fr9GKIdLYstew8i3jH3mzWYNx9ces41iYM29yYi/2CKf/M6E7D?= =?us-ascii?Q?/xRtDnEw4Q/puQ6VE/Wo08HBb2/bcMFHFAf/hP3An2IsxVS4jdvFV2UTK+38?= =?us-ascii?Q?xSjRCZSkdnBJjpNAKYX9YE96RT/e1fMegt0fXVOY/2MyvlKrNoeiFeA+/hHt?= =?us-ascii?Q?0BYvWeX8cusbkvTXkii/3UCQ9r4YMsoT2/HgJ4sNrlc6aQ6+WdBao7nfiziQ?= =?us-ascii?Q?R4MF/nVlx+I+6j5C/RwSJ3Grsl3oWs29xGjiQkcFWnu0fjQXLAztPIvvudCI?= =?us-ascii?Q?/A5ngFRHZtbNbyJJPD8D2Pb1ffzV4LryUdJQcJTAYcXDT7TjPkKHbOJshWRx?= =?us-ascii?Q?zGBhcNeUDalE30JHMG7ObKm+jrXeEePZqXw8HXnZAyPW/xaNpInbvT1iaUyE?= =?us-ascii?Q?kPNOfMbH0oU8zSxzI9LMF3ma+fZPU+uQAboiwyIcREUPBAFlZkB7wCAbBtE2?= =?us-ascii?Q?7k7kmQPlnFg95ua6su3gEiX8Kojtb12UUiJs0D514ACWrCS+A8RnRI5DXcna?= =?us-ascii?Q?Jl6nUjse+iqiUSBwQ3enYDLsAdELlzO7/YcpekImQgel5qFjRjiwNO6F/m1o?= =?us-ascii?Q?f1O52dV74ZcnL40WxOWA6VMWEDiycGDt0A6P/kXFX2yed/fK8o3kM+zyu1r9?= =?us-ascii?Q?/TXzmKFkJj5Q4Owzj5JlaOMUsLLG1jW0hYT60UVqjM8VucEZJQv9+ZW+S67B?= =?us-ascii?Q?Fc3Q3+NwFo//ok7wA5zw4oFUqvrJtnTeJ5lBA2exXNfdd51lP86jzZeA6q0t?= =?us-ascii?Q?Tb1JlqMfbURVZexJEGPYndKW4NCfU+AVAuu6Gy3yd2nL5F6hhBoocyZlTbKH?= =?us-ascii?Q?beDMf6GC7IkCpUqTX2xw2iMSgxQxJ1SmAKV09z4kkPiJEmuINeu2C+GGeyDQ?= =?us-ascii?Q?TIiFFKKNOBmuNIbBxhHldbd3utUwOH/cFIypPAm2M7Qcp69AsuPKizQL1l6x?= =?us-ascii?Q?dienmPzyRCj/PQJYbVUnkOZ34vNBwFvp8LEybaROQ/xjaUGq25/mx7RQ4PgT?= =?us-ascii?Q?d4B3SIJjeeHg29eM34XkgiuTBkJbivWKILOlCd?= X-Forefront-PRVS: 033054F29A X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(6069001)(39850400002)(39410400002)(39840400002)(39450400003)(39400400002)(6116002)(42186005)(83506001)(38730400002)(76506005)(2950100002)(1076002)(6486002)(86362001)(6496005)(9686003)(54356999)(305945005)(2906002)(7416002)(7736002)(33656002)(50986999)(5660300001)(8676002)(81166006)(189998001)(4001350100001)(53936002)(23726003)(6666003)(478600001)(76176999)(4326008)(25786009)(98436002)(47776003)(5890100001)(18370500001)(921003)(1121003); DIR:OUT; SFP:1102; SCL:1; SRVR:DM5PR15MB1756; H:localhost; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM5PR15MB1756; 23:NAYjHEz0+hTlUiiYRQK6qBI32F9danuGmZtnwuPjt?= =?us-ascii?Q?u28o6RZjuop1qO5Hc6kjpU3TCQ5GpJDCUbGKqYsNXSCFYHEGO2Ot7CBf0ZC0?= =?us-ascii?Q?Ru3BlUu/6aog0mhZOI7y9REFcNDUHeSncqFmTcNMpnAQVTFTP/r5kF+SaysS?= =?us-ascii?Q?ZTtTHvvXq2ztjp6TEyG230zXDxBNCIjUq+5JnN1dcOpIpE4IeFguGeSheded?= =?us-ascii?Q?Jqrl+79YQpcsi55vOf2l9y/uoGfibdPsNoBPwwr7xEmbj0bcoPTfh2qiebxc?= =?us-ascii?Q?pCx3nM+lN9ylFDQXRw8+CIpuZRk9SE8InDYKOufSwJYL2S6VQ/I6HfnX1hvO?= =?us-ascii?Q?X7r06vx+rumkjAdZp2jbKn3xbwpvhuTVDX5b+qfmOmc9jxavnCL5lvAJ7osg?= =?us-ascii?Q?IHB1QaCLblXAvBTRTuMLx+kK+8tJVCRoVM7N68H7XC7O6eJzbvcQuj+YS3SI?= =?us-ascii?Q?x6gAEwE3AKipM0OJXYFzqMPxrYH1meKbIP4qT57C2ijz0UTsVObcM6KFpwWe?= =?us-ascii?Q?PK8aINx5szaDvayfihs5dJVC37OcPon08nzps0YAwvN1MGT88dbv5ZGcS0GA?= =?us-ascii?Q?898I/4/ruEPpK2r6KtXnOjAfD7pjEFdo7Hz80Ip3I7W6d3m17DFSqE5djXqQ?= =?us-ascii?Q?3F5N55vn66FGEjrTH5Ozaw2znhczDTHgQrod8tECo3vAj0vwMskCI2XBEY/s?= =?us-ascii?Q?nnus3ndM7RpQfqDNTRXNJuyxLBCU0vTXnEIT791k/Um/qmRb4XVKD0AQTRgg?= =?us-ascii?Q?WQ9aLdyRDIR5zFjRG4qnv8ex7/NCT+kMRQqrn3+Pfnl8SKYJPAdxY9PxeoNL?= =?us-ascii?Q?0TUeLxfkzT8bOWRuLKWmeTLyeY2Bc7TRMloExePr4aPZvaepBZlaZzuZSCgG?= =?us-ascii?Q?c+NIR0QtDyMXIcsJ9vnJ5TTutIvT9VqyAoJ+JNPae8F/gPuyvp5gW64JYxTq?= =?us-ascii?Q?dS/pwDQmWRk5mNWzIL/ntpiMgUEXGBfpwZAmQtldLr6NXOZw0jfQfbv6vkc+?= =?us-ascii?Q?PAp+fRjx/ovY+hPlbABXsy80aj4WDaQA6agD9X9mk4f5K7rSuGGRlR5vtO1T?= =?us-ascii?Q?LQwPtSMhN47VLFPhXUvDa0CiCP/UdGrnyqZYjM0VBT+C1+FndLbJFBosFiZ0?= =?us-ascii?Q?pIICcbsAjw=3D?= X-Microsoft-Exchange-Diagnostics: 1; DM5PR15MB1756; 6:6AzmGTU1hibr2z6VmUrBpsqIezPocruO0FRrItARPMz9pqQOFgLqk74aftwsuXdc0N6ofMRn3W12UitORT22oTer8aDwm2DhCwVmMfkzhr8ErEImh43V//4CxvRMf0mRSblFFPmBMgZmZRGShSquHYeKBjqxxF5yArkbpu/uJJWrjyETk0OJJV6m4ToXrgXZA2hjuX00qktKUX+oPo2aa0tGj3FKN2QvuCBvwicLhnQD7Xx/ba8nQjUAeczGpq7Qal9HXqpKwC0SvLrlgyWokImGciDGtq5XHe3sibaIUeUCheTD/QoqSbXWzgylIUesc/wbbo1UQkhxyDYRKiyM9ng46Alr2ezwB+Zyl1QLPLW7+lJ9bUhxLPIB4NWPnnbQNXB329Dip8y29MoeiNNbT6K6mbvideMOr9tmU7vc+YFqtC/jvuhgOuoE+X80R04wuYaYslsO7rAjA6nEOXmkiLaDpysOc767/jYNrjjP9loyAEZ/bwJ/cAIdfYuHnDXyRUuSNrUnY9TrlsF+aKL7xw== X-Microsoft-Exchange-Diagnostics: 1; DM5PR15MB1756; 5:s02JjO1XbqJv6t5rO7Xz/0jaYxtGbcD2mgaeRHD61s4PJeuOFo0J0rynfqvd/aJMyrVTtEvZApCA8TUVbxR5P2BDK3FuzPjhjiA4N62/+I6qWOiDzLA8EnqoBUMC1dpacruV9PNvwwamyMJ5onhrug3oqaopvk8+57WL/otJ3yVbunt1qWe4qhovwuwTvqJvyBWThLBVS0xm1n5dpIqR79Jkv1Awrxbyi7dxrDJMv1GqLFTIwBQ2zZQheYXS1h+BB7/yT+TE4PGC8dp8I1/NmZ9akCM08ddhTc9qY0DBUYD1hbYbqN0BJffaC9S/Vd4cf0Y81driSGFO242sa7EVpmSYvYWJ0cvluLwxHWMVBqqBHUGgNSWwDgu/gk4y0eLfC66kS5931pVlJFRlvXhaDPbv8e0erFasAwaCPp70oGvwLG40X7TVb34Vt125B+n5FaypbTEX975/Q1jZHLrVMjDwR73chxQmBKmueVBofLw943we/SPNgzm+3W9UAnQo; 24:oCfpRqprbOz8Gp3Y17HxTcaTJCOB8j+isF5WvOd65jiWMPeUeRww5+d6Qj2Pqo0RkQ3d9yLMaxjODM9MBiLR8HyB1jX6Ca/fQohwvuztD7E= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM5PR15MB1756; 7:xRmhLMBXxOZQf9Qq0pHs4KFjj433cK2YqwcEzmttJvzC8Wx/irnOc6b0WVRERGikegfGwqt8SlrRnD/zfh/pky6wcIeN6/2u1BYM+blisYnuVFheQ42nMK8NmdqMUHL9W+oj+gL9qo6EMAB5O4uT6KDwrlvzMpYTEy+xX9tTTjsCKX5cIVRijYHb2wt5MDi12FS/KLUJAwauJbycjhxu95Gk8NYa25s5d9aBpdi4kSQhQaY8ikZENmrqFT1nflM3V8ERwCznRGP/Zd9eMDyonblaYj1PEOLNUh0KGay5yPnh0P0xFccFf1zZ95Dbghzw866zHZZzBmep4120hx4YEg==; 20:qr4Q1NILmLkvmtokHVsOt8N9/II3mPl+vnuNsxC0htVklyNyk/bGdi5V/XPf/lpGzfSGJsHpRPwPH2JcqmPGDUnIRX0DzU65E6ZD5WJ11RrCgPK0gDHvj4fjHrwGbXBLcNQFWM6MMDcbWpj2uHQFxOAX0iml2ZQYEmn+bcbZ3mo= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Jun 2017 17:00:31.0207 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR15MB1756 X-OriginatorOrg: fb.com X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-06-06_12:, , signatures=0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add the infrustructure for attaching Upper Layer Protocols (ULPs) over TCP sockets. Based on a similar infrastructure in tcp_cong. The idea is that any ULP can add its own logic by changing the TCP proto_ops structure to its own methods. Example usage: setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")); modules will call: tcp_register_ulp(&tcp_tls_ulp_ops); to register/unregister their ulp, with an init function and name. A list of registered ulps will be returned by tcp_get_available_ulp, which is hooked up to /proc. Example: $ cat /proc/sys/net/ipv4/tcp_available_ulp tls There is currently no functionality to remove or chain ULPs, but it should be possible to add these in the future if needed. Signed-off-by: Boris Pismenny Signed-off-by: Dave Watson --- include/net/inet_connection_sock.h | 4 ++ include/net/tcp.h | 25 +++++++ include/uapi/linux/tcp.h | 1 + net/ipv4/Makefile | 2 +- net/ipv4/sysctl_net_ipv4.c | 25 +++++++ net/ipv4/tcp.c | 28 ++++++++ net/ipv4/tcp_ipv4.c | 2 + net/ipv4/tcp_ulp.c | 134 +++++++++++++++++++++++++++++++++++++ 8 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 net/ipv4/tcp_ulp.c diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index c7a5779..13e4c89 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -75,6 +75,8 @@ struct inet_connection_sock_af_ops { * @icsk_pmtu_cookie Last pmtu seen by socket * @icsk_ca_ops Pluggable congestion control hook * @icsk_af_ops Operations which are AF_INET{4,6} specific + * @icsk_ulp_ops Pluggable ULP control hook + * @icsk_ulp_data ULP private data * @icsk_ca_state: Congestion control state * @icsk_retransmits: Number of unrecovered [RTO] timeouts * @icsk_pending: Scheduled timer event @@ -97,6 +99,8 @@ struct inet_connection_sock { __u32 icsk_pmtu_cookie; const struct tcp_congestion_ops *icsk_ca_ops; const struct inet_connection_sock_af_ops *icsk_af_ops; + const struct tcp_ulp_ops *icsk_ulp_ops; + void *icsk_ulp_data; unsigned int (*icsk_sync_mss)(struct sock *sk, u32 pmtu); __u8 icsk_ca_state:6, icsk_ca_setsockopt:1, diff --git a/include/net/tcp.h b/include/net/tcp.h index 82462db..fcc39f8 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1992,4 +1992,29 @@ static inline void tcp_listendrop(const struct sock *sk) enum hrtimer_restart tcp_pace_kick(struct hrtimer *timer); +/* + * Interface for adding Upper Level Protocols over TCP + */ + +#define TCP_ULP_NAME_MAX 16 +#define TCP_ULP_MAX 128 +#define TCP_ULP_BUF_MAX (TCP_ULP_NAME_MAX*TCP_ULP_MAX) + +struct tcp_ulp_ops { + struct list_head list; + + /* initialize ulp */ + int (*init)(struct sock *sk); + /* cleanup ulp */ + void (*release)(struct sock *sk); + + char name[TCP_ULP_NAME_MAX]; + struct module *owner; +}; +int tcp_register_ulp(struct tcp_ulp_ops *type); +void tcp_unregister_ulp(struct tcp_ulp_ops *type); +int tcp_set_ulp(struct sock *sk, const char *name); +void tcp_get_available_ulp(char *buf, size_t len); +void tcp_cleanup_ulp(struct sock *sk); + #endif /* _TCP_H */ diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index 38a2b07..8204dce 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h @@ -117,6 +117,7 @@ enum { #define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */ #define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */ #define TCP_FASTOPEN_CONNECT 30 /* Attempt FastOpen with connect */ +#define TCP_ULP 31 /* Attach a ULP to a TCP connection */ struct tcp_repair_opt { __u32 opt_code; diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index f83de23..afcb435 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -8,7 +8,7 @@ obj-y := route.o inetpeer.o protocol.o \ inet_timewait_sock.o inet_connection_sock.o \ tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \ - tcp_rate.o tcp_recovery.o \ + tcp_rate.o tcp_recovery.o tcp_ulp.o \ tcp_offload.o datagram.o raw.o udp.o udplite.o \ udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \ fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \ diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 86957e9..6a40837c 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -360,6 +360,25 @@ static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table, ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (write && ret == 0) tcp_fastopen_active_timeout_reset(); + + return ret; +} + +static int proc_tcp_available_ulp(struct ctl_table *ctl, + int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct ctl_table tbl = { .maxlen = TCP_ULP_BUF_MAX, }; + int ret; + + tbl.data = kmalloc(tbl.maxlen, GFP_USER); + if (!tbl.data) + return -ENOMEM; + tcp_get_available_ulp(tbl.data, TCP_ULP_BUF_MAX); + ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + kfree(tbl.data); + return ret; } @@ -707,6 +726,12 @@ static struct ctl_table ipv4_table[] = { .proc_handler = proc_dointvec_ms_jiffies, }, { + .procname = "tcp_available_ulp", + .maxlen = TCP_ULP_BUF_MAX, + .mode = 0444, + .proc_handler = proc_tcp_available_ulp, + }, + { .procname = "icmp_msgs_per_sec", .data = &sysctl_icmp_msgs_per_sec, .maxlen = sizeof(int), diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f7be94f..0aa72cd 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2461,6 +2461,24 @@ static int do_tcp_setsockopt(struct sock *sk, int level, release_sock(sk); return err; } + case TCP_ULP: { + char name[TCP_ULP_NAME_MAX]; + + if (optlen < 1) + return -EINVAL; + + val = strncpy_from_user(name, optval, + min_t(long, TCP_ULP_NAME_MAX - 1, + optlen)); + if (val < 0) + return -EFAULT; + name[val] = 0; + + lock_sock(sk); + err = tcp_set_ulp(sk, name); + release_sock(sk); + return err; + } default: /* fallthru */ break; @@ -3017,6 +3035,16 @@ static int do_tcp_getsockopt(struct sock *sk, int level, return -EFAULT; return 0; + case TCP_ULP: + if (get_user(len, optlen)) + return -EFAULT; + len = min_t(unsigned int, len, TCP_ULP_NAME_MAX); + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, icsk->icsk_ulp_ops->name, len)) + return -EFAULT; + return 0; + case TCP_THIN_LINEAR_TIMEOUTS: val = tp->thin_lto; break; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 191b2f7..c2f5538 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1860,6 +1860,8 @@ void tcp_v4_destroy_sock(struct sock *sk) tcp_cleanup_congestion_control(sk); + tcp_cleanup_ulp(sk); + /* Cleanup up the write buffer. */ tcp_write_queue_purge(sk); diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c new file mode 100644 index 0000000..e2beb80 --- /dev/null +++ b/net/ipv4/tcp_ulp.c @@ -0,0 +1,134 @@ +/* + * Pluggable TCP upper layer protocol support. + * + * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved. + * Copyright (c) 2016-2017, Dave Watson . All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(tcp_ulp_list_lock); +static LIST_HEAD(tcp_ulp_list); + +/* Simple linear search, don't expect many entries! */ +static struct tcp_ulp_ops *tcp_ulp_find(const char *name) +{ + struct tcp_ulp_ops *e; + + list_for_each_entry_rcu(e, &tcp_ulp_list, list) { + if (strcmp(e->name, name) == 0) + return e; + } + + return NULL; +} + +static const struct tcp_ulp_ops *__tcp_ulp_find_autoload(const char *name) +{ + const struct tcp_ulp_ops *ulp = NULL; + + rcu_read_lock(); + ulp = tcp_ulp_find(name); + +#ifdef CONFIG_MODULES + if (!ulp && capable(CAP_NET_ADMIN)) { + rcu_read_unlock(); + request_module("%s", name); + rcu_read_lock(); + ulp = tcp_ulp_find(name); + } +#endif + if (!ulp || !try_module_get(ulp->owner)) + ulp = NULL; + + rcu_read_unlock(); + return ulp; +} + +/* Attach new upper layer protocol to the list + * of available protocols. + */ +int tcp_register_ulp(struct tcp_ulp_ops *ulp) +{ + int ret = 0; + + spin_lock(&tcp_ulp_list_lock); + if (tcp_ulp_find(ulp->name)) { + pr_notice("%s already registered or non-unique name\n", + ulp->name); + ret = -EEXIST; + } else { + list_add_tail_rcu(&ulp->list, &tcp_ulp_list); + } + spin_unlock(&tcp_ulp_list_lock); + + return ret; +} +EXPORT_SYMBOL(tcp_register_ulp); + +void tcp_unregister_ulp(struct tcp_ulp_ops *ulp) +{ + spin_lock(&tcp_ulp_list_lock); + list_del_rcu(&ulp->list); + spin_unlock(&tcp_ulp_list_lock); + + synchronize_rcu(); +} +EXPORT_SYMBOL(tcp_unregister_ulp); + +/* Build string with list of available upper layer protocl values */ +void tcp_get_available_ulp(char *buf, size_t maxlen) +{ + struct tcp_ulp_ops *ulp_ops; + size_t offs = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(ulp_ops, &tcp_ulp_list, list) { + offs += snprintf(buf + offs, maxlen - offs, + "%s%s", + offs == 0 ? "" : " ", ulp_ops->name); + } + rcu_read_unlock(); +} + +void tcp_cleanup_ulp(struct sock *sk) +{ + struct inet_connection_sock *icsk = inet_csk(sk); + + if (!icsk->icsk_ulp_ops) + return; + + if (icsk->icsk_ulp_ops->release) + icsk->icsk_ulp_ops->release(sk); + module_put(icsk->icsk_ulp_ops->owner); +} + +/* Change upper layer protocol for socket */ +int tcp_set_ulp(struct sock *sk, const char *name) +{ + struct inet_connection_sock *icsk = inet_csk(sk); + const struct tcp_ulp_ops *ulp_ops; + int err = 0; + + if (icsk->icsk_ulp_ops) + return -EEXIST; + + ulp_ops = __tcp_ulp_find_autoload(name); + if (!ulp_ops) + err = -ENOENT; + else + err = ulp_ops->init(sk); + + if (err) + goto out; + + icsk->icsk_ulp_ops = ulp_ops; + out: + return err; +}