From patchwork Wed Mar 27 08:43:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Huettner X-Patchwork-Id: 1916578 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=mail.schwarz header.i=@mail.schwarz header.a=rsa-sha256 header.s=selector1 header.b=e8KIPET4; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mail.schwarz header.i=@mail.schwarz header.a=rsa-sha256 header.s=selector1 header.b=e8KIPET4; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (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 4V4Kvb04vYz1yXq for ; Wed, 27 Mar 2024 19:43:37 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 57C7460590; Wed, 27 Mar 2024 08:43:31 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id tCmC6DKLPn62; Wed, 27 Mar 2024 08:43:28 +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 smtp3.osuosl.org 5601F60833 Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=mail.schwarz header.i=@mail.schwarz header.a=rsa-sha256 header.s=selector1 header.b=e8KIPET4; dkim=fail reason="signature verification failed" (2048-bit key) header.d=mail.schwarz header.i=@mail.schwarz header.a=rsa-sha256 header.s=selector1 header.b=e8KIPET4 Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id 5601F60833; Wed, 27 Mar 2024 08:43:28 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 30E43C0077; Wed, 27 Mar 2024 08:43:28 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 9E126C0037 for ; Wed, 27 Mar 2024 08:43:26 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 867EC81EB8 for ; Wed, 27 Mar 2024 08:43:26 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id DPpgbYMXyzjf for ; Wed, 27 Mar 2024 08:43:24 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2a01:111:f403:2613::600; helo=eur05-vi1-obe.outbound.protection.outlook.com; envelope-from=felix.huettner@mail.schwarz; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org C675F8177C Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=reject dis=none) header.from=mail.schwarz DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org C675F8177C Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key, unprotected) header.d=mail.schwarz header.i=@mail.schwarz header.a=rsa-sha256 header.s=selector1 header.b=e8KIPET4; dkim=pass (2048-bit key) header.d=mail.schwarz header.i=@mail.schwarz header.a=rsa-sha256 header.s=selector1 header.b=e8KIPET4 Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05on20600.outbound.protection.outlook.com [IPv6:2a01:111:f403:2613::600]) by smtp1.osuosl.org (Postfix) with ESMTPS id C675F8177C for ; Wed, 27 Mar 2024 08:43:23 +0000 (UTC) ARC-Seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=WEqU7yW+fY1+Oq6xf1l2Qh87xgVPIG+SjFbtauXg+f6LdUPzs7i8cqS8nxjVtgObF5x3XCMTCqk3KuyQyEwTFb6LdU0dzdoZz2IjtEjbva4+5AijgmX2mZgRdGQHpiaiN+o7amlg99J8V3KnbPOY9tktBIm9gzexQTRK/0BqC0Dqmgna0+rHF7VZIXtLRYmF2yV7zgjjZwMTi2ARHcemrQZseyZB3g3a7dYkKztFFxvNKlj74K8/nzu0gNUQXbxlEG916t55GoLc/vjnAuCF93QCgrrkYbLn4tFvr9g7sPxA4zp6iXlUDN2DcI6qxF45R5Dyq/UZTYPFd+n59Vcysg== ARC-Message-Signature: i=2; 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=hitznJo/rdRiwOKA25rGCBfn70VXlNLG2W04EAOG08U=; b=kXef35DvR3fic/UASe9eU9sHfkaejmgRQJZyNP90gaW1K9seZsqN2NIPk7R9LuaK1CouN8oGdvCRyL3v/R7j66Y8381u3Rcb2oobE5UBRkoRi/emjc2T7/DwHNbiLrAp4GLQ/2WFaMympPP1PFr/bAK6led1AL/rFLFGXfPnKq0KUIpQIMQqyTf7SL462YsSEmD5nhPI2CjrwFLxATu104azQexd5qtr4B4/WPJ3zjpiV7S2AqCmdzGDFpA5aT0zHISAN6J55q9CHgnWBTRZ0otJzKBOREFbvyl7rxnaYRhZdnnQlyyh1QCBu7Qnde1ycrFQ1vMrPGWjsxw8EdwXnA== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 104.40.229.156) smtp.rcpttodomain=openvswitch.org smtp.mailfrom=mail.schwarz; dmarc=pass (p=reject sp=none pct=100) action=none header.from=mail.schwarz; dkim=pass (signature was verified) header.d=mail.schwarz; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=mail.schwarz] dkim=[1,1,header.d=mail.schwarz] dmarc=[1,1,header.from=mail.schwarz]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.schwarz; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hitznJo/rdRiwOKA25rGCBfn70VXlNLG2W04EAOG08U=; b=e8KIPET4vhVUkyM5/h7g459uOylouPCv9AZidgR1eFNPvqzPXYlsVpOMxTYfKks3fLED1WRpt5l7ef4FaDo6HmtCg1gzuAWCJnynfuI2GguwLUlWQkU0QP2tElRoyUPgzlwpsetW8Cfi6pzOjGCOFBWmderpE7dxAsx+fltFFTrZhmPZYxD+/IAg3v/fG3kY/8kIiMoN1kmlwT/LM1hnj67e4VKXN6AP0t1sL5lS3d48+kTY2WVLPCmgfD3mZ1yOwLDfRZgoYgZ4iEhdjSDAm7vCfZVekFD0wPWslczZPij53yCmGxpQw8UxJsw6zzUwersUSB3j+8jYig+ZFW3bGA== Received: from AS4P195CA0014.EURP195.PROD.OUTLOOK.COM (2603:10a6:20b:5e2::10) by AS1PR10MB5579.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:477::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.32; Wed, 27 Mar 2024 08:43:19 +0000 Received: from AM4PEPF00027A5F.eurprd04.prod.outlook.com (2603:10a6:20b:5e2:cafe::8a) by AS4P195CA0014.outlook.office365.com (2603:10a6:20b:5e2::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.13 via Frontend Transport; Wed, 27 Mar 2024 08:43:19 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 104.40.229.156) smtp.mailfrom=mail.schwarz; dkim=pass (signature was verified) header.d=mail.schwarz;dmarc=pass action=none header.from=mail.schwarz; Received-SPF: Pass (protection.outlook.com: domain of mail.schwarz designates 104.40.229.156 as permitted sender) receiver=protection.outlook.com; client-ip=104.40.229.156; helo=eu1.smtp.exclaimer.net; pr=C Received: from eu1.smtp.exclaimer.net (104.40.229.156) by AM4PEPF00027A5F.mail.protection.outlook.com (10.167.16.74) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.7409.10 via Frontend Transport; Wed, 27 Mar 2024 08:43:18 +0000 Received: from EUR01-VE1-obe.outbound.protection.outlook.com (104.47.1.50) by eu1.smtp.exclaimer.net (104.40.229.156) with Exclaimer Signature Manager ESMTP Proxy eu1.smtp.exclaimer.net (tlsversion=TLS12, tlscipher=TLS_ECDHE_WITH_AES256_SHA384); Wed, 27 Mar 2024 08:43:17 +0000 X-ExclaimerHostedSignatures-MessageProcessed: true X-ExclaimerProxyLatency: 4446354 X-ExclaimerImprintLatency: 1618678 X-ExclaimerImprintAction: 6b430d80cd7746d2bae39c621745753e ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RxWHG0fGBxdgHvV9b/AMtbvb9MaHl+D+52AaijcI3V3tgR2JHHeSHrQVnt7dOks2J9tzfSunm9EKM5poJqUIpAHenmcSORw+CNiS0jZrIrghEtg59yQNPDMbA0ZRXWc3EVNlXdiand+9gbwCaqAom3cDrsbM2vvuIcV8DUdDlbTf5EDwL0WhfhZCUvYH2sYiTZKuvJNtuhLEDvcTTu2EyzcBz7df1iSgQrBtNO5mH7FdaIrUg38RovZXkTbKya8/WPMxDl6zXHz1vUVmNYG4w5DrW4H6KvjdEQO7W4BaIMc+WAfwKuT4fEvCOVXn+uwPlxcfBGzftHS3xqHXrspcng== 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=hitznJo/rdRiwOKA25rGCBfn70VXlNLG2W04EAOG08U=; b=XraTp0UptIgAubonIZcXKbgF3eoczNiccJMh515NFrWR31lHrHdpsRtUTJ7jynyE5l/jdIr9VgBRl7e9z9Hf2rNu5nRobCBIHi1Sn+sPqFslLUoWPPRC/Bpbub6ap9KX4aabc3+PPO8yj1nUawYscuUE2zuS9oJMv2KwrERudvrfZqkj7UrzGYlWu+DJvMOwiQ8383uAZ40bzRApI0Z4ncZmV72/9Lp6zaeEqVxeukGeqj0jMguBNpU2eb0naCPuxMiAp44lN8Jitmy3dRrCC2q5woYY5UD07Ao7RieK/Ey4By7QVs5bR9WM+7DITghXMlFdl6fDt4qtTvkZbXbFdg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mail.schwarz; dmarc=pass action=none header.from=mail.schwarz; dkim=pass header.d=mail.schwarz; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.schwarz; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=hitznJo/rdRiwOKA25rGCBfn70VXlNLG2W04EAOG08U=; b=e8KIPET4vhVUkyM5/h7g459uOylouPCv9AZidgR1eFNPvqzPXYlsVpOMxTYfKks3fLED1WRpt5l7ef4FaDo6HmtCg1gzuAWCJnynfuI2GguwLUlWQkU0QP2tElRoyUPgzlwpsetW8Cfi6pzOjGCOFBWmderpE7dxAsx+fltFFTrZhmPZYxD+/IAg3v/fG3kY/8kIiMoN1kmlwT/LM1hnj67e4VKXN6AP0t1sL5lS3d48+kTY2WVLPCmgfD3mZ1yOwLDfRZgoYgZ4iEhdjSDAm7vCfZVekFD0wPWslczZPij53yCmGxpQw8UxJsw6zzUwersUSB3j+8jYig+ZFW3bGA== Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=mail.schwarz; Received: from PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:102:30d::9) by AS8PR10MB7828.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:63e::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.31; Wed, 27 Mar 2024 08:43:16 +0000 Received: from PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM ([fe80::6c69:4f96:2e5d:8aae]) by PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM ([fe80::6c69:4f96:2e5d:8aae%4]) with mapi id 15.20.7409.028; Wed, 27 Mar 2024 08:43:15 +0000 Date: Wed, 27 Mar 2024 09:43:13 +0100 To: dev@openvswitch.org Message-ID: Mail-Followup-To: dev@openvswitch.org Content-Disposition: inline X-ClientProxiedBy: FR3P281CA0110.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a3::7) To PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:102:30d::9) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: PAVPR10MB6914:EE_|AS8PR10MB7828:EE_|AM4PEPF00027A5F:EE_|AS1PR10MB5579:EE_ X-MS-Office365-Filtering-Correlation-Id: ca11db8a-e5af-438f-c7b4-08dc4e39f360 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: W14VbIMWT2AxIWjMiOxDHH2RVnNTvPHAvz+CPycsdSeizVr55A/Nlaesh1chLpvLAp6xC0TJH8T9UFpqEnsvuG14hPpal8RF8XRCt5Co+1sXDtI/zvldyceuV+m5YwBsfde28Sa4Hct2Fi8iIgYE0hwlBV/rHXbUHAGOgMb4shpBjuRnnlb3yIAoBcOAOsjFoWe8Zq4wSiFKDBix5Aug2oTQXE1dMspybdnVllto6kMtDmi7CJS/ofsS0kksYogg/1bQ+AdYBCm7EKUfg+MGnSYwL8Pcia1KamwnoOv29xVIGmByghnuLrHXswaUBMFCxopVhvFfWG00JecEg56tR2fcdZka7ajkldpgUI9zQ6uiGls4zp37zj0PFiGfDro+8PQq0uAnRgmkepSxceVe+JmLyAmj7uE4oZkAYBzM0tYEvxTQ3maiJspnQcjpfo0kiAr7wfxx7xQhUQDcwc1AfuCkWoV200qpp5TMRZHnQOfEY3dejMnC0EeJZljyt1sWSMVOxL23vaBoOp2qV7Zguo5MlnQDob7c1xhGrM7eVFrji8T4+BGWSFgwq3giNbG9APPzKgnRG6qEwR5UsFhl+NcFRMfE+MrxyXBP5bajgjs3VBJ1utOec5OsP0dfCvM/Ov6P+ks9P2FnzEnKmvGv9LFRUPXtjkY25hENff1GYyQ= X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(13230031)(376005)(1800799015)(366007); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS8PR10MB7828 X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM4PEPF00027A5F.eurprd04.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: c5781ae8-f866-488b-f75c-08dc4e39f1ca X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Pbqzi0yKW8hlRUqos80JXlmHocP5ldpOxystpOAIvrNAI6B5Psw1BUfCXwFfZ38/Cb+UruQhw6gtBo9OSVqJ97EaTdn2FxVesfmwbUtv4ApjA3uDC477sYywLciOxtwnXx9G+cDj8VFdSJRBoKaXjIXKVgpjEbR1TUEOWKg5tnFK62MLPYANlyIpt4bKpGbmYTi7Zv+FiGzl20RbrrDMUkr4QSq26Jk/9B2AEsY88XWumRjChynuUfg5Pc39SaHuS3lIwoNGL5QPwL21sfUJPy3U4jwim37FS1sWpxeH4jG0bX0Sjjtf9BL2qGbKoa6mMfOSjjijZyaoIUtDS8Fg8KF3C4GnliOTWWMnia/5azfoFD5GB/ZOZFAiBekFZScGHAflRbTyFZ9FrK7ATlbXNkEZN9l4mq95LHlbw6mf6Qk3BfPXjSLYRTRwBXOj3L3DVXG9NOlkB6pcNugpF4KqWe+RxOtywcKcrR9jTiE3k0umRp1V6vJTNL8zLfh48nACVFbW4/s2jgpExvUZOWNnlquqVlkx2Tis7G5eYNVZBa/CaNm1eRhxknfHswG+NY8KQd5yvTqI8O7kJDYnYdosqyj77QgW0zHRsBHjqxRfJipGqkQSKeHjTcT1hfLgpCtZ1s+cHZ1PqNatbewuhUIbS8Na+JJthdGYL7w40ZgLvC/qktzjKPOT5AmzTkiuGpCBL+JvoDzwAPO5s/HOglkUZlOhhJin+h/0IKz2yzXKStSVIog/D+DO++/yIbrhq+BJ X-Forefront-Antispam-Report: CIP:104.40.229.156; CTRY:NL; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:eu1.smtp.exclaimer.net; PTR:eu1.smtp.exclaimer.net; CAT:NONE; SFS:(13230031)(36860700004)(82310400014)(1800799015)(376005); DIR:OUT; SFP:1101; X-OriginatorOrg: mail.schwarz X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2024 08:43:18.0732 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ca11db8a-e5af-438f-c7b4-08dc4e39f360 X-MS-Exchange-CrossTenant-Id: d04f4717-5a6e-4b98-b3f9-6918e0385f4c X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=d04f4717-5a6e-4b98-b3f9-6918e0385f4c; Ip=[104.40.229.156]; Helo=[eu1.smtp.exclaimer.net] X-MS-Exchange-CrossTenant-AuthSource: AM4PEPF00027A5F.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS1PR10MB5579 Subject: [ovs-dev] [PATCH ovn] northd: Support routing over other address families. 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: Felix Huettner via dev From: Felix Huettner Reply-To: Felix Huettner Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" In most cases IPv4 packets are routed only over other IPv4 networks and IPv6 packets are routed only over IPv6 networks. However there is no interent reason for this limitation. Routing IPv4 packets over IPv6 networks just requires the router to contain a route for an IPv4 network with an IPv6 nexthop. This was previously prevented in OVN in ovn-nbctl and northd. By removing these filters the forwarding will work if the mac addresses are prepopulated. If the mac addresses are not prepopulated we will attempt to resolve them using the original address family of the packet and not the address family of the nexthop. This will fail and we will not forward the packet. This feature can for example be used by service providers to interconnect multiple IPv4 networks of a customer without needing to negotiate free IPv4 addresses by just using any IPv6 address. Signed-off-by: Felix Huettner --- NEWS | 4 + northd/northd.c | 45 ++-- tests/ovn-nbctl.at | 8 +- tests/ovn.at | 615 ++++++++++++++++++++++++++++++++++++++++++ utilities/ovn-nbctl.c | 12 +- 5 files changed, 650 insertions(+), 34 deletions(-) base-commit: dc52bf70cb7e066fdb84d88622d7f380eda18e8c diff --git a/NEWS b/NEWS index 4d6ebea89..b419b2628 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ Post v24.03.0 flow table id. "lflow-stage-to-oftable STAGE_NAME" that converts stage name into OpenFlow table id. + - Allow Static Routes where the address families of ip_prefix and nexthop + diverge (e.g. IPv4 packets over IPv6 links). This is currently limited to + nexthops that have their mac addresses prepopulated (so + dynamic_neigh_routers must be false). OVN v24.03.0 - 01 Mar 2024 -------------------------- diff --git a/northd/northd.c b/northd/northd.c index 1839b7d8b..0359cde89 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -10238,18 +10238,6 @@ parsed_routes_add(struct ovn_datapath *od, const struct hmap *lr_ports, return NULL; } - /* Verify that ip_prefix and nexthop have same address familiy. */ - if (valid_nexthop) { - if (IN6_IS_ADDR_V4MAPPED(&prefix) != IN6_IS_ADDR_V4MAPPED(&nexthop)) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); - VLOG_WARN_RL(&rl, "Address family doesn't match between 'ip_prefix'" - " %s and 'nexthop' %s in static route "UUID_FMT, - route->ip_prefix, route->nexthop, - UUID_ARGS(&route->header_.uuid)); - return NULL; - } - } - /* Verify that ip_prefix and nexthop are on the same network. */ if (!is_discard_route && !find_static_route_outport(od, lr_ports, route, @@ -10666,7 +10654,7 @@ build_ecmp_route_flow(struct lflow_table *lflows, struct ovn_datapath *od, struct lflow_ref *lflow_ref) { - bool is_ipv4 = IN6_IS_ADDR_V4MAPPED(&eg->prefix); + bool is_ipv4_network = IN6_IS_ADDR_V4MAPPED(&eg->prefix); uint16_t priority; struct ecmp_route_list_node *er; struct ds route_match = DS_EMPTY_INITIALIZER; @@ -10675,7 +10663,8 @@ build_ecmp_route_flow(struct lflow_table *lflows, struct ovn_datapath *od, int ofs = !strcmp(eg->origin, ROUTE_ORIGIN_CONNECTED) ? ROUTE_PRIO_OFFSET_CONNECTED: ROUTE_PRIO_OFFSET_STATIC; build_route_match(NULL, eg->route_table_id, prefix_s, eg->plen, - eg->is_src_route, is_ipv4, &route_match, &priority, ofs); + eg->is_src_route, is_ipv4_network, &route_match, + &priority, ofs); free(prefix_s); struct ds actions = DS_EMPTY_INITIALIZER; @@ -10708,7 +10697,11 @@ build_ecmp_route_flow(struct lflow_table *lflows, struct ovn_datapath *od, /* Find the outgoing port. */ const char *lrp_addr_s = NULL; struct ovn_port *out_port = NULL; - if (!find_static_route_outport(od, lr_ports, route, is_ipv4, + bool is_ipv4_gateway = is_ipv4_network; + if (route->nexthop && route->nexthop[0]) { + is_ipv4_gateway = strchr(route->nexthop, '.') ? true : false; + } + if (!find_static_route_outport(od, lr_ports, route, is_ipv4_gateway, &lrp_addr_s, &out_port)) { continue; } @@ -10733,9 +10726,9 @@ build_ecmp_route_flow(struct lflow_table *lflows, struct ovn_datapath *od, "eth.src = %s; " "outport = %s; " "next;", - is_ipv4 ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6, + is_ipv4_gateway ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6, route->nexthop, - is_ipv4 ? REG_SRC_IPV4 : REG_SRC_IPV6, + is_ipv4_gateway ? REG_SRC_IPV4 : REG_SRC_IPV6, lrp_addr_s, out_port->lrp_networks.ea_s, out_port->json_key); @@ -10757,13 +10750,18 @@ add_route(struct lflow_table *lflows, struct ovn_datapath *od, const struct ovsdb_idl_row *stage_hint, bool is_discard_route, int ofs, struct lflow_ref *lflow_ref) { - bool is_ipv4 = strchr(network_s, '.') ? true : false; + bool is_ipv4_network = strchr(network_s, '.') ? true : false; + bool is_ipv4_gateway = is_ipv4_network; struct ds match = DS_EMPTY_INITIALIZER; uint16_t priority; const struct ovn_port *op_inport = NULL; + if (gateway && gateway[0]) { + is_ipv4_gateway = strchr(gateway, '.') ? true : false; + } + /* IPv6 link-local addresses must be scoped to the local router port. */ - if (!is_ipv4) { + if (!is_ipv4_network) { struct in6_addr network; ovs_assert(ipv6_parse(network_s, &network)); if (in6_is_lla(&network)) { @@ -10771,7 +10769,7 @@ add_route(struct lflow_table *lflows, struct ovn_datapath *od, } } build_route_match(op_inport, rtb_id, network_s, plen, is_src_route, - is_ipv4, &match, &priority, ofs); + is_ipv4_network, &match, &priority, ofs); struct ds common_actions = DS_EMPTY_INITIALIZER; struct ds actions = DS_EMPTY_INITIALIZER; @@ -10779,11 +10777,12 @@ add_route(struct lflow_table *lflows, struct ovn_datapath *od, ds_put_cstr(&actions, debug_drop_action()); } else { ds_put_format(&common_actions, REG_ECMP_GROUP_ID" = 0; %s = ", - is_ipv4 ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6); + is_ipv4_gateway ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6); if (gateway && gateway[0]) { ds_put_cstr(&common_actions, gateway); } else { - ds_put_format(&common_actions, "ip%s.dst", is_ipv4 ? "4" : "6"); + ds_put_format(&common_actions, "ip%s.dst", + is_ipv4_network ? "4" : "6"); } ds_put_format(&common_actions, "; " "%s = %s; " @@ -10791,7 +10790,7 @@ add_route(struct lflow_table *lflows, struct ovn_datapath *od, "outport = %s; " "flags.loopback = 1; " "next;", - is_ipv4 ? REG_SRC_IPV4 : REG_SRC_IPV6, + is_ipv4_gateway ? REG_SRC_IPV4 : REG_SRC_IPV6, lrp_addr_s, op->lrp_networks.ea_s, op->json_key); diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at index 5248e6c76..60dcdc9be 100644 --- a/tests/ovn-nbctl.at +++ b/tests/ovn-nbctl.at @@ -1757,7 +1757,7 @@ AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.1/24 11.0.0.2]) AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.10.0/24 lp0]) AT_CHECK([ovn-nbctl --bfd lr-route-add lr0 10.0.20.0/24 11.0.2.1 lp0]) AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.10.0/24 lp1], [1], [], - [ovn-nbctl: bad IPv4 nexthop argument: lp1 + [ovn-nbctl: bad nexthop argument: lp1 ]) dnl Add overlapping route with 10.0.0.1/24 @@ -1771,13 +1771,13 @@ AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24a 11.0.0.1], [1], [], [ovn-nbctl: bad prefix argument: 10.0.0.111/24a ]) AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24 11.0.0.1a], [1], [], - [ovn-nbctl: bad IPv4 nexthop argument: 11.0.0.1a + [ovn-nbctl: bad nexthop argument: 11.0.0.1a ]) AT_CHECK([ovn-nbctl lr-route-add lr0 10.0.0.111/24 11.0.0.1/24], [1], [], - [ovn-nbctl: bad IPv4 nexthop argument: 11.0.0.1/24 + [ovn-nbctl: bad nexthop argument: 11.0.0.1/24 ]) AT_CHECK([ovn-nbctl lr-route-add lr0 2001:0db8:1::/64 2001:0db8:0:f103::1/64], [1], [], - [ovn-nbctl: bad IPv6 nexthop argument: 2001:0db8:0:f103::1/64 + [ovn-nbctl: bad nexthop argument: 2001:0db8:0:f103::1/64 ]) AT_CHECK([ovn-nbctl --ecmp lr-route-add lr0 20.0.0.0/24 discard], [1], [], [ovn-nbctl: ecmp is not valid for discard routes. diff --git a/tests/ovn.at b/tests/ovn.at index 4d0c7ad53..8818d0db9 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -38475,3 +38475,618 @@ OVS_WAIT_FOR_OUTPUT([as hv1 ovs-ofctl dump-flows br-int table=0 |grep priority=1 OVN_CLEANUP([hv1]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([2 HVs, 2 LS, 1 lport/LS, 2 peer LRs, IPv4 over IPv6]) +ovn_start + +# Logical network: +# Two LRs - R1 and R2 that are connected to each other as peers in 2001:db8::/64 +# network. R1 has a switchs ls1 (192.168.1.0/24) connected to it. +# R2 has ls2 (172.16.1.0/24) connected to it. + +ls1_lp1_mac="f0:00:00:01:02:03" +rp_ls1_mac="00:00:00:01:02:03" +rp_ls2_mac="00:00:00:01:02:04" +ls2_lp1_mac="f0:00:00:01:02:04" + +ls1_lp1_ip="192.168.1.2" +ls2_lp1_ip="172.16.1.2" + +ovn-nbctl lr-add R1 +ovn-nbctl lr-add R2 + +ovn-nbctl ls-add ls1 +ovn-nbctl ls-add ls2 + +# Connect ls1 to R1 +ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24 + +ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \ + options:router-port=ls1 addresses=\"$rp_ls1_mac\" + +# Connect ls2 to R2 +ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24 + +ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \ + options:router-port=ls2 addresses=\"$rp_ls2_mac\" + +# Connect R1 to R2 +ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 2001:db8::1/64 peer=R2_R1 +ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 2001:db8::2/64 peer=R1_R2 + +AT_CHECK([ovn-nbctl lr-route-add R1 "0.0.0.0/0" 2001:db8::2]) +AT_CHECK([ovn-nbctl lr-route-add R2 "0.0.0.0/0" 2001:db8::1]) + +# Create logical port ls1-lp1 in ls1 +ovn-nbctl lsp-add ls1 ls1-lp1 \ +-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip" + +# Create logical port ls2-lp1 in ls2 +ovn-nbctl lsp-add ls2 ls2-lp1 \ +-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip" + +# Create two hypervisor and create OVS ports corresponding to logical ports. +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +sim_add hv2 +as hv2 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.2 +ovs-vsctl -- add-port br-int hv2-vif1 -- \ + set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \ + options:tx_pcap=hv2/vif1-tx.pcap \ + options:rxq_pcap=hv2/vif1-rx.pcap \ + ofport-request=1 + + +# Pre-populate the hypervisors' ARP tables so that we don't lose any +# packets for ARP resolution (native tunneling doesn't queue packets +# for ARP resolution). +OVN_POPULATE_ARP + +# Allow some time for ovn-northd and ovn-controller to catch up. +wait_for_ports_up +check ovn-nbctl --wait=hv sync + +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + +echo "---------NB dump-----" +ovn-nbctl show +echo "---------------------" +ovn-nbctl list logical_router +echo "---------------------" +ovn-nbctl list logical_router_port +echo "---------------------" + +echo "---------SB dump-----" +ovn-sbctl list datapath_binding +echo "---------------------" +ovn-sbctl list port_binding +echo "---------------------" + +echo "------ hv1 dump ----------" +as hv1 ovs-ofctl show br-int +as hv1 ovs-ofctl dump-flows br-int +echo "------ hv2 dump ----------" +as hv2 ovs-ofctl show br-int +as hv2 ovs-ofctl dump-flows br-int + +# Packet to Expect +# The TTL should be decremented by 2. +packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac && + ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +echo $packet | ovstest test-ovn expr-to-packets > expected + +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "reg0 == 172.16.1.2" | wc -l], [0], [1 +]) + +# Disable the ls2-lp1 port. +ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "reg0 == 172.16.1.2" | wc -l], [0], [0 +]) + +# Generate the packet destined for ls2-lp1 and it should not be delivered. +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" + +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) +# The 2nd packet sent shound not be received. +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +OVN_CLEANUP([hv1],[hv2]) + +AT_CLEANUP +]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([2 HVs, 2 LS, 1 lport/LS, LRs connected via LS, IPv4 over IPv6]) +ovn_start + +# Logical network: +# Two LRs - R1 and R2 that are connected to ls-transfer in 2001:db8::/64 +# network. R1 has a switchs ls1 (192.168.1.0/24) connected to it. +# R2 has ls2 (172.16.1.0/24) connected to it. + +ls1_lp1_mac="f0:00:00:01:02:03" +rp_ls1_mac="00:00:00:01:02:03" +rp_ls2_mac="00:00:00:01:02:04" +ls2_lp1_mac="f0:00:00:01:02:04" + +ls1_lp1_ip="192.168.1.2" +ls2_lp1_ip="172.16.1.2" + +ovn-nbctl lr-add R1 +ovn-nbctl lr-add R2 + +ovn-nbctl ls-add ls1 +ovn-nbctl ls-add ls2 +ovn-nbctl ls-add ls-transfer + +# Connect ls1 to R1 +ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24 + +ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \ + options:router-port=ls1 addresses=\"$rp_ls1_mac\" + +# Connect ls2 to R2 +ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24 + +ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \ + options:router-port=ls2 addresses=\"$rp_ls2_mac\" + +# Connect R1 to R2 +ovn-nbctl lrp-add R1 R1_ls-transfer 00:00:00:02:03:04 2001:db8::1/64 +ovn-nbctl lrp-add R2 R2_ls-transfer 00:00:00:02:03:05 2001:db8::2/64 + +ovn-nbctl lsp-add ls-transfer ls-transfer_r1 -- \ + set Logical_Switch_Port ls-transfer_r1 type=router \ + options:router-port=R1_ls-transfer addresses=\"router\" +ovn-nbctl lsp-add ls-transfer ls-transfer_r2 -- \ + set Logical_Switch_Port ls-transfer_r2 type=router \ + options:router-port=R2_ls-transfer addresses=\"router\" + +AT_CHECK([ovn-nbctl lr-route-add R1 "0.0.0.0/0" 2001:db8::2]) +AT_CHECK([ovn-nbctl lr-route-add R2 "0.0.0.0/0" 2001:db8::1]) + +# Create logical port ls1-lp1 in ls1 +ovn-nbctl lsp-add ls1 ls1-lp1 \ +-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip" + +# Create logical port ls2-lp1 in ls2 +ovn-nbctl lsp-add ls2 ls2-lp1 \ +-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip" + +# Create two hypervisor and create OVS ports corresponding to logical ports. +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +sim_add hv2 +as hv2 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.2 +ovs-vsctl -- add-port br-int hv2-vif1 -- \ + set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \ + options:tx_pcap=hv2/vif1-tx.pcap \ + options:rxq_pcap=hv2/vif1-rx.pcap \ + ofport-request=1 + + +# Pre-populate the hypervisors' ARP tables so that we don't lose any +# packets for ARP resolution (native tunneling doesn't queue packets +# for ARP resolution). +OVN_POPULATE_ARP + +# Allow some time for ovn-northd and ovn-controller to catch up. +wait_for_ports_up +check ovn-nbctl --wait=hv sync + +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + +echo "---------NB dump-----" +ovn-nbctl show +echo "---------------------" +ovn-nbctl list logical_router +echo "---------------------" +ovn-nbctl list logical_router_port +echo "---------------------" + +echo "---------SB dump-----" +ovn-sbctl list datapath_binding +echo "---------------------" +ovn-sbctl list port_binding +echo "---------------------" + +echo "------ hv1 dump ----------" +as hv1 ovs-ofctl show br-int +as hv1 ovs-ofctl dump-flows br-int +echo "------ hv2 dump ----------" +as hv2 ovs-ofctl show br-int +as hv2 ovs-ofctl dump-flows br-int + +# Packet to Expect +# The TTL should be decremented by 2. +packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac && + ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +echo $packet | ovstest test-ovn expr-to-packets > expected + +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "reg0 == 172.16.1.2" | wc -l], [0], [1 +]) + +# Disable the ls2-lp1 port. +ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "reg0 == 172.16.1.2" | wc -l], [0], [0 +]) + +# Generate the packet destined for ls2-lp1 and it should not be delivered. +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" + +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) +# The 2nd packet sent shound not be received. +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +OVN_CLEANUP([hv1],[hv2]) + +AT_CLEANUP +]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([2 HVs, 2 LS, 1 lport/LS, LRs connected via LS, IPv4 over IPv6, ECMP]) +ovn_start + +# Logical network: +# Two LRs - R1 and R2 that are connected to ls-transfer1 and lr-transfer2 in +# 2001:db8:1::/64 and 2001:db8:2::/64 +# network. R1 has a switchs ls1 (192.168.1.0/24) connected to it. +# R2 has ls2 (172.16.1.0/24) connected to it. + +ls1_lp1_mac="f0:00:00:01:02:03" +rp_ls1_mac="00:00:00:01:02:03" +rp_ls2_mac="00:00:00:01:02:04" +ls2_lp1_mac="f0:00:00:01:02:04" + +ls1_lp1_ip="192.168.1.2" +ls2_lp1_ip="172.16.1.2" + +ovn-nbctl lr-add R1 +ovn-nbctl lr-add R2 + +ovn-nbctl ls-add ls1 +ovn-nbctl ls-add ls2 +ovn-nbctl ls-add ls-transfer1 +ovn-nbctl ls-add ls-transfer2 + +# Connect ls1 to R1 +ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24 + +ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \ + options:router-port=ls1 addresses=\"$rp_ls1_mac\" + +# Connect ls2 to R2 +ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24 + +ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \ + options:router-port=ls2 addresses=\"$rp_ls2_mac\" + +# Connect R1 to R2 (ls-transfer1) +ovn-nbctl lrp-add R1 R1_ls-transfer1 00:00:00:02:03:04 2001:db8:1::1/64 +ovn-nbctl lrp-add R2 R2_ls-transfer1 00:00:00:02:03:05 2001:db8:1::2/64 + +ovn-nbctl lsp-add ls-transfer1 ls-transfer1_r1 -- \ + set Logical_Switch_Port ls-transfer1_r1 type=router \ + options:router-port=R1_ls-transfer1 addresses=\"router\" +ovn-nbctl lsp-add ls-transfer1 ls-transfer1_r2 -- \ + set Logical_Switch_Port ls-transfer1_r2 type=router \ + options:router-port=R2_ls-transfer1 addresses=\"router\" + +# Connect R1 to R2 (ls-transfer2) +ovn-nbctl lrp-add R1 R1_ls-transfer2 00:00:00:02:03:14 2001:db8:2::1/64 +ovn-nbctl lrp-add R2 R2_ls-transfer2 00:00:00:02:03:15 2001:db8:2::2/64 + +ovn-nbctl lsp-add ls-transfer2 ls-transfer2_r1 -- \ + set Logical_Switch_Port ls-transfer2_r1 type=router \ + options:router-port=R1_ls-transfer2 addresses=\"router\" +ovn-nbctl lsp-add ls-transfer2 ls-transfer2_r2 -- \ + set Logical_Switch_Port ls-transfer2_r2 type=router \ + options:router-port=R2_ls-transfer2 addresses=\"router\" + +AT_CHECK([ovn-nbctl lr-route-add R1 "0.0.0.0/0" 2001:db8:1::2]) +AT_CHECK([ovn-nbctl --ecmp lr-route-add R1 "0.0.0.0/0" 2001:db8:2::2]) +AT_CHECK([ovn-nbctl lr-route-add R2 "0.0.0.0/0" 2001:db8:1::1]) +AT_CHECK([ovn-nbctl --ecmp lr-route-add R2 "0.0.0.0/0" 2001:db8:2::1]) + +# Create logical port ls1-lp1 in ls1 +ovn-nbctl lsp-add ls1 ls1-lp1 \ +-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip" + +# Create logical port ls2-lp1 in ls2 +ovn-nbctl lsp-add ls2 ls2-lp1 \ +-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip" + +# Create two hypervisor and create OVS ports corresponding to logical ports. +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +sim_add hv2 +as hv2 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.2 +ovs-vsctl -- add-port br-int hv2-vif1 -- \ + set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \ + options:tx_pcap=hv2/vif1-tx.pcap \ + options:rxq_pcap=hv2/vif1-rx.pcap \ + ofport-request=1 + + +# Pre-populate the hypervisors' ARP tables so that we don't lose any +# packets for ARP resolution (native tunneling doesn't queue packets +# for ARP resolution). +OVN_POPULATE_ARP + +# Allow some time for ovn-northd and ovn-controller to catch up. +wait_for_ports_up +check ovn-nbctl --wait=hv sync + +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + +echo "---------NB dump-----" +ovn-nbctl show +echo "---------------------" +ovn-nbctl list logical_router +echo "---------------------" +ovn-nbctl list logical_router_port +echo "---------------------" + +echo "---------SB dump-----" +ovn-sbctl list datapath_binding +echo "---------------------" +ovn-sbctl list port_binding +echo "---------------------" + +echo "------ hv1 dump ----------" +as hv1 ovs-ofctl show br-int +as hv1 ovs-ofctl dump-flows br-int +echo "------ hv2 dump ----------" +as hv2 ovs-ofctl show br-int +as hv2 ovs-ofctl dump-flows br-int + +# Packet to Expect +# The TTL should be decremented by 2. +packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac && + ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +echo $packet | ovstest test-ovn expr-to-packets > expected + +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "reg0 == 172.16.1.2" | wc -l], [0], [1 +]) + +# Disable the ls2-lp1 port. +ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "reg0 == 172.16.1.2" | wc -l], [0], [0 +]) + +# Generate the packet destined for ls2-lp1 and it should not be delivered. +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" + +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) +# The 2nd packet sent shound not be received. +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +OVN_CLEANUP([hv1],[hv2]) + +AT_CLEANUP +]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([2 HVs, 2 LS, 1 lport/LS, 2 peer LRs, IPv6 over IPv4]) +ovn_start + +# Logical network: +# Two LRs - R1 and R2 that are connected to each other as peers in 10.0.0.0/24 +# network. R1 has a switchs ls1 (2001:db8:1::/64) connected to it. +# R2 has ls2 (2001:db8:2::/64) connected to it. + +ls1_lp1_mac="f0:00:00:01:02:03" +rp_ls1_mac="00:00:00:01:02:03" +rp_ls2_mac="00:00:00:01:02:04" +ls2_lp1_mac="f0:00:00:01:02:04" + +ls1_lp1_ip="2001:db8:1::2" +ls2_lp1_ip="2001:db8:2::2" + +ovn-nbctl lr-add R1 +ovn-nbctl lr-add R2 + +ovn-nbctl ls-add ls1 +ovn-nbctl ls-add ls2 + +# Connect ls1 to R1 +ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 2001:db8:1::1/64 + +ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \ + options:router-port=ls1 addresses=\"$rp_ls1_mac\" + +# Connect ls2 to R2 +ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 2001:db8:2::1/64 + +ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \ + options:router-port=ls2 addresses=\"$rp_ls2_mac\" + +# Connect R1 to R2 +ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 10.0.0.1/24 peer=R2_R1 +ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 10.0.0.2/24 peer=R1_R2 + +AT_CHECK([ovn-nbctl lr-route-add R1 "::/0" 10.0.0.2]) +AT_CHECK([ovn-nbctl lr-route-add R2 "::/0" 10.0.0.1]) + +# Create logical port ls1-lp1 in ls1 +ovn-nbctl lsp-add ls1 ls1-lp1 \ +-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip" + +# Create logical port ls2-lp1 in ls2 +ovn-nbctl lsp-add ls2 ls2-lp1 \ +-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip" + +# Create two hypervisor and create OVS ports corresponding to logical ports. +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 +ovs-vsctl -- add-port br-int hv1-vif1 -- \ + set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \ + options:tx_pcap=hv1/vif1-tx.pcap \ + options:rxq_pcap=hv1/vif1-rx.pcap \ + ofport-request=1 + +sim_add hv2 +as hv2 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.2 +ovs-vsctl -- add-port br-int hv2-vif1 -- \ + set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \ + options:tx_pcap=hv2/vif1-tx.pcap \ + options:rxq_pcap=hv2/vif1-rx.pcap \ + ofport-request=1 + + +# Pre-populate the hypervisors' ARP tables so that we don't lose any +# packets for ARP resolution (native tunneling doesn't queue packets +# for ARP resolution). +OVN_POPULATE_ARP + +# Allow some time for ovn-northd and ovn-controller to catch up. +wait_for_ports_up +check ovn-nbctl --wait=hv sync + +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip6 && ip.ttl==64 && ip6.src==$ls1_lp1_ip && ip6.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) + + +echo "---------NB dump-----" +ovn-nbctl show +echo "---------------------" +ovn-nbctl list logical_router +echo "---------------------" +ovn-nbctl list logical_router_port +echo "---------------------" + +echo "---------SB dump-----" +ovn-sbctl list datapath_binding +echo "---------------------" +ovn-sbctl list port_binding +echo "---------------------" + +echo "------ hv1 dump ----------" +as hv1 ovs-ofctl show br-int +as hv1 ovs-ofctl dump-flows br-int +echo "------ hv2 dump ----------" +as hv2 ovs-ofctl show br-int +as hv2 ovs-ofctl dump-flows br-int + +# Packet to Expect +# The TTL should be decremented by 2. +packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac && + ip6 && ip.ttl==62 && ip6.src==$ls1_lp1_ip && ip6.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" +echo $packet | ovstest test-ovn expr-to-packets > expected + +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "xxreg0 == 2001:db8:2::2" | wc -l], [0], [1 +]) + +# Disable the ls2-lp1 port. +ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false + +AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \ +grep "xxreg0 == 2001:db8:2::2" | wc -l], [0], [0 +]) + +# Generate the packet destined for ls2-lp1 and it should not be delivered. +# Packet to send. +packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac && + ip6 && ip.ttl==64 && ip6.src==$ls1_lp1_ip && ip6.dst==$ls2_lp1_ip && + udp && udp.src==53 && udp.dst==4369" + +OVS_WAIT_UNTIL([as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"]) +# The 2nd packet sent shound not be received. +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected]) + +OVN_CLEANUP([hv1],[hv2]) + +AT_CLEANUP +]) diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index 25eb86f7f..f827b2ad9 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -4546,11 +4546,9 @@ nbctl_lr_route_add(struct ctl_context *ctx) } char *route_table = shash_find_data(&ctx->options, "--route-table"); - bool v6_prefix = false; prefix = normalize_ipv4_prefix_str(ctx->argv[2]); if (!prefix) { prefix = normalize_ipv6_prefix_str(ctx->argv[2]); - v6_prefix = true; } if (!prefix) { ctl_error(ctx, "bad prefix argument: %s", ctx->argv[2]); @@ -4561,15 +4559,15 @@ nbctl_lr_route_add(struct ctl_context *ctx) if (is_discard_route) { next_hop = xasprintf("discard"); } else { - next_hop = v6_prefix - ? normalize_ipv6_addr_str(ctx->argv[3]) - : normalize_ipv4_addr_str(ctx->argv[3]); + next_hop = normalize_ipv4_addr_str(ctx->argv[3]); + if (!next_hop) { + next_hop = normalize_ipv6_addr_str(ctx->argv[3]); + } if (!next_hop) { /* check if it is a output port. */ error = lrp_by_name_or_uuid(ctx, ctx->argv[3], true, &out_lrp); if (error) { - ctl_error(ctx, "bad %s nexthop argument: %s", - v6_prefix ? "IPv6" : "IPv4", ctx->argv[3]); + ctl_error(ctx, "bad nexthop argument: %s", ctx->argv[3]); free(error); goto cleanup; }