From patchwork Wed Mar 20 14:39:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naveen Yerramneni X-Patchwork-Id: 1914131 X-Patchwork-Delegate: nusiddiq@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256 header.s=proofpoint20171006 header.b=rsNcUqKD; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256 header.s=selector1 header.b=lE/VQ5JQ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4V0B9F52c6z23r9 for ; Thu, 21 Mar 2024 01:41:05 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id A9182820B4; Wed, 20 Mar 2024 14:41:03 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id l_RCXq-3KSqM; Wed, 20 Mar 2024 14:40:58 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org BA0CE820C8 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256 header.s=proofpoint20171006 header.b=rsNcUqKD; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256 header.s=selector1 header.b=lE/VQ5JQ Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id BA0CE820C8; Wed, 20 Mar 2024 14:40:58 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9C7B4C0072; Wed, 20 Mar 2024 14:40:58 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 224BAC007C for ; Wed, 20 Mar 2024 14:40:57 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id A2C3F415B0 for ; Wed, 20 Mar 2024 14:40:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qkcQ4LFzg_81 for ; Wed, 20 Mar 2024 14:40:46 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=148.163.155.12; helo=mx0b-002c1b01.pphosted.com; envelope-from=naveen.yerramneni@nutanix.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org 9A2D4415BB Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=nutanix.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 9A2D4415BB Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256 header.s=proofpoint20171006 header.b=rsNcUqKD; dkim=pass (2048-bit key, unprotected) header.d=nutanix.com header.i=@nutanix.com header.a=rsa-sha256 header.s=selector1 header.b=lE/VQ5JQ Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) by smtp2.osuosl.org (Postfix) with ESMTPS id 9A2D4415BB for ; Wed, 20 Mar 2024 14:40:44 +0000 (UTC) Received: from pps.filterd (m0127843.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 42KBLa3L016812; Wed, 20 Mar 2024 07:40:43 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :content-transfer-encoding:content-type:mime-version; s= proofpoint20171006; bh=e1wXR3xIQzQTRQRbZ6jMc0GKvQ5htsugAB6VYi6uV CE=; b=rsNcUqKDI4Se3+BxkxryVkO1gRgEHA+hwUOyjMM+Mm78E/u3/Sf08ubJc YrR6XZVflBYu4on7KQ0Vdbw4G84Hn7XDGoQxFtLt7pfIQ9suCUPdRH8c3BL1CftT 1B3r+bN5nSeB2Zh/MthL233Vf5sMOIacLDTVLalD53bkwubMrNiXv+GhL7f5fhX6 Uc009cEVHEzO5QndHmbsqOkFL/71JKDf4rEWRwJMcIBAXPMx/4dGHCtYXZmhLqr8 0QkM1qpYA5i9+XjGj2j2dGCvwGK5f3dnd2jIKNMM99vqOdTzNBF+lfWHALHUkpvI POYoBQlfgeND/nisuLyjepivoDN1Q== Received: from nam10-dm6-obe.outbound.protection.outlook.com (mail-dm6nam10lp2100.outbound.protection.outlook.com [104.47.58.100]) by mx0b-002c1b01.pphosted.com (PPS) with ESMTPS id 3wyhqmstp1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 20 Mar 2024 07:40:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=B56ToG94hkvX5MYjp8YULPiETDjD/wpZdpnn93uNhn9abTII5CTCSAl1q59rkqXz5pLK7MSrNf+SvI60YWwTa3+o1FV/3iCwhQFWBJq4DVwds5oQsoB4rzYKrCcBwetyVda1WSyVJrQbk66Sp7A0j1YbnBzav0UfvO4KiryVeK0M89UTtIlsGTIQ5fe/Eho2Yl6U+sTCCyCdG8GCKlr7tqoQ2l7lvPv1lRTNbjRm7J6gmOsvUHcF3vjyheLkFJ01C/UutkKJ1vFkAhLW60gElW4vhlLVEWUFWZvAkvP+23s/gzTttVbuVQYXg5IoEgLhfF3Ax7piHnsN7BHpf6hOSA== 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=e1wXR3xIQzQTRQRbZ6jMc0GKvQ5htsugAB6VYi6uVCE=; b=i1bjMkpwx3c9X860ewhz0JdwxWJmYHN6P/PD3KbmtSCDbZ2ugEjAe8c9hMyChalsoPCaaIF38mX4Q30i+YGrfqWiWfLWetmbpK1H8r9WKgzYBFJyQOVc5mPNu7qlKVtdNznpA6svnrGV6U/wWVlY8kGfSU8fqsQ3hUehhXCmYimeXyswQDEJmA+4lssu/ZULm5q6qeWooYEKTtGu5o5KM7UprRWqokF5XYKzl+0aPpoqCjoCKJACZ1Q7Cm4I8woWbXTnxQTG+LT6ZY345UEhxX9yEnDAieGPoElYMrSFJGFUTic+hkEUbvCbgUvA3urIq7uup9+xmH4Z4s0T4owDfw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nutanix.com; dmarc=pass action=none header.from=nutanix.com; dkim=pass header.d=nutanix.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nutanix.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=e1wXR3xIQzQTRQRbZ6jMc0GKvQ5htsugAB6VYi6uVCE=; b=lE/VQ5JQZE3Nb/dyx/6P+dVfaE51MEP8qwrpeY7BQlSDEpDrEawcXri64/qxnBqtenLW8OD1WdPPfR2SU+7w+QeL2xxk+WsBxSjcRKwfAkyrZBv2vbxEX7xoXKEtMyl/txO5ozzxGN9z9+pJiTji61t1rYeH8ikkrJCdmaBHvS6y/TDrOCH8yQwPWLnpi3uYVBFYMeWpZC1881b7Fby6yd8mieRHvGNI18+KLB4CbYovnH7qHUSsfyloMTgBCzHTWVOHG2ZU+BI/XVZg9sq4Nji/mJvgNFfP8yyMl7uBRg04ONd9rGkXbdQ5khQdCz2mMzC5UGUaMkWMN/lXmD8foQ== Received: from SJ0PR02MB7808.namprd02.prod.outlook.com (2603:10b6:a03:326::16) by SJ2PR02MB9705.namprd02.prod.outlook.com (2603:10b6:a03:53d::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7386.31; Wed, 20 Mar 2024 14:40:41 +0000 Received: from SJ0PR02MB7808.namprd02.prod.outlook.com ([fe80::d95e:4ad8:aa24:7c4]) by SJ0PR02MB7808.namprd02.prod.outlook.com ([fe80::d95e:4ad8:aa24:7c4%3]) with mapi id 15.20.7386.025; Wed, 20 Mar 2024 14:40:41 +0000 From: Naveen Yerramneni To: dev@openvswitch.org Date: Wed, 20 Mar 2024 14:39:57 +0000 Message-Id: <20240320143958.39052-4-naveen.yerramneni@nutanix.com> X-Mailer: git-send-email 2.36.6 In-Reply-To: <20240320143958.39052-1-naveen.yerramneni@nutanix.com> References: <20240320143958.39052-1-naveen.yerramneni@nutanix.com> X-ClientProxiedBy: PH8PR15CA0005.namprd15.prod.outlook.com (2603:10b6:510:2d2::12) To SJ0PR02MB7808.namprd02.prod.outlook.com (2603:10b6:a03:326::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR02MB7808:EE_|SJ2PR02MB9705:EE_ X-MS-Office365-Filtering-Correlation-Id: 54262c7f-f5da-4dcc-57e2-08dc48ebb73a x-proofpoint-crosstenant: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PV3A5ug1UjNegiHc7Jb9EuGFjLQeEmqPcgrEmxWRJlHjUEw03YiQIUgndVN0eATmVUGy3Pv8iQvxhPYdBHmnQ1qKIyTWq1KxKRBLtmbXuhh/ur8brJPFb/xzWPjBgAvit3C2h2so7sLEq9YgZszTl01tX03ew+wwUgj2SBH2V4+yqyeUgi3/iROqDi6p1UhzXbCkkjAPQMjrZ+TBEHGuW/Hi2DsOQOmAyKtvGD/BLtsJCBOz/7gR6v2B/qEAdlmNBgUJpGgEz0vePQk+HvBWcw2JjfKLhMtFl5GUjlbVjHR0yFakNF6i1rnT88ttswKpGOW6jZTfRqcLkJBFlM7n7qS6nXoJoTc0IQa3ehloDvAKIPWFabdD9a1+bwroFdF+KS+iDQHDer2FbKVf/Cvosc6aFOey/mKm4/cxdj6U9S+G23n8KGfWybRKDfcRLUtHnZSqqeSje/Kk3PVCTjWGuP9YrAvhL3l3YyUh3det4eJgicXqwQ5NEfOn1DAybT57vMoHckR6penjN1YnDTgD6B81dGlIGfQn74EcCo85jb1tVxlC2eMZzHMFED24d9O1+MmMn6ZEkSmkMm8NkpBMevATz/je/z6ULU1oTgkj0Cxjo/F0AODsjDnbztZ93gi3a8MX0tJz/Ulo7pmKjR3kcFvF2q2dudxFRNOBsPPZMxQ3aK87orC2rXVX+YaiN0gaCQHG8wkAo1CHWXZh7n7WfEEGF7TOK4kJgCOfZuyvkfw= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR02MB7808.namprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(366007)(52116005)(1800799015)(376005)(38350700005); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: +HLkoL0P/3m+cZFt8zHcDLWexjwTgQbLYBFlfKvW/JC4/i5kR6wifCuh80J2PGkuW7k+vQT6fvL/H9dPFSlzvYAuNissli2vZ6hiAE4wtuaYiFhrBodl/Nh8BfA3gfQKo9IMmwqDVLzEqzyJkmZX/EiGykxzNmcocccLWmNaARKYHZp9XzvDDkrBuqleHCblvIGzLIWaXRV/cKPLgVpWlikM38VO4tbAANGRSVtYmPxmr+3cKuNukfvfknHkostIDD+R2+SnDHA0CoLWTrhqAgwaxV97x7hAdoBu9k5IuH4XFMwD7nkGYDQZKmcmHwxp2zYlEwg0D0/V7h57KMMRIjZpYrKW0N2Nwv3QefjrhrvxVxkt+oLFrfB0JprGmVYBDpqrwpK9Uu0QKwFdsK71QseVuZHVZfrr9u3WfEnAbEl0SOMoHLDWFKUxJE9B0tzmMorQsaYKBHBjMvM0UYsr4+Z1ZIU5xeHLP9AuDpgBuzPZY4h5fb9PahgPuyStzkBpMW1vxw1Sn8+lQuK1QuDMyfTXr8klYqT2MeJSdjwEuDZg3mvsoBeMk1a4pAFYq9PQW4vUkm35T5jjyUge/Adt4nUjqvUzi+bl3mmGNi3CIhHVF1lwPLSU++tvPeBILSnu8IFvBLE3jqz3KEs/aRKEW3+7LF0JibnLeLJWIFWBkKr9jC62C5CvtooP1yvFhrkTU7QIHwJRw/4tbjAnYgu7OVYnTUNx3VCAFnKzXmiteAJZH5t4OO1C3XE8z9AqD8mO32dS3CrCMi58M9Nl5V/bNc9ajghyCGN+PFNGYTuP2aX9UocmUAzOdD6ZG3fkKXS382NxC8K6teWwCxVGUbWNjHiV0rgaI+3sUO3cVTwZn/5r9czW1N64YAVERymfAqOTxmzAMVnHW8prU7yv6FNmjv/jrkr2qdOb4bwgcvaEL4ROLH69rPmTsV17/byA0lzL3WTUKPgRzA4XUAx+1A0Uy82Buce85SAN7JMOQ3Zs0UAPu3fu2bZHyb6vGA/NGqyNzLwmpGtcQLDqVbMqPDVYURufPZBneDAadcEZqnlWXVYYxIdJerwgh9yCarqMhMl9D0UDk8fTtKh6JVPR6/WKtz45ek2CjGpWMBjIfVQBuwwvNGvGQGOYNffhMcjwxbu01uqDLyGwfeYemUuwIoKNBqfezoyhYDsupO+dN6raYV+X221KUa1JI4B1ItoTLe0qOGlAqbEDlqxv6fk+moixnSTegB856ruumGYfaTe0BvEAL0DMI5S0xgitd+fgSZS+//IQuk4HGngwCgZrzv+8Mn9O/4uKliqDfm+zDeEGvuXSsuH8m+xET81j+s93Vl9X9A9ZngZ3r/NxkAnmvZC3y61yZMS700JB75Mx34DMIFEMPxbI1U42AJLnd+v8W08PVIoOo3N/cYUA7xnwNY7tzLxEeGyvpnz128Z8740zscb5FIOH2goNzE5zOulOh1VJgm1p0kZiAND8ntsDh471C70baAgHwcS/FtPxHoLoKu3wNXm+ttALeK6mDyvdE7Hcg1459VXrXXb3p3VMvMBw3NUQsLZkxFSbrn3CgqmVWExFBuv+qq9yA9aPqmFfdDS1QAejYeZCyS9Q/MD/sK5b8AVjTKolES2oUBaGcIoRSrs= X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: 54262c7f-f5da-4dcc-57e2-08dc48ebb73a X-MS-Exchange-CrossTenant-AuthSource: SJ0PR02MB7808.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Mar 2024 14:40:40.9948 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2oPx+FaEfuiuzj7lD9Py6JQfuH3LKU5KNhR/AEMkByYvP6Z9pQfqLil1AjGZhBuptTK4h2uZRkhsKtSsTY5lhZU/M2RysAIbSW28bjoO/AY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR02MB9705 X-Proofpoint-GUID: edfu1W2RX41qVCiqJg8pDRD5tcxZiyp6 X-Proofpoint-ORIG-GUID: edfu1W2RX41qVCiqJg8pDRD5tcxZiyp6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-20_10,2024-03-18_03,2023-05-22_02 X-Proofpoint-Spam-Reason: safe Cc: huzaifa.c@nutanix.com Subject: [ovs-dev] [PATCH OVN v5 3/4] northd: DHCP Relay Agent support for overlay IPv4 subnets. 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: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" NB SCHEMA CHANGES ----------------- 1. New DHCP_Relay table "DHCP_Relay": { "columns": { "name": {"type": "string"}, "servers": {"type": {"key": "string", "min": 0, "max": 1}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, "options": {"type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, "isRoot": true}, 2. New column to Logical_Router_Port table "dhcp_relay": {"type": {"key": {"type": "uuid", "refTable": "DHCP_Relay", "refType": "strong"}, "min": 0, "max": 1}}, NEW PIPELINE STAGES ------------------- Following stage is added for DHCP relay feature. Some of the flows are fitted into the existing pipeline tages. 1. lr_in_dhcp_relay_req - This stage process the DHCP request packets coming from DHCP clients. - DHCP request packets for which dhcp_relay_req_chk action (which gets applied in ip input stage) is successful are forwarded to DHCP server. - DHCP request packets for which dhcp_relay_req_chk action is unsuccessful gets dropped. 2. lr_in_dhcp_relay_resp_chk - This stage applied the dhcp_relay_resp_chk action for DHCP response packets coming from the DHCP server. 3. lr_in_dhcp_relay_resp - DHCP response packets for which dhcp_relay_resp_chk is sucessful are forwarded to the DHCP clients. - DHCP response packets for which dhcp_relay_resp_chk is unsucessful gets dropped. REGISTRY USAGE --------------- - reg9[7] : To store the result of dhcp_relay_req_chk action. - reg9[8] : To store the result of dhcp_relay_resp_chk action. - reg2 : To store the original dest ip for DHCP response packets. This is required to properly match the packets in lr_in_dhcp_relay_resp stage since dhcp_relay_resp_chk action changes the dest ip. FLOWS ----- Following are the flows added when DHCP Relay is configured on one overlay subnet, one additonal flow is added in ls_in_l2_lkup table for each VM part of the subnet. 1. table=27(ls_in_l2_lkup ), priority=100 , match=(inport == && eth.src == && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67), action=(eth.dst=;outport=;next;/* DHCP_RELAY_REQ */) 2. table=3 (lr_in_ip_input ), priority=110 , match=(inport == && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && ip.frag == 0 && udp.src == 68 && udp.dst == 67), action=(reg9[7] = dhcp_relay_req_chk(, );next; /* DHCP_RELAY_REQ */) 3. table=3 (lr_in_ip_input ), priority=110 , match=(ip4.src == && ip4.dst == && udp.src == 67 && udp.dst == 67), action=(next;/* DHCP_RELAY_RESP */) 4. table=4 (lr_in_dhcp_relay_req), priority=100 , match=(inport == "lrp1" && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67 && reg9[7]), action=(ip4.src=;ip4.dst=;udp.src=67;next; /* DHCP_RELAY_REQ */) 5. table=4 (lr_in_dhcp_relay_req), priority=1 , match=(inport == && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67 && reg9[7] == 0), action=(drop; /* DHCP_RELAY_REQ */) 6. table=18(lr_in_dhcp_relay_resp_chk), priority=100 , match=(ip4.src == && ip4.dst == && ip.frag == 0 && udp.src == 67 && udp.dst == 67), action=(reg2 = ip4.dst;reg9[8] = dhcp_relay_resp_chk(, );next;/* DHCP_RELAY_RESP */) 7. table=19(lr_in_dhcp_relay_resp), priority=100 , match=(ip4.src == && reg2 == && udp.src == 67 && udp.dst == 67 && reg9[8]), action=(ip4.src=;udp.dst=68;outport=;output; /* DHCP_RELAY_RESP */) 8. table=19(lr_in_dhcp_relay_resp), priority=1 , match=(ip4.src == && reg2 == && udp.src == 67 && udp.dst == 67 && reg9[8] == 0), action=(drop; /* DHCP_RELAY_RESP */) Commands to enable the feature ------------------------------ ovn-nbctl create DHCP_Relay name= servers= ovn-nbctl set Logical_Router_port dhcp_relay= ovn-nbctl set Logical_Switch other_config:dhcp_relay_port= Limitations: ------------ - All OVN features that needs IP address to be configured on logical port (like proxy arp, etc) will not be supported for overlay subnets on which DHCP relay is enabled. Signed-off-by: Naveen Yerramneni Co-authored-by: Huzaifa Calcuttawala Signed-off-by: Huzaifa Calcuttawala CC: Mary Manohar --- northd/northd.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++- northd/northd.h | 41 +++---- ovn-nb.ovsschema | 19 +++- ovn-nb.xml | 39 +++++++ tests/ovn.at | 2 +- 5 files changed, 349 insertions(+), 23 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 1839b7d8b..3c5372691 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -91,7 +91,6 @@ static bool use_ct_inv_match = true; static bool default_acl_drop; #define MAX_OVN_TAGS 4096 - /* Due to various hard-coded priorities need to implement ACLs, the * northbound database supports a smaller range of ACL priorities than @@ -153,6 +152,8 @@ static bool default_acl_drop; #define REGBIT_LOOKUP_NEIGHBOR_IP_RESULT "reg9[3]" #define REGBIT_DST_NAT_IP_LOCAL "reg9[4]" #define REGBIT_KNOWN_LB_SESSION "reg9[6]" +#define REGBIT_DHCP_RELAY_REQ_CHK "reg9[7]" +#define REGBIT_DHCP_RELAY_RESP_CHK "reg9[8]" /* Register to store the eth address associated to a router port for packets * received in S_ROUTER_IN_ADMISSION. @@ -168,6 +169,7 @@ static bool default_acl_drop; #define REG_NEXT_HOP_IPV6 "xxreg0" #define REG_SRC_IPV4 "reg1" #define REG_SRC_IPV6 "xxreg1" +#define REG_DHCP_RELAY_DIP_IPV4 "reg2" #define REG_ROUTE_TABLE_ID "reg7" /* Register used to store backend ipv6 address @@ -232,7 +234,7 @@ static bool default_acl_drop; * | R1 | SRC_IPV4 for ARP-REQ | 0 | | R | | * | | (>= IP_INPUT) | | | E | NEXT_HOP_IPV6 (>= DEFRAG ) | * +-----+---------------------------+---+-----------------+ G | | - * | R2 | UNUSED | X | | 0 | | + * | R2 REG_DHCP_RELAY_DIP_IPV4 | X | | 0 | | * | | | R | | | | * +-----+---------------------------+ E | UNUSED | | | * | R3 | UNUSED | G | | | | @@ -259,7 +261,9 @@ static bool default_acl_drop; * | | EGRESS_LOOPBACK/ | G | UNUSED | * | R9 | PKT_LARGER/ | 4 | | * | | LOOKUP_NEIGHBOR_RESULT/ | | | - * | | SKIP_LOOKUP_NEIGHBOR} | | | + * | | SKIP_LOOKUP_NEIGHBOR/ | | | + * | |REGBIT_DHCP_RELAY_REQ_CHK/ | | | + * | |REGBIT_DHCP_RELAY_RESP_CHK}| | | * | | | | | * | | REG_ORIG_TP_DPORT_ROUTER | | | * | | | | | @@ -8555,6 +8559,90 @@ build_dhcpv6_options_flows(struct ovn_port *op, ds_destroy(&match); } +static const char * +ls_dhcp_relay_port(const struct ovn_datapath *od) +{ + return smap_get(&od->nbs->other_config, "dhcp_relay_port"); +} + +static void +build_lswitch_dhcp_relay_flows(struct ovn_port *op, + const struct hmap *ls_ports, + struct lflow_table *lflows, + struct ds *match, + struct ds *actions) +{ + if (op->nbrp || !op->nbsp) { + return; + } + + /* consider only ports attached to VMs */ + if (strcmp(op->nbsp->type, "")) { + return; + } + + if (!op->od || !op->od->n_router_ports || + !op->od->nbs) { + return; + } + + /* configure dhcp relay flows only when peer router has + * relay config enabled */ + const char *dhcp_relay_port = ls_dhcp_relay_port(op->od); + if (!dhcp_relay_port) { + return; + } + + struct ovn_port *sp = ovn_port_find(ls_ports, dhcp_relay_port); + + if (!sp || !sp->nbsp || !sp->peer) { + return; + } + + struct ovn_port *rp = sp->peer; + if (!rp || !rp->nbrp || !rp->nbrp->dhcp_relay || rp->peer != sp) { + return; + } + + char *server_ip_str = NULL; + uint16_t port; + int addr_family; + struct in6_addr server_ip; + struct nbrec_dhcp_relay *dhcp_relay = rp->nbrp->dhcp_relay; + + if (!ip_address_and_port_from_lb_key(dhcp_relay->servers, &server_ip_str, + &server_ip, &port, &addr_family)) { + return; + } + + if (server_ip_str == NULL) { + return; + } + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "inport == %s && eth.src == %s && " + "ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && " + "udp.src == 68 && udp.dst == 67", + op->json_key, op->lsp_addrs[0].ea_s); + ds_put_format(actions, + "eth.dst=%s;outport=%s;next;/* DHCP_RELAY_REQ */", + rp->lrp_networks.ea_s,sp->json_key); + ovn_lflow_add_with_hint__(lflows, op->od, + S_SWITCH_IN_L2_LKUP, 100, + ds_cstr(match), + ds_cstr(actions), + op->key, + NULL, + &op->nbsp->header_, + op->lflow_ref); + ds_clear(match); + ds_clear(actions); + free(server_ip_str); +} + static void build_drop_arp_nd_flows_for_unbound_router_ports(struct ovn_port *op, const struct ovn_port *port, @@ -9156,6 +9244,13 @@ build_lswitch_dhcp_options_and_response(struct ovn_port *op, return; } + if (op->od && op->od->nbs + && ls_dhcp_relay_port(op->od)) { + /* Don't add the DHCP server flows if DHCP Relay is enabled on the + * logical switch. */ + return; + } + bool is_external = lsp_is_external(op->nbsp); if (is_external && (!op->od->n_localnet_ports || !op->nbsp->ha_chassis_group)) { @@ -13611,6 +13706,166 @@ build_dhcpv6_reply_flows_for_lrouter_port( } } +static void +build_dhcp_relay_flows_for_lrouter_port( + struct ovn_port *op, struct lflow_table *lflows, + struct ds *match, struct ds *actions, + struct lflow_ref *lflow_ref) +{ + if (!op->nbrp || !op->nbrp->dhcp_relay) { + return; + + } + + /* configure dhcp relay flows only when peer switch has + * relay config enabled */ + struct ovn_port *sp = op->peer; + if (!sp || !sp->nbsp || sp->peer != op || + !sp->od || !ls_dhcp_relay_port(sp->od)) { + return; + } + + struct nbrec_dhcp_relay *dhcp_relay = op->nbrp->dhcp_relay; + if (!dhcp_relay->servers) { + return; + } + + int addr_family; + /* currently not supporting custom port, + * dhcp server port is always set to 67 when installing flows */ + uint16_t port; + char *server_ip_str = NULL; + struct in6_addr server_ip; + + if (!ip_address_and_port_from_lb_key(dhcp_relay->servers, &server_ip_str, + &server_ip, &port, &addr_family)) { + return; + } + + if (server_ip_str == NULL) { + return; + } + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "inport == %s && " + "ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && " + "ip.frag == 0 && udp.src == 68 && udp.dst == 67", + op->json_key); + ds_put_format(actions, + REGBIT_DHCP_RELAY_REQ_CHK + " = dhcp_relay_req_chk(%s, %s);" + "next; /* DHCP_RELAY_REQ */", + op->lrp_networks.ipv4_addrs[0].addr_s, server_ip_str); + + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "inport == %s && " + "ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && " + "udp.src == 68 && udp.dst == 67 && " + REGBIT_DHCP_RELAY_REQ_CHK, + op->json_key); + ds_put_format(actions, + "ip4.src=%s;ip4.dst=%s;udp.src=67;next; /* DHCP_RELAY_REQ */", + op->lrp_networks.ipv4_addrs[0].addr_s, server_ip_str); + + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_DHCP_RELAY_REQ, 100, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "inport == %s && " + "ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && " + "udp.src == 68 && udp.dst == 67 && " + REGBIT_DHCP_RELAY_REQ_CHK" == 0", + op->json_key); + ds_put_format(actions, + "drop; /* DHCP_RELAY_REQ */"); + + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_DHCP_RELAY_REQ, 1, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "ip4.src == %s && ip4.dst == %s && " + "ip.frag == 0 && udp.src == 67 && udp.dst == 67", + server_ip_str, op->lrp_networks.ipv4_addrs[0].addr_s); + ds_put_format(actions, "next;/* DHCP_RELAY_RESP */"); + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "ip4.src == %s && ip4.dst == %s && " + "udp.src == 67 && udp.dst == 67", + server_ip_str, op->lrp_networks.ipv4_addrs[0].addr_s); + ds_put_format(actions, + REG_DHCP_RELAY_DIP_IPV4" = ip4.dst;" + REGBIT_DHCP_RELAY_RESP_CHK + " = dhcp_relay_resp_chk(%s, %s);next;/* DHCP_RELAY_RESP */", + op->lrp_networks.ipv4_addrs[0].addr_s, server_ip_str); + + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_DHCP_RELAY_RESP_CHK, + 100, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "ip4.src == %s && " + REG_DHCP_RELAY_DIP_IPV4" == %s && " + "udp.src == 67 && udp.dst == 67 && " + REGBIT_DHCP_RELAY_RESP_CHK, + server_ip_str, op->lrp_networks.ipv4_addrs[0].addr_s); + ds_put_format(actions, + "ip4.src=%s;udp.dst=68;" + "outport=%s;output; /* DHCP_RELAY_RESP */", + op->lrp_networks.ipv4_addrs[0].addr_s, op->json_key); + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_DHCP_RELAY_RESP, + 100, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + + ds_clear(match); + ds_clear(actions); + + ds_put_format( + match, "ip4.src == %s && " + REG_DHCP_RELAY_DIP_IPV4" == %s && " + "udp.src == 67 && udp.dst == 67 && " + REGBIT_DHCP_RELAY_RESP_CHK" == 0", + server_ip_str, op->lrp_networks.ipv4_addrs[0].addr_s); + ds_put_format(actions, + "drop; /* DHCP_RELAY_RESP */"); + ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_DHCP_RELAY_RESP, + 1, + ds_cstr(match), ds_cstr(actions), + &op->nbrp->header_, lflow_ref); + ds_clear(match); + ds_clear(actions); + free(server_ip_str); +} + static void build_ipv6_input_flows_for_lrouter_port( struct ovn_port *op, struct lflow_table *lflows, @@ -14881,6 +15136,13 @@ static void build_lr_nat_defrag_and_lb_default_flows( lflow_ref); ovn_lflow_add(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 0, "1", "next;", lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_IN_DHCP_RELAY_REQ, 0, "1", + "next;", lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_IN_DHCP_RELAY_RESP_CHK, 0, "1", + "next;", lflow_ref); + ovn_lflow_add(lflows, od, S_ROUTER_IN_DHCP_RELAY_RESP, 0, "1", + "next;", lflow_ref); + /* Send the IPv6 NS packets to next table. When ovn-controller * generates IPv6 NS (for the action - nd_ns{}), the injected @@ -15640,6 +15902,7 @@ build_lswitch_and_lrouter_iterate_by_lsp(struct ovn_port *op, build_lswitch_icmp_packet_toobig_admin_flows(op, lflows, match, actions); build_lswitch_ip_unicast_lookup(op, lflows, actions, match); + build_lswitch_dhcp_relay_flows(op, ls_ports, lflows, match, actions); /* Build Logical Router Flows. */ build_arp_resolve_flows_for_lsp(op, lflows, lr_ports, match, actions); @@ -15669,6 +15932,8 @@ build_lswitch_and_lrouter_iterate_by_lrp(struct ovn_port *op, op->lflow_ref); build_dhcpv6_reply_flows_for_lrouter_port(op, lsi->lflows, &lsi->match, op->lflow_ref); + build_dhcp_relay_flows_for_lrouter_port(op, lsi->lflows, &lsi->match, + &lsi->actions, op->lflow_ref); build_ipv6_input_flows_for_lrouter_port(op, lsi->lflows, &lsi->match, &lsi->actions, lsi->meter_groups, diff --git a/northd/northd.h b/northd/northd.h index 3f1cd8341..0a349c8f7 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -437,24 +437,29 @@ enum ovn_stage { PIPELINE_STAGE(ROUTER, IN, LOOKUP_NEIGHBOR, 1, "lr_in_lookup_neighbor") \ PIPELINE_STAGE(ROUTER, IN, LEARN_NEIGHBOR, 2, "lr_in_learn_neighbor") \ PIPELINE_STAGE(ROUTER, IN, IP_INPUT, 3, "lr_in_ip_input") \ - PIPELINE_STAGE(ROUTER, IN, UNSNAT, 4, "lr_in_unsnat") \ - PIPELINE_STAGE(ROUTER, IN, DEFRAG, 5, "lr_in_defrag") \ - PIPELINE_STAGE(ROUTER, IN, LB_AFF_CHECK, 6, "lr_in_lb_aff_check") \ - PIPELINE_STAGE(ROUTER, IN, DNAT, 7, "lr_in_dnat") \ - PIPELINE_STAGE(ROUTER, IN, LB_AFF_LEARN, 8, "lr_in_lb_aff_learn") \ - PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 9, "lr_in_ecmp_stateful") \ - PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 10, "lr_in_nd_ra_options") \ - PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 11, "lr_in_nd_ra_response") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 12, "lr_in_ip_routing_pre") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 13, "lr_in_ip_routing") \ - PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 14, "lr_in_ip_routing_ecmp") \ - PIPELINE_STAGE(ROUTER, IN, POLICY, 15, "lr_in_policy") \ - PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 16, "lr_in_policy_ecmp") \ - PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 17, "lr_in_arp_resolve") \ - PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 18, "lr_in_chk_pkt_len") \ - PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 19, "lr_in_larger_pkts") \ - PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 20, "lr_in_gw_redirect") \ - PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 21, "lr_in_arp_request") \ + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_REQ, 4, "lr_in_dhcp_relay_req") \ + PIPELINE_STAGE(ROUTER, IN, UNSNAT, 5, "lr_in_unsnat") \ + PIPELINE_STAGE(ROUTER, IN, DEFRAG, 6, "lr_in_defrag") \ + PIPELINE_STAGE(ROUTER, IN, LB_AFF_CHECK, 7, "lr_in_lb_aff_check") \ + PIPELINE_STAGE(ROUTER, IN, DNAT, 8, "lr_in_dnat") \ + PIPELINE_STAGE(ROUTER, IN, LB_AFF_LEARN, 9, "lr_in_lb_aff_learn") \ + PIPELINE_STAGE(ROUTER, IN, ECMP_STATEFUL, 10, "lr_in_ecmp_stateful") \ + PIPELINE_STAGE(ROUTER, IN, ND_RA_OPTIONS, 11, "lr_in_nd_ra_options") \ + PIPELINE_STAGE(ROUTER, IN, ND_RA_RESPONSE, 12, "lr_in_nd_ra_response") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_PRE, 13, "lr_in_ip_routing_pre") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING, 14, "lr_in_ip_routing") \ + PIPELINE_STAGE(ROUTER, IN, IP_ROUTING_ECMP, 15, "lr_in_ip_routing_ecmp") \ + PIPELINE_STAGE(ROUTER, IN, POLICY, 16, "lr_in_policy") \ + PIPELINE_STAGE(ROUTER, IN, POLICY_ECMP, 17, "lr_in_policy_ecmp") \ + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP_CHK, 18, \ + "lr_in_dhcp_relay_resp_chk") \ + PIPELINE_STAGE(ROUTER, IN, DHCP_RELAY_RESP, 19, \ + "lr_in_dhcp_relay_resp") \ + PIPELINE_STAGE(ROUTER, IN, ARP_RESOLVE, 20, "lr_in_arp_resolve") \ + PIPELINE_STAGE(ROUTER, IN, CHK_PKT_LEN, 21, "lr_in_chk_pkt_len") \ + PIPELINE_STAGE(ROUTER, IN, LARGER_PKTS, 22, "lr_in_larger_pkts") \ + PIPELINE_STAGE(ROUTER, IN, GW_REDIRECT, 23, "lr_in_gw_redirect") \ + PIPELINE_STAGE(ROUTER, IN, ARP_REQUEST, 24, "lr_in_arp_request") \ \ /* Logical router egress stages. */ \ PIPELINE_STAGE(ROUTER, OUT, CHECK_DNAT_LOCAL, 0, \ diff --git a/ovn-nb.ovsschema b/ovn-nb.ovsschema index a9c5b7af5..a616dbd6b 100644 --- a/ovn-nb.ovsschema +++ b/ovn-nb.ovsschema @@ -1,7 +1,7 @@ { "name": "OVN_Northbound", "version": "7.3.0", - "cksum": "3546526738 34483", + "cksum": "3858903371 35372", "tables": { "NB_Global": { "columns": { @@ -436,6 +436,11 @@ "ipv6_prefix": {"type": {"key": "string", "min": 0, "max": "unlimited"}}, + "dhcp_relay": {"type": {"key": {"type": "uuid", + "refTable": "DHCP_Relay", + "refType": "strong"}, + "min": 0, + "max": 1}}, "external_ids": { "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}, @@ -534,6 +539,18 @@ "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"}}}, "isRoot": true}, + "DHCP_Relay": { + "columns": { + "name": {"type": "string"}, + "servers": {"type": {"key": "string", + "min": 0, + "max": 1}}, + "options": {"type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}, + "external_ids": { + "type": {"key": "string", "value": "string", + "min": 0, "max": "unlimited"}}}, + "isRoot": true}, "Connection": { "columns": { "target": {"type": "string"}, diff --git a/ovn-nb.xml b/ovn-nb.xml index b652046a7..5cb6ba640 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -703,6 +703,13 @@ + + If set to the name of logical switch port of type router + then, DHCP Relay is enabled for this logical switch provided the + corresponding has DHCP Relay + configured. + + Value used to request to assign L2 address only if neither subnet nor ipv6_prefix are specified @@ -3066,6 +3073,11 @@ or port has all ingress and egress traffic dropped. + + This column is used to enabled DHCP Relay. Please refer + to table. + +

Gateways, as documented under Gateways in the OVN @@ -4379,6 +4391,33 @@ or + +

+ OVN implements native DHCPv4 relay support which caters to the common + use case of relaying the DHCP requests to external DHCP server. +

+ +

+ A name for the DHCP Relay. +

+
+ +

+ The DHCPv4 server IP address. +

+
+ +

+ Future purpose. +

+
+ + + See External IDs at the beginning of this document. + + +
+

Configuration for a database connection to an Open vSwitch database diff --git a/tests/ovn.at b/tests/ovn.at index 4d0c7ad53..32e3d8b13 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -34942,7 +34942,7 @@ check ovn-nbctl set nb_global . options:use_common_zone="true" check ovn-nbctl --wait=hv sync # Use constants so that if tables or registers change, this test can # be updated easily. -DNAT_TABLE=15 +DNAT_TABLE=16 SNAT_TABLE=45 DNAT_ZONE_REG="NXM_NX_REG11[[0..15]]" SNAT_ZONE_REG="NXM_NX_REG12[[0..15]]"