From patchwork Mon Nov 4 11:04:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Huettner X-Patchwork-Id: 2006187 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=stackit.cloud header.i=@stackit.cloud header.a=rsa-sha256 header.s=selector1 header.b=YNoBSwvK; dkim=fail reason="signature verification failed" (2048-bit key) header.d=stackit.cloud header.i=@stackit.cloud header.a=rsa-sha256 header.s=selector1 header.b=YNoBSwvK; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (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 4Xhpb05Vxnz1xyJ for ; Mon, 4 Nov 2024 22:07:24 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id B5AD340E4E; Mon, 4 Nov 2024 11:07:19 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id wv171mXM-jWU; Mon, 4 Nov 2024 11:07:17 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 054AF40C7B Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=stackit.cloud header.i=@stackit.cloud header.a=rsa-sha256 header.s=selector1 header.b=YNoBSwvK; dkim=fail reason="signature verification failed" (2048-bit key) header.d=stackit.cloud header.i=@stackit.cloud header.a=rsa-sha256 header.s=selector1 header.b=YNoBSwvK Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 054AF40C7B; Mon, 4 Nov 2024 11:07:17 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 89B1AC08A3; Mon, 4 Nov 2024 11:07:16 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2F0FEC08A3 for ; Mon, 4 Nov 2024 11:07:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 2BBE040990 for ; Mon, 4 Nov 2024 11:05:14 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id wfgxs_qYfoIz for ; Mon, 4 Nov 2024 11:05:11 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2a01:111:f403:260e::628; helo=eur03-am7-obe.outbound.protection.outlook.com; envelope-from=felix.huettner@stackit.cloud; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org 0DD02409FF Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=reject dis=none) header.from=stackit.cloud DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 0DD02409FF Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key, unprotected) header.d=stackit.cloud header.i=@stackit.cloud header.a=rsa-sha256 header.s=selector1 header.b=YNoBSwvK; dkim=pass (2048-bit key) header.d=stackit.cloud header.i=@stackit.cloud header.a=rsa-sha256 header.s=selector1 header.b=YNoBSwvK Received: from EUR03-AM7-obe.outbound.protection.outlook.com (mail-am7eur03on20628.outbound.protection.outlook.com [IPv6:2a01:111:f403:260e::628]) by smtp2.osuosl.org (Postfix) with ESMTPS id 0DD02409FF for ; Mon, 4 Nov 2024 11:05:00 +0000 (UTC) ARC-Seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=bBpUHJeljF82ZXl8VuQRSn8FdtG5J4cuiPv+yWh63rlZ7GThNdnfrtjh/eir+YtotEb4cfVWk0gNWhUAS3gf0JRLBzff0l3QPn+Tvuiil0g829UZ8be3RIq9qBw6l3GDtxVxc1ibYu+ixwEUO7V35yBChdRKyr8cBc5PaWW13IiEaBXZHpz7MQ8yyEJjPLIyvd80zj3EEaabx4EOCrkxweK8fGwf1IQ9/uuR8Jt6CIKWmwddZRJ7VJMiBxirEvQK9BPptal7bs4ka7jDxMAsCiXzXgixHa4U+JyoHwwWQRAPVB983levwEexsJXzOfsBI3epECGBO8w4KHGgkw/Cbg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=1KzVf61YhxKU3jM0UYB2zXXM6rBCHCl1O3JHai6Sfdg=; b=Wlr+BJ2Kyxu65Cp6Kpr/Sxd56KfRHsIxgmBQaqX+TO+PqCZGb1pEGu4mL20VHpYqe+cgnup6keJRt8aOmXenIqG7JOykaYXa4w8nh/hIgqQwnf4KV+PRGL9HNN5FjdnbKfev6yelQWPpMGLnSKRtVqdqvBxRaJzMSxdpfB8IWFNOLCzhjzOycyZr+zj8FUqBnTyG+OMh6swhYxEymizfIlsj/D4Jo4eYO9t1EmFktOs8nY8SQbcWtCyPCLsolr6mt0w2gRXUb4x37Be5KMI8HGNBFVy4RIUXynzEWXaaUAegEJ21bGd11s57MsE8YntgY6Ug5tptFcXQ6x1m6FldAQ== ARC-Authentication-Results: i=2; mx.microsoft.com 1; spf=fail (sender ip is 104.40.229.156) smtp.rcpttodomain=openvswitch.org smtp.mailfrom=stackit.cloud; dmarc=pass (p=reject sp=none pct=100) action=none header.from=stackit.cloud; dkim=pass (signature was verified) header.d=stackit.cloud; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=stackit.cloud] dkim=[1,1,header.d=stackit.cloud] dmarc=[1,1,header.from=stackit.cloud]) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=stackit.cloud; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1KzVf61YhxKU3jM0UYB2zXXM6rBCHCl1O3JHai6Sfdg=; b=YNoBSwvKjhd1JSvjkNA4hG/YYaJvI+CKiG1fasvaLi8BZr3+MtFwfDKuIzVAIXoI4aVV1idXGJUs07K59j1qVeJCzFdPzFpKM7oKhxTu2+qzfUyOzl0pRlKWXrMr2pnQXt6p952ilefSFbgEHuM0k3BYTU2/xWL6cfWeKRaWDkIOS5OT0jIitznRw1XImH80EVHtLoOdq+XulwP9qtvqnhOgGbdPScMo8jrnSGw42dtfVXgsmJi12DqeUiODalGl0bZIVouNF56IxsCjZBPwiTJr1HDsWPb2g+78QA9upam5DWgsp3pWkf2Hpa3/YiZgVA3sGPW9IHODmaHfQUc9Ng== Received: from DUZPR01CA0084.eurprd01.prod.exchangelabs.com (2603:10a6:10:46a::11) by PAVPR10MB6909.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:102:328::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8137.15; Mon, 4 Nov 2024 11:04:57 +0000 Received: from DB3PEPF0000885F.eurprd02.prod.outlook.com (2603:10a6:10:46a:cafe::60) by DUZPR01CA0084.outlook.office365.com (2603:10a6:10:46a::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8114.30 via Frontend Transport; Mon, 4 Nov 2024 11:04:57 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 104.40.229.156) smtp.mailfrom=stackit.cloud; dkim=pass (signature was verified) header.d=stackit.cloud;dmarc=pass action=none header.from=stackit.cloud; Received-SPF: Fail (protection.outlook.com: domain of stackit.cloud does not designate 104.40.229.156 as permitted sender) receiver=protection.outlook.com; client-ip=104.40.229.156; helo=eu1.smtp.exclaimer.net; Received: from eu1.smtp.exclaimer.net (104.40.229.156) by DB3PEPF0000885F.mail.protection.outlook.com (10.167.242.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8137.17 via Frontend Transport; Mon, 4 Nov 2024 11:04:57 +0000 Received: from EUR05-AM6-obe.outbound.protection.outlook.com (104.47.18.108) by eu1.smtp.exclaimer.net (104.40.229.156) with Exclaimer Signature Manager ESMTP Proxy eu1.smtp.exclaimer.net (tlsversion=TLS12, tlscipher=TLS_DIFFIEHELLMAN_WITH_AES256_NONE); Mon, 4 Nov 2024 11:04:57 +0000 X-ExclaimerHostedSignatures-MessageProcessed: true X-ExclaimerProxyLatency: 8273803 X-ExclaimerImprintLatency: 2948171 X-ExclaimerImprintAction: fed1e82026b04795b8373f343ff6962e ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=xrQxb1grKSq5YX2wUHYO9Gbk4bJolVcinjne0kIlzmpTCaNw4ZwxDee7D6iRPq/61IEb3UKeYvn5SN/Zq6fZb2rTURs7OY2cZuz8FDe09sqejMkQOO/0CFODjnCm+qilChJ78Lzjiyc3iH7gXra0/8+zI9R+w3o+qURO9pdcZCWn/jtKeKFDzCPN3+Va+DLRkes2vCaVP8ti1m/Q6F80pAYNxUg5ybwsDyhBxui00X581iCFVSSr2u7ZNvUfTSl0Xs4aeXQy/wma8HFgkG+kplHg1n0mtuNz31E/w26rBXos2Jp0P99rqszuk56cepDuG3i3rKB4EHTGvJeSNU/mbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=1KzVf61YhxKU3jM0UYB2zXXM6rBCHCl1O3JHai6Sfdg=; b=gZgtdleTa+OM6jqass5EmIP7GTZubG6g0s/QBn21rkwYGm5GTyIC0PzNfEIVWHg6EDtqvSkVLFWjspV8UsR8Rj1B8HEL+oFneMinEhzKs2rj0M1YO0+0t1KQi/Cy+sVSlcWear5ejRCzALIgQAKg5HKGMWcPfnInHf+GJid9KJcvQOzaP+TiCExKsLwhEkWiwBkTXctI+niCc9UPSDHHNBHB7Q/jOCy9Raux8ZnTHvq+x/JBVmV2NCxwfRPQ/1W7PJft0IruNrEu4xOYKk3EY9Aw+a8uif+6IHh/6dBzOekosThryxmOr5ee/n9S47/V/JFfIICcTowWuVmjyOHPSQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=stackit.cloud; dmarc=pass action=none header.from=stackit.cloud; dkim=pass header.d=stackit.cloud; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=stackit.cloud; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1KzVf61YhxKU3jM0UYB2zXXM6rBCHCl1O3JHai6Sfdg=; b=YNoBSwvKjhd1JSvjkNA4hG/YYaJvI+CKiG1fasvaLi8BZr3+MtFwfDKuIzVAIXoI4aVV1idXGJUs07K59j1qVeJCzFdPzFpKM7oKhxTu2+qzfUyOzl0pRlKWXrMr2pnQXt6p952ilefSFbgEHuM0k3BYTU2/xWL6cfWeKRaWDkIOS5OT0jIitznRw1XImH80EVHtLoOdq+XulwP9qtvqnhOgGbdPScMo8jrnSGw42dtfVXgsmJi12DqeUiODalGl0bZIVouNF56IxsCjZBPwiTJr1HDsWPb2g+78QA9upam5DWgsp3pWkf2Hpa3/YiZgVA3sGPW9IHODmaHfQUc9Ng== Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=stackit.cloud; Received: from PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:102:30d::9) by PA2PR10MB8449.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:102:425::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8137.16; Mon, 4 Nov 2024 11:04:55 +0000 Received: from PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM ([fe80::f00d:feeb:e45e:54f8]) by PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM ([fe80::f00d:feeb:e45e:54f8%7]) with mapi id 15.20.8137.013; Mon, 4 Nov 2024 11:04:55 +0000 Date: Mon, 4 Nov 2024 12:04:53 +0100 To: dev@openvswitch.org Message-ID: Mail-Followup-To: dev@openvswitch.org References: Content-Disposition: inline In-Reply-To: X-please-dont-add-a-signature: thanks X-ClientProxiedBy: FR3P281CA0107.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:a3::17) To PAVPR10MB6914.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:102:30d::9) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: PAVPR10MB6914:EE_|PA2PR10MB8449:EE_|DB3PEPF0000885F:EE_|PAVPR10MB6909:EE_ X-MS-Office365-Filtering-Correlation-Id: f1443ffe-0c3a-4054-f55d-08dcfcc08502 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0;ARA:13230040|376014|1800799024|366016; X-Microsoft-Antispam-Message-Info-Original: sZVWqAcj+QZvwt6wWAaTyxWFBDY9tIx6bMAJfs3UYd/z7/sjzqalt6BqXYBFNQRp3YY8jfT9f2kVn9GHz/bQMV0CXu5BG5rcMWIa8k8+Ra1JeMaERfDFn4xpKaspHB4OT7qMliNl3wTTxTo/qrJJRakx5EuDg80hTjTuEn+2sqbLxzxxwraiq7CwPaeWwJBocZSRstVfc8qv2fNZ9YwC4rXUC/MlyANgoM8niYfVelQ2uVrJmKYSVAtg1GNXI3mK43jiNfnJGGSr/3gh9aGEV40/8dohrwOwJ01DTUHfI/iZwd5GlFDPicr0K6Fb/co7W0i/MCoUz4rSm/UeoQHY77uaxuooCFWAX/BgPP/7y2KaGEUGmw+S5hn7PgSLEOS00ZR3dijpkXQ8JYBPdDxMVpBWghOi49APtPib21+xjCkSPkuwfkVLpgFBItELvJcxSRHbWL7hWf+SkCOx5LarJjylEL0PIg6MIvhh/LVkRFtNy+IPeeDF4/RkD+jAMAgDkBWSJjmUZws5XdISr0XX85Ac8GvRgmJNJAiXMkRn3UIUY/sW2mVsck9MwGh5/BJdJuNpGYW7ta2uISR4N692xrZ7QfrPc7FrD++P83lBv/yIjaHVZkE/NbDwOd6EL9BQ/gQMr3j3HvklufxMh9+9Rba3r11MAFd0JofqjS6gt5oxmwqfKwUK6X9bKQiXnah5e+h35AUaXhDpoPMRjbicVTgnWquL1mVMt45oxyQa4D9XCkXdrIdyHrgGVLTv1iVOzdBJvHnr8c3lrtVpkp8izOPX6M8kbVCSan3B4p+ovlUwQfPhWJNdTwe8NTDSgEh7DPKoTx9dPWxz4JPXvyPfd96n7GE3NpEY9OGNGf7UMQnd3UDM5GVdkYHewlVVb+uw4PlrvhBPClERXoHoX2jlCBhp3ZjHjp00npx2SP7hLE20aqe0XkPR2FoUHkle5RCrBPaIEpb/OXnJn+OfbRRNPTu+eAY6bbONB2QkReIZUOJcExDL6ZCEsrGAT/bN70r8smX7hE6/XD5JpWrN69mpSzRaLFnVOrKf8svK42vMNBj5WQybSJN4zmDC452njH4fKnjq90HrK3PlcWjET6Pq+JeRoP1NmRk7m1YJllR2irdyA5o6C9e1MK864tTCwn3usXLRT75GjgioBt8fQOP6H2ictMKdBK9O1GblLQgYR44EobT1E71ABnkh2xPMJQOQfkeODDW3iLVPeKqGlcKoLg2AB/bAxqBqX46+7fXHkaDG5+P7lntrqaZovfQu//vAJ1fsRgffQJ8Wz9XjXpayEj3ZQNd8dpILNudN0/pfM8HlR1QAgWl9sBYN0l5NFrqJ 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:(13230040)(376014)(1800799024)(366016); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: PA2PR10MB8449 X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB3PEPF0000885F.eurprd02.prod.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 1747cbbd-4cd7-4b49-f775-08dcfcc08394 X-Microsoft-Antispam: BCL:0; ARA:13230040|14060799003|36860700013|376014|35042699022|1800799024|82310400026; X-Microsoft-Antispam-Message-Info: 4LJOZSDwd12UmHqvw224WOmjRRRpU521ZwStcFkiCSFoirEDPSZ7jWqkd6gmFaTuECscTmP9ZUgqG6ND3uuTui7tYY1Y/0BPyVsohIUtVCeNQ8nTfTmNW9k8ZZJVb8O0fiI/7Sj5R2vhEiePHt1UDTQ7GeLcWOOmqb8rzK0T/5gfO27K7hc36pWisB57edP2WXDeI4RdmfsI9YKHI/bnXa8sYkFQjkx9ascL8NeU0yR42IetYCtEycp1S86lZeiLY/MqdM+GjeRGz2TQqOxzgmq9Ic+1xTScvL/k01N4p6+xhJC+YNhcB61Gzqc9Z01xM59HtRysECRjx58SuF/HQWKLz0m6ROxXteHEoInTehE156M4Q0Z1zS8mDm99U3iUp4QJH/WQlTcwKlLuFSNz48P5mdCbGaTVrgl4oKP4G//J7e7Xh0pkdGOlgKlJahADdyshuBeS0SEHebO/lPpOZIbEv5UXZBUBqWu8v2OWY6TcBn0H5AENKnWFuEi9tDqBKR6oWPmW1QJAs10r9uX5SLNPojeT4B9jyFDXMre5d6qEJJ3k3VFWGcKE/mSCr/mcjpm82w5n8KXfnBKBhYpGZQM2JNIwAF3NVkXEndyNiAlVUsNletgNtrl+GQAellapH1RC4WRPApoWAFFGYd4MBwyYdn4xGGJ3wFEt6S7AkL3aO9LgsvxCQ11GRzCpruHBZjwt0KnQhA1WwPAKeBdIH4m3s3+WBpD3vhH0C6CxvVIxJge62xNmjGz4pPzrqKm8aQWyiASf1357zjCoZeAAReU2zh6PcKbnI6Qj8UEDzz13L6CkOkLNOKtw35jk07Zp/ldx9tDcBLHEEzA0n9UI6MK8VKE9F2u5Z2HhL3JU0EG/XNY36d468jotULsnMQ5s0UiGl2CriQh6rk41T0K1hZVCpcmpvly9ZVzF5wvhhLNx4Jx4xtz1Tu59WvF2zmHt1A+2KwZ8pPj4TnIMP3edNnDYnMrRogx3EDzO+7kc1reOGzzLwfdUP2OMLfCR6sqwdueMukys22wBjvaFAGgd3mw579//dHrxI/6zlWqo/a5+HjnQtZbS/3fcEQWWOxuz2BSIOKLxtCYCGTdPwYkWAoZpFxOPAG6VSy7RU8478Vt6cJ1Z5wonU++QGiT63HylYhELnWqqnSpZBkBR/x+uTBabI34HQiK2ZfEaxcrOAVptE8O684836qYx3BWEm/ZWVhH9Ebom/b23kr8gHu2QJ0k2Pd5gjLXKGFcpkEhtPzNyNbiKecyqWnTVdZHt+JB4gB94dx3/dDxLLepWiVjk2dnfv0e74p/nldeIBObQPB4a8z7tIxD5bKhinAQolEPxN3Ubq2kQ/OZFHdqbFn09ehHjYvCAUGlUYEznThn9ba+TvyqcXAx4D2IIx+1ymF+L35Dbtgdda2xvpl0BgG0Vow== 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:(13230040)(14060799003)(36860700013)(376014)(35042699022)(1800799024)(82310400026); DIR:OUT; SFP:1101; X-OriginatorOrg: stackit.cloud X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Nov 2024 11:04:57.1189 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f1443ffe-0c3a-4054-f55d-08dcfcc08502 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: DB3PEPF0000885F.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAVPR10MB6909 Subject: [ovs-dev] [PATCH ovn v2 29/32] northd: Support active-active lrps. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 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 case we find a LRP (or a LSP connected to a LRP) that has options:active-active-lrp set we ignore it during normal processing in join_logical_ports. We add an additional section at the end where we then use these ports to generate derived Port_Bindings for each LRP + LSP combination once for each matching ovn-aa-port-mappings entry. In the end this gives us the same result as if someone would have precreated a LRP + LSP combination for each ovn-aa-port-mappings in the northbound. However it allows our users to benefit from active-active routing without their CMS needing to know about this feature (besides the active-active-lrp setting). Signed-off-by: Felix Huettner --- lib/automake.mk | 2 + lib/lrp-index.c | 43 +++++++ lib/lrp-index.h | 25 ++++ lib/ovn-util.c | 97 ++++++++++++++ lib/ovn-util.h | 11 ++ northd/en-northd.c | 4 + northd/inc-proc-northd.c | 6 + northd/northd.c | 272 +++++++++++++++++++++++++++++++++++++-- northd/northd.h | 10 ++ 9 files changed, 456 insertions(+), 14 deletions(-) create mode 100644 lib/lrp-index.c create mode 100644 lib/lrp-index.h diff --git a/lib/automake.mk b/lib/automake.mk index b69e854b0..90b8ed5a4 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -26,6 +26,8 @@ lib_libovn_la_SOURCES = \ lib/ovn-parallel-hmap.c \ lib/ip-mcast-index.c \ lib/ip-mcast-index.h \ + lib/lrp-index.c \ + lib/lrp-index.h \ lib/mac-binding-index.c \ lib/mac-binding-index.h \ lib/mcast-group-index.c \ diff --git a/lib/lrp-index.c b/lib/lrp-index.c new file mode 100644 index 000000000..ac64c4b45 --- /dev/null +++ b/lib/lrp-index.c @@ -0,0 +1,43 @@ +/* + * 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 "lib/lrp-index.h" +#include "lib/ovn-nb-idl.h" + +struct ovsdb_idl_index * +lrp_index_create(struct ovsdb_idl *idl) +{ + return ovsdb_idl_index_create1(idl, &nbrec_logical_router_port_col_name); +} + + +/* Finds and returns the lrp with the given 'name', or NULL if no such + * lrp exists. */ +const struct nbrec_logical_router_port * +lrp_lookup_by_name(struct ovsdb_idl_index *nbrec_lrp_by_name, + const char *name) +{ + struct nbrec_logical_router_port *target = + nbrec_logical_router_port_index_init_row(nbrec_lrp_by_name); + nbrec_logical_router_port_index_set_name(target, name); + + struct nbrec_logical_router_port *retval = + nbrec_logical_router_port_index_find(nbrec_lrp_by_name, target); + + nbrec_logical_router_port_index_destroy_row(target); + + return retval; +} + diff --git a/lib/lrp-index.h b/lib/lrp-index.h new file mode 100644 index 000000000..2c56933fc --- /dev/null +++ b/lib/lrp-index.h @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#ifndef OVN_LRP_INDEX_H +#define OVN_LRP_INDEX_H 1 + +struct ovsdb_idl; + +struct ovsdb_idl_index *lrp_index_create(struct ovsdb_idl *); + +const struct nbrec_logical_router_port *lrp_lookup_by_name( + struct ovsdb_idl_index *nbrec_lrp_by_name, const char *name); + +#endif /* lib/lrp-index.h */ diff --git a/lib/ovn-util.c b/lib/ovn-util.c index 5d0db1a5a..c86f6f209 100644 --- a/lib/ovn-util.c +++ b/lib/ovn-util.c @@ -1074,6 +1074,103 @@ get_chassis_external_id_value_bool(const struct smap *external_ids, return ret; } +bool +chassis_find_active_active_networks(const struct sbrec_chassis *chassis, + const char *network_name, + struct chassis_aa_network + *chassis_aa_network) { + memset(chassis_aa_network, 0, sizeof *chassis_aa_network); + + const char *aa_ports = smap_get(&chassis->other_config, + "ovn-active-active-mappings"); + bool found = false; + char *curnet, *nextnet, *curport, *nextport, *start; + + /* Structure + * ovn-active-active-mappings="|" + * network=";;" + * port="," */ + nextnet = start = xstrdup(aa_ports); + while ((curnet = strsep(&nextnet, "|")) && *curnet) { + nextport = curnet; + char *network = strsep(&nextport, ";"); + if (strcmp(network, network_name)) { + continue; + } + found = true; + chassis_aa_network->network_name = xstrdup(network); + chassis_aa_network->n_addresses = 0; + while ((curport = strsep(&nextport, ";")) && *curport) { + char *mac, *ip; + + mac = strsep(&curport, ","); + ip = curport; + + if (!mac || !ip || !*mac || !*ip) { + VLOG_ERR("Invalid format for " + "ovn-active-active-mappings '%s'", + aa_ports); + continue; + } + + chassis_aa_network->addresses = xrealloc( + chassis_aa_network->addresses, + (chassis_aa_network->n_addresses + 1 + ) * sizeof *chassis_aa_network->addresses); + struct lport_addresses *address = + &chassis_aa_network->addresses[ + chassis_aa_network->n_addresses]; + init_lport_addresses(address); + + if (!eth_addr_from_string(mac, &address->ea)) { + VLOG_ERR("Invalid mac address in " + "ovn-active-active-mappings '%s'", + aa_ports); + free(address); + continue; + } + snprintf(address->ea_s, sizeof address->ea_s, ETH_ADDR_FMT, + ETH_ADDR_ARGS(address->ea)); + + ovs_be32 ip4; + struct in6_addr ip6; + unsigned int plen; + char *error; + + error = ip_parse_cidr(ip, &ip4, &plen); + if (!error) { + if (!ip4) { + VLOG_ERR("Invalid ip address in " + "ovn-active-active-mappings '%s'", + aa_ports); + destroy_lport_addresses(address); + continue; + } + + add_ipv4_netaddr(address, ip4, plen); + } else { + free(error); + + error = ipv6_parse_cidr(ip, &ip6, &plen); + if (!error) { + add_ipv6_netaddr(address, ip6, plen); + } else { + VLOG_ERR("Invalid ip address in " + "ovn-active-active-mappings '%s'", + aa_ports); + destroy_lport_addresses(address); + free(error); + continue; + } + } + chassis_aa_network->n_addresses++; + } + } + + free(start); + return found; +} + void flow_collector_ids_init(struct flow_collector_ids *ids) { ovs_list_init(&ids->list); diff --git a/lib/ovn-util.h b/lib/ovn-util.h index 3ccd7d003..24ee55a9c 100644 --- a/lib/ovn-util.h +++ b/lib/ovn-util.h @@ -44,6 +44,7 @@ struct ovsrec_flow_sample_collector_set_table; struct sbrec_datapath_binding; struct sbrec_logical_flow; struct sbrec_port_binding; +struct sbrec_chassis; struct smap; struct svec; struct uuid; @@ -351,6 +352,16 @@ int64_t daemon_startup_ts(void); char *lr_lb_address_set_name(uint32_t lr_tunnel_key, int addr_family); char *lr_lb_address_set_ref(uint32_t lr_tunnel_key, int addr_family); +struct chassis_aa_network { + char *network_name; + struct lport_addresses *addresses; + size_t n_addresses; +}; + +bool chassis_find_active_active_networks(const struct sbrec_chassis *, + const char *, + struct chassis_aa_network *); + const char * get_chassis_external_id_value(const struct smap *, const char *chassis_id, diff --git a/northd/en-northd.c b/northd/en-northd.c index 8152ccbcf..664ace650 100644 --- a/northd/en-northd.c +++ b/northd/en-northd.c @@ -41,6 +41,10 @@ static void northd_get_input_data(struct engine_node *node, struct northd_input *input_data) { + input_data->nbrec_lrp_by_name = + engine_ovsdb_node_get_index( + engine_get_input("NB_logical_router", node), + "nbrec_lrp_by_name"); input_data->sbrec_chassis_by_name = engine_ovsdb_node_get_index( engine_get_input("SB_chassis", node), diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c index 99318c633..22227f349 100644 --- a/northd/inc-proc-northd.c +++ b/northd/inc-proc-northd.c @@ -19,6 +19,7 @@ #include #include "chassis-index.h" +#include "lrp-index.h" #include "ip-mcast-index.h" #include "static-mac-binding-index.h" #include "lib/inc-proc-eng.h" @@ -361,6 +362,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, .sb_idl = sb->idl, }; + struct ovsdb_idl_index *nbrec_lrp_by_name = + lrp_index_create(nb->idl); struct ovsdb_idl_index *sbrec_chassis_by_name = chassis_index_create(sb->idl); struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name = @@ -380,6 +383,9 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, engine_init(&en_northd_output, &engine_arg); + engine_ovsdb_node_add_index(&en_nb_logical_router, + "nbrec_lrp_by_name", + nbrec_lrp_by_name); engine_ovsdb_node_add_index(&en_sb_chassis, "sbrec_chassis_by_name", sbrec_chassis_by_name); diff --git a/northd/northd.c b/northd/northd.c index 69d86f1c7..6884b7a0e 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -14,6 +14,7 @@ #include +#include #include #include @@ -30,9 +31,11 @@ #include "hmapx.h" #include "openvswitch/hmap.h" #include "openvswitch/json.h" +#include "openvswitch/shash.h" #include "ovn/lex.h" #include "lb.h" #include "lib/chassis-index.h" +#include "lib/lrp-index.h" #include "lib/ip-mcast-index.h" #include "lib/static-mac-binding-index.h" #include "lib/copp.h" @@ -1252,6 +1255,11 @@ ovn_port_cleanup(struct ovn_port *port) free(port->ps_addrs); port->ps_addrs = NULL; port->n_ps_addrs = 0; + if (port->is_active_active) { + ovs_assert(port->aa_chassis_name); + free(port->aa_mac); + free(port->aa_chassis_name); + } destroy_lport_addresses(&port->lrp_networks); destroy_lport_addresses(&port->proxy_arp_addrs); @@ -1433,6 +1441,32 @@ lrport_is_enabled(const struct nbrec_logical_router_port *lrport) return !lrport->enabled || *lrport->enabled; } +static bool +lrport_is_active_active(const struct nbrec_logical_router_port *lrport) +{ + if (!lrport) { + return false; + } + return smap_get_bool(&lrport->options, "active-active-lrp", false); +} + +static const struct nbrec_logical_router_port* +lsp_get_peer(struct ovsdb_idl_index *nbrec_lrp_by_name, + const struct nbrec_logical_switch_port *nbsp) +{ + if (!lsp_is_router(nbsp)) { + return NULL; + } + + const char *peer_name = smap_get( ->options, "router-port"); + if (!peer_name) { + return NULL; + } + + return lrp_lookup_by_name(nbrec_lrp_by_name, peer_name); +} + + static bool lsp_force_fdb_lookup(const struct ovn_port *op) { @@ -1462,6 +1496,18 @@ ovn_port_get_peer(const struct hmap *lr_ports, struct ovn_port *op) return ovn_port_find(lr_ports, peer_name); } +static const char * +ovn_port_get_mac(struct ovn_port *op) +{ + if (op->is_active_active) { + return op->aa_mac; + } else if (op->primary_port && op->primary_port->is_active_active) { + return op->primary_port->aa_mac; + } else { + return op->nbrp->mac; + } +} + static void ipam_insert_ip_for_datapath(struct ovn_datapath *od, uint32_t ip, bool dynamic) { @@ -2295,13 +2341,19 @@ join_logical_ports_lrp(struct hmap *ports, return op; } +struct active_active_port { + const struct nbrec_logical_switch_port *nbsp; + const struct nbrec_logical_router_port *nbrp; + struct ovn_datapath *switch_dp; + struct ovn_datapath *router_dp; +}; + static struct ovn_port * create_cr_port(struct ovn_port *op, struct hmap *ports, struct ovs_list *both_dbs, struct ovs_list *nb_only) { - char *redirect_name = ovn_chassis_redirect_name( - op->nbsp ? op->nbsp->name : op->nbrp->name); + char *redirect_name = ovn_chassis_redirect_name(op->key); struct ovn_port *crp = ovn_port_find(ports, redirect_name); if (crp && crp->sb && crp->sb->datapath == op->od->sb) { @@ -2346,6 +2398,8 @@ peer_needs_cr_port_creation(struct ovn_port *op) static void join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, + struct ovsdb_idl_index *nbrec_lrp_by_name, + struct ovsdb_idl_index *sbrec_chassis_by_name, struct hmap *ls_datapaths, struct hmap *lr_datapaths, struct hmap *ports, unsigned long *queue_id_bitmap, struct hmap *tag_alloc_table, struct ovs_list *sb_only, @@ -2355,6 +2409,8 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, ovs_list_init(nb_only); ovs_list_init(both); + struct shash active_active_ports = SHASH_INITIALIZER(&active_active_ports); + const struct sbrec_port_binding *sb; SBREC_PORT_BINDING_TABLE_FOR_EACH (sb, sbrec_pb_table) { struct ovn_port *op = ovn_port_create(ports, sb->logical_port, @@ -2371,6 +2427,20 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, = od->nbr->ports[i]; struct lport_addresses lrp_networks; + + if (lrport_is_active_active(nbrp)) { + struct ovn_port *op = ovn_port_find_bound(ports, nbrp->name); + if (op) { + ovs_list_remove(&op->list); + } + struct active_active_port *aap = xzalloc( + sizeof(struct active_active_port)); + aap->nbrp = nbrp; + aap->router_dp = od; + shash_add(&active_active_ports, nbrp->name, aap); + continue; + } + if (!extract_lrp_networks(nbrp, &lrp_networks)) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); @@ -2388,6 +2458,16 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, for (size_t i = 0; i < od->nbs->n_ports; i++) { const struct nbrec_logical_switch_port *nbsp = od->nbs->ports[i]; + const struct nbrec_logical_router_port *nbrp + = lsp_get_peer(nbrec_lrp_by_name, nbsp); + if (lrport_is_active_active(nbrp)) { + struct active_active_port *aap = + shash_find_data(&active_active_ports, nbrp->name); + ovs_assert(aap); + aap->nbsp = nbsp; + aap->switch_dp = od; + continue; + } join_logical_ports_lsp(ports, nb_only, both, od, nbsp, nbsp->name, queue_id_bitmap, tag_alloc_table); @@ -2466,6 +2546,103 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, } } + /* Now we setup the active-active lrp/lsps */ + struct shash_node *aa_snode; + SHASH_FOR_EACH (aa_snode, &active_active_ports) { + const struct active_active_port *aap = aa_snode->data; + const struct nbrec_logical_switch_port *nbsp = aap->nbsp; + const struct nbrec_logical_router_port *nbrp = aap->nbrp; + ovs_assert(nbrp); + ovs_assert(aap->switch_dp); + ovs_assert(aap->router_dp); + + if (aap->switch_dp->n_localnet_ports != 1) { + static struct vlog_rate_limit rl + = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "active-active lrp '%s' is not connect to a " + "ls with exactly one localnet port", nbrp->name); + continue; + } + + const struct ovn_port *localnet_port = + aap->switch_dp->localnet_ports[0]; + + const char *network_name = + smap_get(&localnet_port->nbsp->options, "network_name"); + if (!network_name) { + static struct vlog_rate_limit rl + = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "active-active lrp '%s' has a localnet port " + "connected with no network_name", nbrp->name); + continue; + } + + if (!nbrp->ha_chassis_group) { + static struct vlog_rate_limit rl + = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "missing 'ha_chassis_group' for" + " active-active-port %s", nbrp->name); + continue; + } + + for (size_t i = 0; i < nbrp->ha_chassis_group->n_ha_chassis; i++) { + const struct nbrec_ha_chassis *hc + = nbrp->ha_chassis_group->ha_chassis[i]; + + const struct sbrec_chassis *chassis = chassis_lookup_by_name( + sbrec_chassis_by_name, hc->chassis_name); + if (!chassis) { + static struct vlog_rate_limit rl + = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "'ha_chassis_group' contains not found" + " chassis %s", hc->chassis_name); + continue; + } + + struct chassis_aa_network networks; + if (!chassis_find_active_active_networks(chassis, network_name, + &networks)) { + static struct vlog_rate_limit rl + = VLOG_RATE_LIMIT_INIT(5, 1); + VLOG_WARN_RL(&rl, "chassis %s does not contain network" + " but it is in ha_chassis_group", chassis->name); + continue; + } + + for (size_t j = 0; j < networks.n_addresses; j++) { + char *lrp_name = xasprintf("%s-%s-%"PRIuSIZE, + nbrp->name, chassis->name, j); + char *lsp_name = xasprintf("%s-%s-%"PRIuSIZE, + nbsp->name, chassis->name, j); + struct ovn_port *lrp = + join_logical_ports_lrp(ports, nb_only, both, &dgps, + aap->router_dp, nbrp, + lrp_name, &networks.addresses[j]); + struct ovn_port *lsp = + join_logical_ports_lsp(ports, nb_only, both, + aap->switch_dp, nbsp, + lsp_name, queue_id_bitmap, + tag_alloc_table); + free(lrp_name); + free(lsp_name); + if (!lrp || !lsp) { + continue; + } + lrp->peer = lsp; + lsp->peer = lrp; + lrp->is_active_active = true; + lsp->is_active_active = true; + lrp->aa_mac = xstrdup(networks.addresses[j].ea_s); + lrp->aa_chassis_name = xstrdup(chassis->name); + lsp->aa_chassis_name = xstrdup(chassis->name); + lrp->aa_chassis_index = j; + lsp->aa_chassis_index = j; + } + free(networks.network_name); + free(networks.addresses); + } + } + struct hmapx_node *hmapx_node; HMAPX_FOR_EACH (hmapx_node, &dgps) { op = hmapx_node->data; @@ -2523,6 +2700,8 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, HMAP_FOR_EACH (op, key_node, ports) { ipam_add_port_addresses(op->od, op); } + + shash_destroy_free_data(&active_active_ports); } /* Returns an array of strings, each consisting of a MAC address followed @@ -2876,6 +3055,51 @@ sync_ha_chassis_group_for_sbpb( sbrec_port_binding_set_ha_chassis_group(pb, sb_ha_grp); } +static char * +generate_ha_chassis_group_active_active( + struct ovsdb_idl_txn *ovnsb_txn, + struct ovsdb_idl_index *sbrec_chassis_by_name, + struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name, + const char *chassis_name, + const struct sbrec_port_binding *pb) +{ + bool new_sb_chassis_group = false; + char *chassis_group_name = xasprintf( + "active-active-fixed-%s", chassis_name); + const struct sbrec_ha_chassis_group *sb_ha_grp = + ha_chassis_group_lookup_by_name( + sbrec_ha_chassis_grp_by_name, chassis_group_name); + + if (!sb_ha_grp) { + sb_ha_grp = sbrec_ha_chassis_group_insert(ovnsb_txn); + sbrec_ha_chassis_group_set_name(sb_ha_grp, chassis_group_name); + new_sb_chassis_group = true; + } + + if (new_sb_chassis_group) { + struct sbrec_ha_chassis **sb_ha_chassis = NULL; + sb_ha_chassis = xcalloc(1, sizeof *sb_ha_chassis); + const struct sbrec_chassis *chassis = + chassis_lookup_by_name(sbrec_chassis_by_name, chassis_name); + sb_ha_chassis[0] = sbrec_ha_chassis_insert(ovnsb_txn); + /* It's perfectly ok if the chassis is NULL. This could + * happen when ovn-controller exits and removes its row + * from the chassis table in OVN SB DB. */ + sbrec_ha_chassis_set_chassis(sb_ha_chassis[0], chassis); + sbrec_ha_chassis_set_priority(sb_ha_chassis[0], 1); + const struct smap external_ids = + SMAP_CONST1(&external_ids, "chassis-name", + chassis_name); + sbrec_ha_chassis_set_external_ids(sb_ha_chassis[0], &external_ids); + sbrec_ha_chassis_group_set_ha_chassis(sb_ha_grp, sb_ha_chassis, + 1); + free(sb_ha_chassis); + } + + sbrec_port_binding_set_ha_chassis_group(pb, sb_ha_grp); + return chassis_group_name; +} + /* This functions translates the gw chassis on the nb database * to HA chassis group in the sb database entries. */ @@ -3130,14 +3354,29 @@ ovn_port_update_sbrec(struct ovsdb_idl_txn *ovnsb_txn, "ignoring the latter.", op->nbrp->name); } - /* HA Chassis group is set. Ignore 'gateway_chassis'. */ - sync_ha_chassis_group_for_sbpb(ovnsb_txn, - sbrec_chassis_by_name, - sbrec_ha_chassis_grp_by_name, - op->nbrp->ha_chassis_group, - op->sb); - sset_add(active_ha_chassis_grps, - op->nbrp->ha_chassis_group->name); + if (op->primary_port && op->primary_port->is_active_active) { + + /* Generate new HA Chassis group just bound to one node. */ + char *ha_chassis_group = + generate_ha_chassis_group_active_active(ovnsb_txn, + sbrec_chassis_by_name, + sbrec_ha_chassis_grp_by_name, + op->primary_port->aa_chassis_name, + op->sb); + sset_add(active_ha_chassis_grps, + ha_chassis_group); + free(ha_chassis_group); + } else { + + /* HA Chassis group is set. Ignore 'gateway_chassis'. */ + sync_ha_chassis_group_for_sbpb(ovnsb_txn, + sbrec_chassis_by_name, + sbrec_ha_chassis_grp_by_name, + op->nbrp->ha_chassis_group, + op->sb); + sset_add(active_ha_chassis_grps, + op->nbrp->ha_chassis_group->name); + } } else if (op->nbrp->n_gateway_chassis) { /* Legacy gateway_chassis support. * Create ha_chassis_group for the Northbound gateway_chassis @@ -4252,6 +4491,7 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn, const struct sbrec_mac_binding_table *sbrec_mac_binding_table, const struct sbrec_ha_chassis_group_table *sbrec_ha_chassis_group_table, const struct sbrec_route_table *sbrec_route_table, + struct ovsdb_idl_index *nbrec_lrp_by_name, struct ovsdb_idl_index *sbrec_chassis_by_name, struct ovsdb_idl_index *sbrec_chassis_by_hostname, struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name, @@ -4272,7 +4512,10 @@ build_ports(struct ovsdb_idl_txn *ovnsb_txn, /* Borrow ls_ports for joining NB and SB for both LSPs and LRPs. * We will split them later. */ struct hmap *ports = ls_ports; - join_logical_ports(sbrec_port_binding_table, ls_datapaths, lr_datapaths, + join_logical_ports(sbrec_port_binding_table, + nbrec_lrp_by_name, + sbrec_chassis_by_name, + ls_datapaths, lr_datapaths, ports, queue_id_bitmap, &tag_alloc_table, &sb_only, &nb_only, &both); @@ -12974,7 +13217,7 @@ build_lrouter_icmp_packet_toobig_admin_flows( " (ip6 && icmp6.type == 2 && icmp6.code == 0)) &&" " eth.dst == %s && !is_chassis_resident(%s) &&" " flags.tunnel_rx == 1", - op->nbrp->mac, op->cr_port->json_key); + ovn_port_get_mac(op), op->cr_port->json_key); ds_clear(actions); ds_put_format(actions, "outport <-> inport; inport = %s; next;", op->json_key); @@ -13017,7 +13260,7 @@ build_lswitch_icmp_packet_toobig_admin_flows( "((ip4 && icmp4.type == 3 && icmp4.code == 4) ||" " (ip6 && icmp6.type == 2 && icmp6.code == 0)) && " "eth.src == %s && outport == %s && flags.tunnel_rx == 1", - peer->nbrp->mac, op->json_key); + ovn_port_get_mac(peer), op->json_key); ovn_lflow_add(lflows, op->od, S_SWITCH_IN_CHECK_PORT_SEC, 120, ds_cstr(match), "outport <-> inport; next;", op->lflow_ref); @@ -13026,7 +13269,7 @@ build_lswitch_icmp_packet_toobig_admin_flows( "((ip4 && icmp4.type == 3 && icmp4.code == 4) ||" " (ip6 && icmp6.type == 2 && icmp6.code == 0)) && " "eth.dst == %s && flags.tunnel_rx == 1", - peer->nbrp->mac); + ovn_port_get_mac(peer)); ds_clear(actions); ds_put_format(actions, "outport <-> inport; next(pipeline=ingress,table=%d);", @@ -19055,6 +19298,7 @@ ovnnb_db_run(struct northd_input *input_data, input_data->sbrec_mac_binding_table, input_data->sbrec_ha_chassis_group_table, input_data->sbrec_route_table, + input_data->nbrec_lrp_by_name, input_data->sbrec_chassis_by_name, input_data->sbrec_chassis_by_hostname, input_data->sbrec_ha_chassis_grp_by_name, diff --git a/northd/northd.h b/northd/northd.h index 75ad86973..12fe83440 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -66,6 +66,7 @@ struct northd_input { const struct chassis_features *features; /* Indexes */ + struct ovsdb_idl_index *nbrec_lrp_by_name; struct ovsdb_idl_index *sbrec_chassis_by_name; struct ovsdb_idl_index *sbrec_chassis_by_hostname; struct ovsdb_idl_index *sbrec_ha_chassis_grp_by_name; @@ -664,6 +665,15 @@ struct ovn_port { /* Only used for the router type LSP whose peer is l3dgw_port */ bool enable_router_port_acl; + /* Used for active-active port bindings to store the data they where + * generated from */ + bool is_active_active; + char *aa_chassis_name; + size_t aa_chassis_index; + /* The following value is only set on the lrp side of an + * active-active port binding */ + char *aa_mac; + /* Reference of lflows generated for this ovn_port. * * This data is initialized and destroyed by the en_northd node, but