From patchwork Wed Jun 8 15:03:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wilson Peng X-Patchwork-Id: 1640702 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=vmware.com header.i=@vmware.com header.a=rsa-sha256 header.s=selector2 header.b=R+feZllr; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LJ9WY6YbXz9s75 for ; Thu, 9 Jun 2022 01:05:13 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 0AC6941A34; Wed, 8 Jun 2022 15:05:09 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id eOoazpeZX3iO; Wed, 8 Jun 2022 15:05:06 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id B7D974177F; Wed, 8 Jun 2022 15:05:05 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 8775EC0039; Wed, 8 Jun 2022 15:05:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5BB11C002D for ; Wed, 8 Jun 2022 15:05:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 404E94177F for ; Wed, 8 Jun 2022 15:05:04 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PMLnX9UgG9Nv for ; Wed, 8 Jun 2022 15:05:00 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12on20625.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe5a::625]) by smtp4.osuosl.org (Postfix) with ESMTPS id 9F1BF40904 for ; Wed, 8 Jun 2022 15:05:00 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=aXF+B7AfQmnZcgRtxZqLJAsKU8Jff5O9of2U09B34Hug7LgcTFhT1CMCXThEUdMeVkumPFcVJnqykN8yxccxBiMaDixdY6Y1FfgTX45ZfC7a5XQpoa7eV7UQlGya9WOkK6CbFTuaWs+FlyMgtys2DA7Bp844fUeTbNUDh2G+3HgybJoXEwid6sLrE8/NBzte8rEAQUGY1vcv3b1kmL2zVVnQKe5jiMKayEcnKbC5CkiZX86C2GglmLswOl/2yjtg58otTOOE6v1tVk3ZdTRB8D6lYERVLw5Ghr+4Gvyllrmq2AIBET7i3h6Ic2cOFUCZuAyAIUsQ6nYh9hXRcpbS2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=UZUCEKKTwk2ngcqLh3ZxtE8/oeMzQ2KplTXTIuY2gSE=; b=T08ov/N1fKZH9lDYbcwxOr11BFaQ7q9eScX1wruokTOINVZT1XhJ4FSg6SGOj8lrz+6CygW9/jEcoCf+8baDjyxmVhSIYnve6B0Px7ePiZnQquXqFh+E+IUp3BCEf9HYQwqYMkzAdZJ2npZdTMF2j7jbkAu5P1r5aI00x9Kq5lDotFu77mJxUtkkUZNzlhLZKHbPdlHd30IJvjLlTYXWCQSUIY9SJptEtiIa7bRVKD10qVEOHXtMcQXV7rVF1xrWo6yPHyrBlWwm0da2pRNSBw0v25XjfJlkFIkTgAjG6rEWT0D/sAPuDjOdTmmiANMadXU2BahmnVq2SYNe2HpsxA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=vmware.com; dmarc=pass action=none header.from=vmware.com; dkim=pass header.d=vmware.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vmware.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UZUCEKKTwk2ngcqLh3ZxtE8/oeMzQ2KplTXTIuY2gSE=; b=R+feZllr7BpnI0RWWxoXo7VfyniVGJ94DqasHvJm4uBslmZfzb17E3HMKSn3QeI+p1mz0kdfux2iOUjN8SQM7HeT0SCHlCJhuZ9XhDfvnIl3kXAGe5u9At5sVcqJaTN3Pw/VUfL2C0bZRTFkKmHnTfvdkGPG0C7hWPOR0Wnv/cY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=vmware.com; Received: from SN6PR05MB5935.namprd05.prod.outlook.com (2603:10b6:805:100::18) by DM5PR05MB2986.namprd05.prod.outlook.com (2603:10b6:3:51::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5332.10; Wed, 8 Jun 2022 15:03:57 +0000 Received: from SN6PR05MB5935.namprd05.prod.outlook.com ([fe80::5899:85e4:d7bb:303d]) by SN6PR05MB5935.namprd05.prod.outlook.com ([fe80::5899:85e4:d7bb:303d%5]) with mapi id 15.20.5332.011; Wed, 8 Jun 2022 15:03:57 +0000 To: dev@openvswitch.org Date: Wed, 8 Jun 2022 23:03:39 +0800 Message-Id: <20220608150339.87756-1-svc.ovs-community@vmware.com> X-Mailer: git-send-email 2.30.1 (Apple Git-130) X-ClientProxiedBy: SG2PR01CA0196.apcprd01.prod.exchangelabs.com (2603:1096:4:189::23) To SN6PR05MB5935.namprd05.prod.outlook.com (2603:10b6:805:100::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c6a528c4-e800-4708-b417-08da49601bfc X-MS-TrafficTypeDiagnostic: DM5PR05MB2986:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: OF1taheQErTwd9pOpCzKgUpxMCRX7abonhWX81jLd8PD/RHPDXj+z5+mLFIjt6uaMcthRzf87AVR4/KLiSSUNOCe/e28sPJTiSd9thYmAcEU5ZuqJr0jCQrCFXf1OnSQYpv8j4oGDWHS1OAWyWcq5l3PUsMxigMzN9p7o5BA4kNPNaEyQstGmuQzHs3AjMayzLQPHyfBJzlgWTCUWdD8+P9whQqwZv9G28pvj02xOQ9oWUvklLRyFjXHlFHcxmcL4rS5Z2BdR2PuAo9JNgvFbEZ9iuv+4tyoUzKTkI7hbdRexC5bQm3dlHo/JUZfXwQJ/UoD+nubK+iDNrS2xF5HC0AsfLUfzhLzCaoCN/K2xj+C/dulZmSVzVxGkPybJto9kh07ghNuqm56tv4vVNaJtbszHifSZYdaTRVAzCR1BiOb6+44jkApqi1ulIvSrL803tUnuoO6nIu55upkuUxcoZRqCu2xES+i4dN+ZVSe0DRr1Q/pfVhkkGaTv0+3wJoC8BpGbW0J2obrUms1ti8nvej1BDQDlY7VFvoXx8cOJGMGr8Odx7FE+Y+bg9cydHwDS0gJMwF/T07+fyDfxLB2FNhNn7LJRqwrK9lgIZWwNG74wmgwnoIw3sFUVu0YicuL3RKUgObmxDeYOn4eEsEcErvEfZ+J+wR5hM9OWBaSTtDMMHpv4dAAmQo9F/mEoZZuMBuIJRTvYHj6IDfQJpMU6VBQoqMRH4mnW2o8BLqbXnIUGWVi9t8aBbk+qlo8pXe1SrZrrF3m0Cjlm7udVquEj1TMFSlN/D5bNfjrMVGM9r9F7wBOByEPe3WItdzSbkby X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SN6PR05MB5935.namprd05.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230001)(4636009)(366004)(107886003)(38100700002)(8676002)(52116002)(2616005)(66476007)(19627235002)(36756003)(6506007)(316002)(1076003)(30864003)(6512007)(86362001)(6666004)(5660300002)(508600001)(6916009)(83380400001)(66556008)(2906002)(4326008)(66946007)(8936002)(186003)(6486002)(966005)(43062005); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 2 X-MS-Exchange-AntiSpam-MessageData-0: Nr2kIXJ7SSd2PKWnMMlh6aWxNYy0eQ+OotRVMmcTxTcOxajL5WMUrXGfn5JC0wmQxtB9kSuibIO/74mLPpNY7BBe6g3lAlSX1NwUeWI79c6dE7k62UJ/r6p6V/T2LXQrhmhyenzTXNAWzA7dAz9pKud4wwvAV+xaVk7Gj6/7vBGLe1rRYxADvCEsbRdm8voWJpP4bQx/LnS87i0fK0zOzpkJ/qSktdvP6Wh+BPWhBKYOIU+qDPHigX2wHZMFPXe0omYfPCm1bQbRQoECYPOMM06KhNNTexg2LIKWyYA8sIq11M+lH4h29wE1UxxjdZ0K2YCneXR/SQ8uDc8H5H28y6FMIn3M0q1AKiW8FKhb+h7SMBghtxNxqd8KVNQPtMoTP386W4I6+b2JMQEkU+v8ExjyU8BvCujJoXwZlO/+pAqirstabB5WkAuT3SdZ3b902fv2Ye4bPIKl2KmZkGjee7RiD1ju+ESaQ3SbSeLtuJnSoTPY3/cZGv/ecmEtiKF4WLaBYIIO73dAXViqB/1Q0OUIShngdYncCb6NW3OigQ794Lr6fjX72LcogSkEtpMtjkOilmTZOlqz1gqlwrmNKnwYGsFa9+hAy+aIoFmffnn0wNEsuqoBFaiNfkMaWGqA85WDjQEhSqHFnCDMZUL7aCgcMwu/jH/gW+oa0Ntmgytm/N4NEkMGB1GKu5p3BnFlSRmJO73xpM2HkKArb6VZvs7/xYOQlc3ON9SnjYtvzrib1B0ib2i2c8Dsu2gOXe4ptPe1y6lPJBqqQTj8zdz7XuTelfUXbKUQcV68yVU1VRIhAGWkVz9EBqLWbJABG8yQSCvFLK+1lMLcjThW/G+TT7xIFuRAxgj3mIsWLAApcBurdsR//a9355XleN74zkm2dQbyDYQYmS0gnGU0hmqhVxaflOvV/E5btmzdO3F+Ux3T4+wGlFGF/BREeU128x6W4oOrnk57fNQx/7PtPeBxpRptzs6G7Lvt6h/91dvQ2LEN18jagAQ1QiEcyRoDvIXSWX2O7hjwNnzjHzphRM1d22FqMEZC94UdWCgUWLhD/WbRRI56PrxHbRBcx0+mbe5PFm6u31YoodAZ1Exo4tts1tL8XPK7ilCBXVotH5FUx4WqKx6M1UTAuiZgMbSoQNMgciH3tO60ltHINrEYwF66pVUcuuY2B8z8p0eAYZ4ey0mblhHq7VObiPZqHyZ4g2nLV9wVFGllI+ZpMKCzvuqIKFVHSgfIxJFC9+0vqq2B7eH03hISWvUXRbIebwfLZtmaY1KrqWqrJB+QcpdmoXRxBr6cHnxNCrD6TxdyfWZ+9eE08Ib9XGxJw12qJd4kgM1FRWU2pb49P7K4bUS3HI59tnB+2WiwAUmdK9g4rdJkg7CJooqxr86oNxMp7dRT65FUfMhDX1MtiA3mnG2S5TF29K4sKQ54eMJjJgyzTTcUJsFSDQeKVeFOVzfCO47yTzRuaFFw6jM+WkSLItoZOWEhAmRqAATUPVky60gt/VyFujfpkSJiXgm66JfqVaPPadbIiw62eEF5s6KixV6fBicBeYEa+EFWE6aZRT4NCDMz3TaM9pcsX1OIfINjSzyM7Y28DRMwCxWFuoJWN5+1CtddMzaVyCRFhOG2j2cr8ubC7DejinV1vzeY+kwVYuRCcOP3p3zehLLoxljcXTuxoxhUOWVAWZrrMnuBXtnbo/wriJTr0VumTmYK+1TFH8j3emer2ifsNFr4ePx98Ve8QHTvZgfu56lYtDeChM2I+zAfQZ4I7jop35WMVpBBRNamvFeywYGwLB24 X-MS-Exchange-AntiSpam-MessageData-1: FJvNwzLnjV8NsvtFuLVvKtuJi6d02slXYrE= X-OriginatorOrg: vmware.com X-MS-Exchange-CrossTenant-Network-Message-Id: c6a528c4-e800-4708-b417-08da49601bfc X-MS-Exchange-CrossTenant-AuthSource: SN6PR05MB5935.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Jun 2022 15:03:57.1267 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b39138ca-3cee-4b4a-a4d6-cd83d9dd62f0 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9R0qXYj4dV6bm0hBJovW00FX8X6FaOujAr6FKDfhRlIx4aHA1rvNq++XU6Xe7jsRIJiUpYPpaxPRtcBrKRLJLSDibMovjjlKKj2RxPHb5d8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR05MB2986 Cc: ldejing Subject: [ovs-dev] [PATCH v1 1/1] datapath-windows: Alg support for ftp and tftp in conntrack X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: ldejing via dev From: Wilson Peng Reply-To: ldejing Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: ldejing In this patch, mainly finished some remaining work of previous patch(53b75e91) about ipv6 conntrack. Tftp with alg mainly parse the tftp packet (IPv4/IPv6) and create the related connection. Ftp with alg mainly fixed some bugs in the IPv4/IPv6. Additionally, this patch includes some misc work for ipv6 conntrack: 1) Fix some bugs for Icmpv6 error code when use the "ct_state=+rel" as match field. 2) Test flow action like ct(nat([20::1]:40)) Test cases: 1) ftp ipv4/ipv6 use alg field in the normal and nat scenario. 2) tftp ipv4/ipv6 use alg field in the normal and nat scenario. 3) icmpv6 error code scenario, including ICMP6_PACKET_TOO_BIG, ICMP6_DST_UNREACH,ICMP6_TIME_EXCEEDED,ICMP6_PARAM_PROB Signed-off-by: ldejing --- Documentation/intro/install/windows.rst | 187 ++++++++++++++------ datapath-windows/automake.mk | 1 + datapath-windows/ovsext/Actions.c | 1 - datapath-windows/ovsext/Conntrack-ftp.c | 109 ++++++------ datapath-windows/ovsext/Conntrack-icmp.c | 6 +- datapath-windows/ovsext/Conntrack-related.c | 30 +++- datapath-windows/ovsext/Conntrack-tftp.c | 70 ++++++++ datapath-windows/ovsext/Conntrack.c | 81 +++++++-- datapath-windows/ovsext/Conntrack.h | 19 +- datapath-windows/ovsext/ovsext.vcxproj | 1 + include/windows/netinet/in.h | 1 + 11 files changed, 373 insertions(+), 133 deletions(-) create mode 100644 datapath-windows/ovsext/Conntrack-tftp.c diff --git a/Documentation/intro/install/windows.rst b/Documentation/intro/install/windows.rst index 0a392d781..8759d1263 100644 --- a/Documentation/intro/install/windows.rst +++ b/Documentation/intro/install/windows.rst @@ -852,32 +852,33 @@ related state. normal scenario Vif38(20::1, ofport:2)->Vif40(20:2, ofport:3) - Vif38Name="podvif38" - Vif40Name="podvif40" + Vif38Name="podvif70" + Vif40Name="Ethernet1" Vif38Port=2 - Vif38Address="20::1" - Vif38MacAddressCli="00-15-5D-F0-01-0b" + Vif38Address="20::88" Vif40Port=3 - Vif40Address="20::2" - Vif40MacAddressCli="00-15-5D-F0-01-0C" + Vif40Address="20::45" + Vif40MacAddressCli="00-50-56-98-9d-97" + Vif38MacAddressCli="00-15-5D-F0-01-0B" Protocol="tcp6" - > netsh int ipv6 set neighbors $Vif38Name $Vif40Address \ - $Vif40MacAddressCli - > netsh int ipv6 set neighbors $Vif40Name $Vif38Address \ - $Vif38MacAddressCli - > ovs-ofctl del-flows br-int --strict "table=0,priority=0" - > ovs-ofctl add-flow br-int "table=0,priority=1,$Protocol \ + > netsh int ipv6 set neighbors $Vif38Name $Vif40Address $Vif40MacAddressCli + > netsh int ipv6 set neighbors $Vif42Name $Vif38Ip $Vif38MacAddressCli + > ovs-ofctl del-flows br-test --strict "table=0,priority=0" + > ovs-ofctl add-flow br-test "table=0,priority=1,$Protocol actions=ct(table=1)" - > ovs-ofctl add-flow br-int "table=1,priority=1,ct_state=+new+trk-est, \ + > ovs-ofctl add-flow br-test "table=1,priority=1,tp_dst=21, $Protocol,\ + actions=ct(commit,table=2,alg=ftp)" + > ovs-ofctl add-flow br-test "table=1,priority=1,tp_src=21, $Protocol,\ + actions=ct(commit,table=2,alg=ftp)" + > ovs-ofctl add-flow br-test "table=1,priority=1, ct_state=+new+trk+rel,\ $Protocol,actions=ct(commit,table=2)" - > ovs-ofctl add-flow br-int "table=1,priority=1, \ - ct_state=-new+trk+est-rel, $Protocol,actions=ct(commit,table=2)" - > ovs-ofctl add-flow br-int "table=1,priority=1, \ - ct_state=-new+trk+est+rel, $Protocol,actions=ct(commit,table=2)" - > ovs-ofctl add-flow br-int "table=2,priority=1,ip6, \ - ipv6_dst=$Vif38Address,$Protocol,actions=output:$Vif38Port" - > ovs-ofctl add-flow br-int "table=2,priority=1,ip6, \ - ipv6_dst=$Vif40Address,$Protocol,actions=output:$Vif40Port" + > ovs-ofctl add-flow br-test "table=1,priority=1, ct_state=-new+trk+est+rel,\ + $Protocol,actions=ct(commit,table=2)" + > ovs-ofctl add-flow br-test "table=2,priority=1,ip6,ipv6_dst=$Vif38Address,\ + $Protocol,actions=output:$Vif38Port" + > ovs-ofctl add-flow br-test "table=2,priority=1,ip6,ipv6_dst=$Vif40Address,\ + $Protocol,actions=output:$Vif40Port" + :: @@ -885,45 +886,127 @@ related state. Vif38(20::1, ofport:2) -> nat address(20::9) -> Vif42(21::3, ofport:4) Due to not construct flow to return neighbor mac address, we set the neighbor mac address manually + Vif38Name="podvif70" + Vif42Name="Ethernet1" + Vif38Ip="20::88" Vif38Port=2 - Vif42Port=4 - Vif38Name="podvif38" - Vif42Name="podvif42" + Vif42Port=3 NatAddress="20::9" NatMacAddress="aa:bb:cc:dd:ee:ff" NatMacAddressForCli="aa-bb-cc-dd-ee-ff" Vif42Ip="21::3" - Vif38MacAddress="00:15:5D:F0:01:0B" - Vif42MacAddress="00:15:5D:F0:01:0D" + Vif38MacAddress="00:15:5D:F0:01:14" + Vif38MacAddressCli="00-15-5D-F0-01-14" + Vif42MacAddress="00:50:56:98:9d:97" Protocol="tcp6" - > netsh int ipv6 set neighbors $Vif38Name $NatAddress \ - $NatMacAddressForCli - > netsh int ipv6 set neighbors $Vif42Name $NatAddress \ - $NatMacAddressForCli - > ovs-ofctl del-flows br-int --strict "table=0,priority=0" - > ovs-ofctl add-flow br-int "table=0,priority=2,ipv6, \ - dl_dst=$NatMacAddress,ct_state=-trk,$Protocol \ - actions=ct(table=1,zone=456,nat)" - > ovs-ofctl add-flow br-int "table=0,priority=1,ipv6, \ - ct_state=-trk,ip6,$Protocol actions=ct(nat, zone=456,table=1)" - > ovs-ofctl add-flow br-int "table=1,ipv6,in_port=$Vif38Port, \ - ipv6_dst=$NatAddress,ct_state=+trk+new,$Protocol \ - actions=ct(commit,nat(dst=$Vif42Ip),zone=456, \ - exec(set_field:1->ct_mark)),mod_dl_src=$NatMacAddress, \ + netsh int ipv6 set neighbors $Vif38Name $NatAddress $NatMacAddressForCli + netsh int ipv6 set neighbors $Vif42Name $Vif38Ip $Vif38MacAddressCli + > ovs-ofctl del-flows br-test --strict "table=0,priority=0" + > ovs-ofctl add-flow br-test "table=0,priority=2,ipv6,ipv6_dst=$NatAddress,\ + ct_state=-trk,$Protocol actions=ct(table=1,zone=456)" + > ovs-ofctl add-flow br-test "table=0,priority=1,ipv6,ipv6_dst=$Vif38Ip,\ + ct_state=-trk,ip6,$Protocol actions=ct(zone=456,table=1)" + > ovs-ofctl add-flow br-test "table=1,priority=2,ipv6,in_port=$Vif38Port,\ + ipv6_dst=$NatAddress,ct_state=+trk-rel,tp_dst=21,$Protocol \ + actions=ct(commit,alg=ftp,nat(dst=$Vif42Ip),zone=456, \ + exec(set_field:1->ct_mark)),mod_dl_src=$NatMacAddress,\ mod_dl_dst=$Vif42MacAddress,output:$Vif42Port" - > ovs-ofctl add-flow br-int "table=1,ipv6,ct_state=+dnat,$Protocol, \ - action=resubmit(,2)" - > ovs-ofctl add-flow br-int "table=1,ipv6,ct_state=+trk+snat, \ - $Protocol,action=resubmit(,2)" - > ovs-ofctl add-flow br-int "table=1,ipv6,ct_state=+trk+rel,$Protocol, \ - action=resubmit(,2)" - > ovs-ofctl add-flow br-int "table=2,ipv6,in_port=$Vif38Port, \ - ipv6_dst=$Vif42Ip,$Protocol, actions=mod_dl_src=$NatMacAddress, \ - mod_dl_dst=$Vif42MacAddress,output:$Vif42Port" - > ovs-ofctl add-flow br-int "table=2,ipv6,in_port=$Vif42Port, \ - ct_state=-new+est,ct_mark=1,ct_zone=456,$Protocol, \ - actions=mod_dl_src=$NatMacAddress,mod_dl_dst=$Vif38MacAddress, \ + > ovs-ofctl add-flow br-test "table=1,priority=1,ipv6,ct_state=+trk-rel,\ + ipv6_dst=$Vif38Ip,$Protocol,action=ct(nat,alg=ftp,zone=456,table=2)" + > ovs-ofctl add-flow br-test "table=1,ipv6,ct_state=+trk+rel,\ + ipv6_dst=$NatAddress,$Protocol,action=ct(table=2,commit,nat(dst=$Vif42Ip),\ + zone=456, exec(set_field:1->ct_mark))" + > ovs-ofctl add-flow br-test "table=1,ipv6,ct_state=+trk+rel,$Protocol,\ + ipv6_dst=$Vif38Ip, action=ct(nat,zone=456,table=2)" + > ovs-ofctl add-flow br-test "table=2,ipv6,ipv6_dst=$Vif42Ip,$Protocol,\ + actions=mod_dl_src=$NatMacAddress, mod_dl_dst=$Vif42MacAddress,\ + output:$Vif42Port" + > ovs-ofctl add-flow br-test "table=2,ipv6,ipv6_dst=$Vif38Ip,\ + ct_state=-new+est,ct_mark=1,ct_zone=456,$Protocol,\ + actions=mod_dl_src=$NatMacAddress,mod_dl_dst=$Vif38MacAddress,\ output:$Vif38Port" + > ovs-ofctl add-flow br-test "table=2,ipv6,ipv6_dst=$Vif38Ip,ct_state=+new,\ + ct_mark=1,ct_zone=456,$Protocol,actions=mod_dl_src=$NatMacAddress,\ + mod_dl_dst=$Vif38MacAddress, output:$Vif38Port" + +Tftp same with ftp, it also contains a related connection, we could use +following follow test the tftp connection. + +:: + + normal scenario + Vif38Name="podvif70" + Vif40Name="Ethernet1" + Vif38Port=2 + Vif38Address="20::88" + Vif40Port=3 + Vif40Address="20::45" + Vif40MacAddressCli="00-50-56-98-9d-97" + Vif38MacAddressCli="00-15-5D-F0-01-14" + Protocol="udp6" + netsh int ipv6 set neighbors $Vif38Name $Vif40Address $Vif40MacAddressCli + netsh int ipv6 set neighbors $Vif40Name $Vif38Address $Vif38MacAddressCli + > ovs-ofctl del-flows br-test --strict "table=0,priority=0" + > ovs-ofctl add-flow br-test "table=0,priority=1,$Protocol, + ipv6_src=$Vif38Address actions=ct(table=1)" + > ovs-ofctl add-flow br-test "table=0,priority=1,$Protocol, + ipv6_src=$Vif40Address actions=ct(table=1)" + > ovs-ofctl add-flow br-test "table=1,priority=1,ct_state=+new+trk-est, + tp_dst=69,$Protocol,udp6 actions=ct(commit,alg=tftp,table=2)" + > ovs-ofctl add-flow br-test "table=1,priority=1,ct_state=-new+trk+est-rel,\ + udp6 $Protocol,actions=ct(commit,table=2)" + > ovs-ofctl add-flow br-test "table=1,priority=1,ct_state=-new+trk+est+rel,\ + $Protocol,actions=ct(commit,table=2)" + > ovs-ofctl add-flow br-test "table=1,priority=1,ct_state=+new+trk+rel,\ + $Protocol,actions=ct(commit,table=2)" + > ovs-ofctl add-flow br-test "table=2,priority=1,ip6,ipv6_dst=$Vif38Address,\ + $Protocol,actions=output:$Vif38Port" + > ovs-ofctl add-flow br-test "table=2,priority=1,ip6,ipv6_dst=$Vif40Address,\ + $Protocol,actions=output:$Vif40Port" + +:: + + nat scenario + Vif38Name="podvif70" + Vif42Name="Ethernet1" + Vif38Ip="20::88" + Vif38Port=2 + Vif42Port=3 + NatAddress="20::9" + NatMacAddress="aa:bb:cc:dd:ee:ff" + NatMacAddressForCli="aa-bb-cc-dd-ee-ff" + Vif42Ip="21::3" + Vif38MacAddress="00:15:5D:F0:01:14" + Vif38MacAddressCli="00-15-5D-F0-01-14" + Vif42MacAddress="00:50:56:98:9d:97" + Protocol="ip6" + netsh int ipv6 set neighbors $Vif38Name $NatAddress $NatMacAddressForCli + netsh int ipv6 set neighbors $Vif42Name $Vif38Ip $Vif38MacAddressCli + > ovs-ofctl del-flows br-test --strict "table=0,priority=0" + > ovs-ofctl add-flow br-test "table=0,priority=2,ipv6,dl_dst=$NatMacAddress,\ + ct_state=-trk,$Protocol actions=ct(table=1,zone=456)" + > ovs-ofctl add-flow br-test "table=0,priority=1,ipv6,ct_state=-trk,ip6,\ + $Protocol actions=ct(table=1,zone=456)" + > ovs-ofctl add-flow br-test "table=1,in_port=$Vif38Port,\ + ipv6_dst=$NatAddress,ct_state=+trk+new-rel,$Protocol,udp6\ + actions=ct(commit,alg=tftp,nat(dst=$Vif42Ip),zone=456,\ + exec(set_field:1->ct_mark)),mod_dl_src=$NatMacAddress,\ + mod_dl_dst=$Vif42MacAddress,output:$Vif42Port" + > ovs-ofctl add-flow br-test "table=1,ipv6,in_port=$Vif42Port,\ + ipv6_dst=$Vif38Ip,ct_state=+trk+rel-rpl,$Protocol\ + actions=ct(commit,nat(src=$NatAddress),zone=456,\ + exec(set_field:1->ct_mark)),mod_dl_src=$NatMacAddress,\ + mod_dl_dst=$Vif38MacAddress,output:$Vif38Port" + > ovs-ofctl add-flow br-test "table=1,ipv6,ct_state=+trk+rel+est+rpl,\ + $Protocol,action=ct(nat,table=2,zone=456)" + > ovs-ofctl add-flow br-test "table=2,ipv6,in_port=$Vif38Port,\ + ct_state=+rel+dnat,ipv6_dst=$Vif42Ip,$Protocol,\ + actions=mod_dl_src=$NatMacAddress,mod_dl_dst=$Vif42MacAddress,\ + output:$Vif42Port" + > ovs-ofctl add-flow br-test "table=2,ipv6,in_port=$Vif42Port,\ + ct_state=-new+est,$Protocol,actions=mod_dl_src=$NatMacAddress,\ + mod_dl_dst=$Vif38MacAddress,output:$Vif38Port" + .. note:: diff --git a/datapath-windows/automake.mk b/datapath-windows/automake.mk index 60b3d6033..a7012f870 100644 --- a/datapath-windows/automake.mk +++ b/datapath-windows/automake.mk @@ -14,6 +14,7 @@ EXTRA_DIST += \ datapath-windows/ovsext/BufferMgmt.c \ datapath-windows/ovsext/BufferMgmt.h \ datapath-windows/ovsext/Conntrack-ftp.c \ + datapath-windows/ovsext/Conntrack-tftp.c \ datapath-windows/ovsext/Conntrack-icmp.c \ datapath-windows/ovsext/Conntrack-other.c \ datapath-windows/ovsext/Conntrack-related.c \ diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c index 0f7f78932..9c1c17b21 100644 --- a/datapath-windows/ovsext/Actions.c +++ b/datapath-windows/ovsext/Actions.c @@ -2378,7 +2378,6 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext, } OvsExecuteHash(key, (const PNL_ATTR)a); - break; } diff --git a/datapath-windows/ovsext/Conntrack-ftp.c b/datapath-windows/ovsext/Conntrack-ftp.c index 066723685..6775496cf 100644 --- a/datapath-windows/ovsext/Conntrack-ftp.c +++ b/datapath-windows/ovsext/Conntrack-ftp.c @@ -122,12 +122,9 @@ OvsCtExtractNumbers(char *buf, *---------------------------------------------------------------------------- */ NDIS_STATUS -OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, - OvsFlowKey *key, - OVS_PACKET_HDR_INFO *layers, - UINT64 currentTime, - POVS_CT_ENTRY entry, - BOOLEAN request) +OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, OvsFlowKey *key, + OVS_PACKET_HDR_INFO *layers, UINT64 currentTime, + POVS_CT_ENTRY entry) { NDIS_STATUS status = NDIS_STATUS_SUCCESS; FTP_TYPE ftpType = 0; @@ -157,52 +154,51 @@ OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, OvsStrlcpy((char *)ftpMsg, (char *)buf, min(len, sizeof(ftpMsg))); char *req = NULL; - if (request) { - if ((len >= 5) && (OvsStrncmp("PORT", ftpMsg, 4) == 0)) { - ftpType = FTP_TYPE_ACTIVE; - req = ftpMsg + 4; - } else if ((len >= 5) && (OvsStrncmp("EPRT", ftpMsg, 4) == 0)) { - ftpType = FTP_EXTEND_TYPE_ACTIVE; - req = ftpMsg + 4; + if ((len >= 5) && (OvsStrncmp("PORT", ftpMsg, 4) == 0)) { + ftpType = FTP_TYPE_ACTIVE; + req = ftpMsg + 4; + } else if ((len >= 5) && (OvsStrncmp("EPRT", ftpMsg, 4) == 0)) { + ftpType = FTP_EXTEND_TYPE_ACTIVE; + req = ftpMsg + 4; + } + + if ((len >= 4) && (OvsStrncmp(FTP_PASV_RSP_PREFIX, ftpMsg, 3) == 0)) { + ftpType = FTP_TYPE_PASV; + /* There are various formats for PASV command. We try to support + * some of them. This has been addressed by RFC 2428 - EPSV. + * Eg: + * 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). + * 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2 + * 227 Entering Passive Mode. h1,h2,h3,h4,p1,p2 + * 227 =h1,h2,h3,h4,p1,p2 + */ + char *paren; + paren = strchr(ftpMsg, '('); + if (paren) { + req = paren + 1; + } else { + /* PASV command without ( */ + req = ftpMsg + 3; + } + } else if ((len >= 4) && ( + OvsStrncmp(FTP_EXTEND_PASV_RSP_PREFIX, ftpMsg, 3) == 0)) { + ftpType = FTP_EXTEND_TYPE_PASV; + /* The ftp extended passive mode only contain port info, ip address + * is same with the network protocol used by control connection. + * 229 Entering Extended Passive Mode (|||port|) + * */ + char *paren; + paren = strchr(ftpMsg, '|'); + if (paren) { + req = paren + 3; + } else { + /* Not a valid EPSV packet. */ + return NDIS_STATUS_INVALID_PACKET; } - } else { - if ((len >= 4) && (OvsStrncmp(FTP_PASV_RSP_PREFIX, ftpMsg, 3) == 0)) { - ftpType = FTP_TYPE_PASV; - /* There are various formats for PASV command. We try to support - * some of them. This has been addressed by RFC 2428 - EPSV. - * Eg: - * 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). - * 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2 - * 227 Entering Passive Mode. h1,h2,h3,h4,p1,p2 - * 227 =h1,h2,h3,h4,p1,p2 - */ - char *paren; - paren = strchr(ftpMsg, '('); - if (paren) { - req = paren + 1; - } else { - /* PASV command without ( */ - req = ftpMsg + 3; - } - } else if ((len >= 4) && (OvsStrncmp(FTP_EXTEND_PASV_RSP_PREFIX, ftpMsg, 3) == 0)) { - ftpType = FTP_EXTEND_TYPE_PASV; - /* The ftp extended passive mode only contain port info, ip address - * is same with the network protocol used by control connection. - * 229 Entering Extended Passive Mode (|||port|) - * */ - char *paren; - paren = strchr(ftpMsg, '|'); - if (paren) { - req = paren + 3; - } else { - /* Not a valid EPSV packet. */ - return NDIS_STATUS_INVALID_PACKET; - } - if (!(*req > '0' && * req < '9')) { - /* Not a valid port number. */ - return NDIS_STATUS_INVALID_PACKET; - } + if (!(*req > '0' && * req < '9')) { + /* Not a valid port number. */ + return NDIS_STATUS_INVALID_PACKET; } } @@ -226,8 +222,15 @@ OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, (arr[2] << 8) | arr[3]); port = ntohs(((arr[4] << 8) | arr[5])); - serverIp.ipv4 = ip; - clientIp.ipv4 = key->ipKey.nwDst; + if (ftpType == FTP_TYPE_ACTIVE) { + serverIp.ipv4 = key->ipKey.nwDst; + clientIp.ipv4 = ip; + } + + if (ftpType == FTP_TYPE_PASV) { + serverIp.ipv4 = ip; + clientIp.ipv4 = key->ipKey.nwDst; + } } else { if (ftpType == FTP_EXTEND_TYPE_ACTIVE) { /** In ftp active mode, we need to parse string like below: @@ -239,7 +242,7 @@ OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, char *nextHdr = NULL; int index = 0; int isIpv6AddressFamily = 0; - char ftpStr[1024] = {0x00}; + char ftpStr[512] = {0x00}; RtlCopyMemory(ftpStr, req, strlen(req)); for (curHdr = ftpStr; *curHdr != '|'; curHdr++); diff --git a/datapath-windows/ovsext/Conntrack-icmp.c b/datapath-windows/ovsext/Conntrack-icmp.c index 9221f8518..081eb73d9 100644 --- a/datapath-windows/ovsext/Conntrack-icmp.c +++ b/datapath-windows/ovsext/Conntrack-icmp.c @@ -78,7 +78,11 @@ OvsConntrackValidateIcmp6Packet(const ICMPHdr *icmp) return FALSE; } - return icmp->type == ICMP6_ECHO_REQUEST; + return icmp->type == ICMP6_ECHO_REQUEST || + icmp->type == ICMP6_PACKET_TOO_BIG || + icmp->type == ICMP6_DST_UNREACH || + icmp->type == ICMP6_TIME_EXCEEDED || + icmp->type == ICMP6_PARAM_PROB; } OVS_CT_ENTRY * diff --git a/datapath-windows/ovsext/Conntrack-related.c b/datapath-windows/ovsext/Conntrack-related.c index f985c7631..99b1553da 100644 --- a/datapath-windows/ovsext/Conntrack-related.c +++ b/datapath-windows/ovsext/Conntrack-related.c @@ -40,6 +40,7 @@ OvsCtRelatedKeyAreSame(OVS_CT_KEY incomingKey, OVS_CT_KEY entryKey) /* FTP PASV - Client initiates the connection from unknown port */ if ((incomingKey.dl_type == entryKey.dl_type) && (incomingKey.dl_type == htons(ETH_TYPE_IPV4)) && + (incomingKey.nw_proto == IPPROTO_TCP) && (incomingKey.dst.addr.ipv4 == entryKey.src.addr.ipv4) && (incomingKey.dst.port == entryKey.src.port) && (incomingKey.src.addr.ipv4 == entryKey.dst.addr.ipv4) && @@ -49,6 +50,7 @@ OvsCtRelatedKeyAreSame(OVS_CT_KEY incomingKey, OVS_CT_KEY entryKey) if ((incomingKey.dl_type == entryKey.dl_type) && (incomingKey.dl_type == htons(ETH_TYPE_IPV6)) && + (incomingKey.nw_proto == IPPROTO_TCP) && !memcmp(&(incomingKey.dst.addr.ipv6), &(entryKey.src.addr.ipv6), sizeof(incomingKey.dst.addr.ipv6)) && (incomingKey.dst.port == entryKey.src.port) && @@ -65,6 +67,7 @@ OvsCtRelatedKeyAreSame(OVS_CT_KEY incomingKey, OVS_CT_KEY entryKey) */ if ((incomingKey.dl_type == entryKey.dl_type) && (incomingKey.dl_type == htons(ETH_TYPE_IPV4)) && + (incomingKey.nw_proto == IPPROTO_TCP) && (incomingKey.src.addr.ipv4 == entryKey.src.addr.ipv4) && (incomingKey.dst.addr.ipv4 == entryKey.dst.addr.ipv4) && (incomingKey.dst.port == entryKey.dst.port) && @@ -74,6 +77,7 @@ OvsCtRelatedKeyAreSame(OVS_CT_KEY incomingKey, OVS_CT_KEY entryKey) if ((incomingKey.dl_type == entryKey.dl_type) && (incomingKey.dl_type == htons(ETH_TYPE_IPV6)) && + (incomingKey.nw_proto == IPPROTO_TCP) && !memcmp(&(incomingKey.src.addr.ipv6), &(entryKey.src.addr.ipv6), sizeof(incomingKey.src.addr.ipv6)) && !memcmp(&(incomingKey.dst.addr.ipv6), &(entryKey.dst.addr.ipv6), @@ -83,6 +87,31 @@ OvsCtRelatedKeyAreSame(OVS_CT_KEY incomingKey, OVS_CT_KEY entryKey) return TRUE; } + /* Tftp protocol */ + if ((incomingKey.dl_type == entryKey.dl_type) && + (incomingKey.dl_type == htons(ETH_TYPE_IPV4)) && + (incomingKey.nw_proto == IPPROTO_UDP) && + !memcmp(&(incomingKey.src.addr.ipv4), &(entryKey.src.addr.ipv4), + sizeof(incomingKey.src.addr.ipv4)) && + !memcmp(&(incomingKey.dst.addr.ipv4), &(entryKey.dst.addr.ipv4), + sizeof(incomingKey.dst.addr.ipv4)) && + (incomingKey.dst.port == entryKey.dst.port) && + (incomingKey.nw_proto == entryKey.nw_proto)) { + return TRUE; + } + + if ((incomingKey.dl_type == entryKey.dl_type) && + (incomingKey.dl_type == htons(ETH_TYPE_IPV6)) && + (incomingKey.nw_proto == IPPROTO_UDP) && + !memcmp(&(incomingKey.src.addr.ipv6), &(entryKey.src.addr.ipv6), + sizeof(incomingKey.src.addr.ipv6)) && + !memcmp(&(incomingKey.dst.addr.ipv6), &(entryKey.dst.addr.ipv6), + sizeof(incomingKey.dst.addr.ipv6)) && + (incomingKey.dst.port == entryKey.dst.port) && + (incomingKey.nw_proto == entryKey.nw_proto)) { + return TRUE; + } + return FALSE; } @@ -165,7 +194,6 @@ OvsCtRelatedEntryCreate(UINT8 ipProto, } UINT32 hash = OvsExtractCtRelatedKeyHash(&entry->key); - NdisAcquireRWLockWrite(ovsCtRelatedLockObj, &lockState, 0); InsertHeadList(&ovsCtRelatedTable[hash & CT_HASH_TABLE_MASK], &entry->link); diff --git a/datapath-windows/ovsext/Conntrack-tftp.c b/datapath-windows/ovsext/Conntrack-tftp.c new file mode 100644 index 000000000..b550e9742 --- /dev/null +++ b/datapath-windows/ovsext/Conntrack-tftp.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 VMware, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "Actions.h" +#include "Conntrack.h" +#include "PacketParser.h" +#include "Util.h" + +NDIS_STATUS +OvsCtHandleTftp(PNET_BUFFER_LIST curNbl, OvsFlowKey *key, + OVS_PACKET_HDR_INFO *layers, UINT64 currentTime, + POVS_CT_ENTRY entry) +{ + UDPHdr udpStorage; + const UDPHdr *udp = NULL; + struct ct_addr serverIp; + struct ct_addr clientIp; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + + udp = OvsGetUdp(curNbl, layers->l4Offset, &udpStorage); + if (!udp) { + return NDIS_STATUS_INVALID_PACKET; + } + + RtlZeroMemory(&serverIp, sizeof(serverIp)); + RtlZeroMemory(&clientIp, sizeof(clientIp)); + + if (OvsCtRelatedLookup(entry->key, currentTime)) { + return NDIS_STATUS_SUCCESS; + } + + if (layers->isIPv4) { + serverIp.ipv4 = key->ipKey.nwDst; + clientIp.ipv4 = key->ipKey.nwSrc; + status = OvsCtRelatedEntryCreate(key->ipKey.nwProto, + key->l2.dlType, + serverIp, + clientIp, + 0, + udp->source, + currentTime, + entry); + } else { + serverIp.ipv6 = key->ipv6Key.ipv6Dst; + clientIp.ipv6 = key->ipv6Key.ipv6Src; + status = OvsCtRelatedEntryCreate(key->ipv6Key.nwProto, + key->l2.dlType, + serverIp, + clientIp, + 0, + udp->source, + currentTime, + entry); + } + + return status; +} \ No newline at end of file diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c index 471bf961b..cec010f28 100644 --- a/datapath-windows/ovsext/Conntrack.c +++ b/datapath-windows/ovsext/Conntrack.c @@ -356,8 +356,8 @@ OvsCtEntryCreate(OvsForwardingContext *fwdCtx, const ICMPHdr *icmp; icmp = OvsGetIcmp(curNbl, layers->l4Offset, &storage); if (!OvsConntrackValidateIcmp6Packet(icmp)) { - if(icmp) { - OVS_LOG_TRACE("Invalid ICMP packet detected, icmp->type %u", + if (icmp) { + OVS_LOG_TRACE("Invalid ICMP6 packet detected, icmp->type %u", icmp->type); } state = OVS_CS_F_INVALID; @@ -874,13 +874,25 @@ OvsCtSetupLookupCtx(OvsFlowKey *flowKey, return NDIS_STATUS_INVALID_PACKET; } + /* It's only designed for unNat traffic, when reverse traffic comes, + * find the unNat table, if found the nat entry, based on the nat entry + * restore the conntrack, it will be stored in the ctx->key and then use the + * ctx->key lookup the conntrack table to find the corresponded + * entry with the traffic.*/ natEntry = OvsNatLookup(&ctx->key, TRUE); if (natEntry) { - /* Translate address first for reverse NAT */ + /* initial direction 20::1 -> 20::9, reverse direction 21::3 -> 20::1 + * 20::9 could be regarded as nat ip, before convert, ctx->key value + * is "21::3 -> 20::1", after convert, ctx->key value is + * "20::9->20::1" */ ctx->key = natEntry->ctEntry->key; OvsCtKeyReverse(&ctx->key); } else { - if (flowKey->l2.dlType == htons(ETH_TYPE_IPV4)) { + if (OvsNatLookup(&ctx->key, FALSE)) { + /* Do nothing here, this branch here used to exclude traffic + * described in https://github.com/openvswitch/ovs-issues/issues/237 + * */ + } else if (flowKey->l2.dlType == htons(ETH_TYPE_IPV4)) { OvsPickupCtTupleAsLookupKey(&(ctx->key), zone, flowKey); } } @@ -903,6 +915,18 @@ OvsDetectFtp6Packet(OvsFlowKey *key) { ntohs(key->ipv6Key.l4.tpSrc) == IPPORT_FTP)); } +static __inline BOOLEAN +OvsDetectTftpPacket(OvsFlowKey *key) { + return (key->ipKey.nwProto == IPPROTO_UDP && + (ntohs(key->ipKey.l4.tpDst) == IPPORT_TFTP)); +} + +static __inline BOOLEAN +OvsDetectTftp6Packet(OvsFlowKey *key) { + return (key->ipv6Key.nwProto == IPPROTO_UDP && + (ntohs(key->ipv6Key.l4.tpDst) == IPPORT_TFTP)); +} + /* *---------------------------------------------------------------------------- * OvsProcessConntrackEntry @@ -989,7 +1013,9 @@ OvsProcessConntrackEntry(OvsForwardingContext *fwdCtx, if (entry) { NdisAcquireSpinLock(&(entry->lock)); if ((layers->isIPv6 && key->ipv6Key.nwProto == IPPROTO_TCP) || - (!(layers->isIPv6) && key->ipKey.nwProto == IPPROTO_TCP)) { + (!(layers->isIPv6) && key->ipKey.nwProto == IPPROTO_TCP) || + (layers->isIPv6 && key->ipv6Key.nwProto == IPPROTO_UDP) || + (!(layers->isIPv6) && key->ipKey.nwProto == IPPROTO_UDP)) { /* Update the related bit if there is a parent */ if (entry->parent) { state |= OVS_CS_F_RELATED; @@ -1156,12 +1182,11 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx, NDIS_STATUS status = NDIS_STATUS_SUCCESS; BOOLEAN triggerUpdateEvent = FALSE; BOOLEAN entryCreated = FALSE; - BOOLEAN isFtpPacket = FALSE; - BOOLEAN isFtpRequestDirection = FALSE; POVS_CT_ENTRY entry = NULL; POVS_CT_ENTRY parent = NULL; PNET_BUFFER_LIST curNbl = fwdCtx->curNbl; OvsConntrackKeyLookupCtx ctx = { 0 }; + CT_HELPER_METHOD helpMethod = CT_HELPER_NONE; LOCK_STATE_EX lockStateTable; UINT64 currentTime; NdisGetCurrentSystemTime((LARGE_INTEGER *) ¤tTime); @@ -1241,32 +1266,52 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx, OvsCtSetMarkLabel(key, entry, mark, labels, &triggerUpdateEvent); + if (helper && RtlEqualMemory(helper, "ftp", sizeof("ftp"))) { + helpMethod = CT_HELPER_FTP; + } else if (helper && RtlEqualMemory(helper, "tftp", sizeof("tftp"))) { + helpMethod = CT_HELPER_TFTP; + } + + /* This code section was added to compatible with the old version, + * because old version regard all traffic to port 21 as ftp traffic, + * no need to add alg field in ct. Thus, the code was added to keep the + * same behavior for ftp and tftp.*/ if (layers->isIPv6) { - isFtpPacket = OvsDetectFtp6Packet(key); - if (ntohs(key->ipv6Key.l4.tpDst) == IPPORT_FTP) { - isFtpRequestDirection = TRUE; + if (OvsDetectFtp6Packet(key)) { + helpMethod = CT_HELPER_FTP; + } + + if (OvsDetectTftp6Packet(key)) { + helpMethod = CT_HELPER_TFTP; } } else { - isFtpPacket = OvsDetectFtpPacket(key); - if (ntohs(key->ipKey.l4.tpDst) == IPPORT_FTP) { - isFtpRequestDirection = TRUE; + if (OvsDetectFtpPacket(key)) { + helpMethod = CT_HELPER_FTP; + } + + if (OvsDetectTftpPacket(key)) { + helpMethod = CT_HELPER_TFTP; } } - if (isFtpPacket) { - /* FTP parser will always be loaded */ - status = OvsCtHandleFtp(curNbl, key, layers, currentTime, entry, - isFtpRequestDirection); + if (helpMethod == CT_HELPER_FTP) { + status = OvsCtHandleFtp(curNbl, key, layers, currentTime, entry); if (status != NDIS_STATUS_SUCCESS) { OVS_LOG_ERROR("Error while parsing the FTP packet"); } } + if (helpMethod == CT_HELPER_TFTP) { + status = OvsCtHandleTftp(curNbl, key, layers, currentTime, entry); + if (status != NDIS_STATUS_SUCCESS) { + OVS_LOG_ERROR("Error while parsing the TFTP packet"); + } + } + parent = entry->parent; /* The entry should have the same helper name with parent's */ if (!entry->helper_name && (helper || (parent && parent->helper_name))) { - helper = helper ? helper : parent->helper_name; entry->helper_name = OvsAllocateMemoryWithTag(strlen(helper) + 1, OVS_CT_POOL_TAG); diff --git a/datapath-windows/ovsext/Conntrack.h b/datapath-windows/ovsext/Conntrack.h index b68a54f30..deb51c0bc 100644 --- a/datapath-windows/ovsext/Conntrack.h +++ b/datapath-windows/ovsext/Conntrack.h @@ -80,6 +80,12 @@ typedef enum _NAT_ACTION { NAT_ACTION_DST_PORT = 1 << 4, } NAT_ACTION; +typedef enum _CT_HELPER_METHOD { + CT_HELPER_NONE = 0, + CT_HELPER_FTP = 1, + CT_HELPER_TFTP = 2, +} CT_HELPER_METHOD; + typedef struct _OVS_CT_KEY { struct ct_endpoint src; struct ct_endpoint dst; @@ -218,11 +224,10 @@ NDIS_STATUS OvsCtRelatedEntryCreate(UINT8 ipProto, UINT64 currentTime, POVS_CT_ENTRY parent); POVS_CT_ENTRY OvsCtRelatedLookup(OVS_CT_KEY key, UINT64 currentTime); - -NDIS_STATUS OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, - OvsFlowKey *key, - OVS_PACKET_HDR_INFO *layers, - UINT64 currentTime, - POVS_CT_ENTRY entry, - BOOLEAN request); +NDIS_STATUS OvsCtHandleFtp(PNET_BUFFER_LIST curNbl, OvsFlowKey *key, + OVS_PACKET_HDR_INFO *layers, UINT64 currentTime, + POVS_CT_ENTRY entry); +NDIS_STATUS OvsCtHandleTftp(PNET_BUFFER_LIST curNbl, OvsFlowKey *key, + OVS_PACKET_HDR_INFO *layers, UINT64 currentTime, + POVS_CT_ENTRY entry); #endif /* __OVS_CONNTRACK_H_ */ diff --git a/datapath-windows/ovsext/ovsext.vcxproj b/datapath-windows/ovsext/ovsext.vcxproj index 7a2cbd2de..6d959ce44 100644 --- a/datapath-windows/ovsext/ovsext.vcxproj +++ b/datapath-windows/ovsext/ovsext.vcxproj @@ -395,6 +395,7 @@ + diff --git a/include/windows/netinet/in.h b/include/windows/netinet/in.h index e4169994b..bae9f8cee 100644 --- a/include/windows/netinet/in.h +++ b/include/windows/netinet/in.h @@ -19,5 +19,6 @@ #define IPPROTO_GRE 47 #define IPPORT_FTP 21 +#define IPPORT_TFTP 69 #endif /* netinet/in.h */