Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2217965/?format=api
{ "id": 2217965, "url": "http://patchwork.ozlabs.org/api/patches/2217965/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ovn/patch/20260331071519.310710-1-dceara@redhat.com/", "project": { "id": 68, "url": "http://patchwork.ozlabs.org/api/projects/68/?format=api", "name": "Open Virtual Network development", "link_name": "ovn", "list_id": "ovs-dev.openvswitch.org", "list_email": "ovs-dev@openvswitch.org", "web_url": "http://openvswitch.org/", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260331071519.310710-1-dceara@redhat.com>", "list_archive_url": null, "date": "2026-03-31T07:15:19", "name": "[ovs-dev,v2] docs: Add dynamic routing integration architecture documentation.", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "87be3dc56784fb117cb87f45c4005c966210d703", "submitter": { "id": 76591, "url": "http://patchwork.ozlabs.org/api/people/76591/?format=api", "name": "Dumitru Ceara", "email": "dceara@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/ovn/patch/20260331071519.310710-1-dceara@redhat.com/mbox/", "series": [ { "id": 498131, "url": "http://patchwork.ozlabs.org/api/series/498131/?format=api", "web_url": "http://patchwork.ozlabs.org/project/ovn/list/?series=498131", "date": "2026-03-31T07:15:19", "name": "[ovs-dev,v2] docs: Add dynamic routing integration architecture documentation.", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/498131/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2217965/comments/", "check": "success", "checks": "http://patchwork.ozlabs.org/api/patches/2217965/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<ovs-dev-bounces@openvswitch.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "ovs-dev@openvswitch.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "ovs-dev@lists.linuxfoundation.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=I4c5hxJd;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)", "smtp2.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=I4c5hxJd", "smtp2.osuosl.org; dmarc=pass (p=quarantine dis=none)\n header.from=redhat.com" ], "Received": [ "from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4flKCD1h7nz1yGH\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 31 Mar 2026 18:15:36 +1100 (AEDT)", "from localhost (localhost [127.0.0.1])\n\tby smtp2.osuosl.org (Postfix) with ESMTP id BDE5C40642;\n\tTue, 31 Mar 2026 07:15:34 +0000 (UTC)", "from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id fXPyuq4swzKK; Tue, 31 Mar 2026 07:15:33 +0000 (UTC)", "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp2.osuosl.org (Postfix) with ESMTPS id 061E44005B;\n\tTue, 31 Mar 2026 07:15:33 +0000 (UTC)", "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id EC469C054A;\n\tTue, 31 Mar 2026 07:15:32 +0000 (UTC)", "from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 31D9EC0549\n for <ovs-dev@openvswitch.org>; Tue, 31 Mar 2026 07:15:32 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n by smtp2.osuosl.org (Postfix) with ESMTP id 17F0A4005B\n for <ovs-dev@openvswitch.org>; Tue, 31 Mar 2026 07:15:32 +0000 (UTC)", "from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id bmAEG0LIIIU8 for <ovs-dev@openvswitch.org>;\n Tue, 31 Mar 2026 07:15:30 +0000 (UTC)", "from us-smtp-delivery-124.mimecast.com\n (us-smtp-delivery-124.mimecast.com [170.10.133.124])\n by smtp2.osuosl.org (Postfix) with ESMTPS id 1075A400D2\n for <ovs-dev@openvswitch.org>; Tue, 31 Mar 2026 07:15:29 +0000 (UTC)", "from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com\n (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by\n relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n cipher=TLS_AES_256_GCM_SHA384) id us-mta-226-bdO1NidoOQKEaMPXYWecHg-1; Tue,\n 31 Mar 2026 03:15:25 -0400", "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS\n id AB2C4195608A\n for <ovs-dev@openvswitch.org>; Tue, 31 Mar 2026 07:15:24 +0000 (UTC)", "from cecil-rh.redhat.com (unknown [10.44.32.199])\n by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP\n id E39DD1954102; Tue, 31 Mar 2026 07:15:22 +0000 (UTC)" ], "X-Virus-Scanned": [ "amavis at osuosl.org", "amavis at osuosl.org" ], "X-Comment": "SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ", "DKIM-Filter": [ "OpenDKIM Filter v2.11.0 smtp2.osuosl.org 061E44005B", "OpenDKIM Filter v2.11.0 smtp2.osuosl.org 1075A400D2" ], "Received-SPF": "Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124;\n helo=us-smtp-delivery-124.mimecast.com; envelope-from=dceara@redhat.com;\n receiver=<UNKNOWN>", "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp2.osuosl.org 1075A400D2", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1774941328;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding;\n bh=4WzCKPbCzxUKVyZA/z3t3SW3ZHByOpPL4ZL5NFWmjfw=;\n b=I4c5hxJdzu6jLvAvvfpUcC2X/P3SvqDe0AECuvajuBLMXHrWmYBTSOhW+sOubUZd5gUSNX\n ui4N6l0BmkGNUFNDGbYQqVSWWPvH0xk9Bq7vwu+PGNEbhBeSKtg0uDqm+FxPKS0yAOHNqt\n 5hNmEXEX59u+FQxXsueeVm7lWHHV//A=", "X-MC-Unique": "bdO1NidoOQKEaMPXYWecHg-1", "X-Mimecast-MFC-AGG-ID": "bdO1NidoOQKEaMPXYWecHg_1774941324", "To": "ovs-dev@openvswitch.org", "Date": "Tue, 31 Mar 2026 09:15:19 +0200", "Message-ID": "<20260331071519.310710-1-dceara@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "dEQiRKVtXc1tP_vdYagofUDncDgfeFhVUmyZo4dmHSY_1774941324", "X-Mimecast-Originator": "redhat.com", "Subject": "[ovs-dev] [PATCH ovn v2] docs: Add dynamic routing integration\n architecture documentation.", "X-BeenThere": "ovs-dev@openvswitch.org", "X-Mailman-Version": "2.1.30", "Precedence": "list", "List-Id": "<ovs-dev.openvswitch.org>", "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>", "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>", "List-Post": "<mailto:ovs-dev@openvswitch.org>", "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>", "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>", "From": "Dumitru Ceara via dev <ovs-dev@openvswitch.org>", "Reply-To": "Dumitru Ceara <dceara@redhat.com>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "ovs-dev-bounces@openvswitch.org", "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>" }, "content": "Add a new Documentation/topics/dynamic-routing/ section covering:\n- OVN's integration model with external routing daemons\n- Architecture diagrams for IP route exchange and EVPN\n- Deployment scenario diagrams for both IP routing and EVPN\n- IP route advertisement and learning mechanisms\n- VRF management\n- EVPN remote VTEP discovery, FDB/neighbor learning, and\n Advertised MAC Binding\n\nReported-at: https://redhat.atlassian.net/browse/FDP-3118\nAssisted-by: Claude, with model: claude-opus-4-6\nSigned-off-by: Dumitru Ceara <dceara@redhat.com>\n---\nV2:\n- addressed Ales' comments:\n - added Advertised_Route column descriptions\n - fixed up nit\n---\n Documentation/automake.mk | 2 +\n .../topics/dynamic-routing/architecture.rst | 630 ++++++++++++++++++\n .../topics/dynamic-routing/index.rst | 31 +\n Documentation/topics/index.rst | 1 +\n 4 files changed, 664 insertions(+)\n create mode 100644 Documentation/topics/dynamic-routing/architecture.rst\n create mode 100644 Documentation/topics/dynamic-routing/index.rst", "diff": "diff --git a/Documentation/automake.mk b/Documentation/automake.mk\nindex 1bc9478bf3..7bd65cbe9f 100644\n--- a/Documentation/automake.mk\n+++ b/Documentation/automake.mk\n@@ -27,6 +27,8 @@ DOC_SOURCE = \\\n \tDocumentation/topics/testing.rst \\\n \tDocumentation/topics/test-development.rst \\\n \tDocumentation/topics/high-availability.rst \\\n+\tDocumentation/topics/dynamic-routing/architecture.rst \\\n+\tDocumentation/topics/dynamic-routing/index.rst \\\n \tDocumentation/topics/incremental-processing/datapath-sync-graph.png \\\n \tDocumentation/topics/incremental-processing/evpn-arp-graph.png \\\n \tDocumentation/topics/incremental-processing/ic-graph.png \\\ndiff --git a/Documentation/topics/dynamic-routing/architecture.rst b/Documentation/topics/dynamic-routing/architecture.rst\nnew file mode 100644\nindex 0000000000..e7c968330f\n--- /dev/null\n+++ b/Documentation/topics/dynamic-routing/architecture.rst\n@@ -0,0 +1,630 @@\n+..\n+ Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n+ not use this file except in compliance with the License. You may obtain\n+ a copy of the License at\n+\n+ http://www.apache.org/licenses/LICENSE-2.0\n+\n+ Unless required by applicable law or agreed to in writing, software\n+ distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+ License for the specific language governing permissions and limitations\n+ under the License.\n+\n+ Convention for heading levels in OVN documentation:\n+\n+ ======= Heading 0 (reserved for the title in a document)\n+ ------- Heading 1\n+ ~~~~~~~ Heading 2\n+ +++++++ Heading 3\n+ ''''''' Heading 4\n+\n+ Avoid deeper levels because they do not render well.\n+\n+===========================\n+Dynamic Routing Integration\n+===========================\n+\n+Introduction\n+------------\n+\n+OVN integrates with dynamic routing protocols to enable automatic exchange\n+of routing information between OVN logical networks and the physical\n+network fabric. A key design principle is that OVN does not implement any\n+routing protocol stack itself. Instead, OVN relies on external routing\n+protocol daemons --- such as FRR (Free Range Routing) --- running on each\n+hypervisor (chassis) to handle the protocol control plane. OVN is not\n+intended to ever implement routing protocols (BGP, OSPF, or others)\n+directly.\n+\n+The routing protocol control plane lives entirely outside OVN. OVN\n+interacts with these external daemons indirectly through the Linux kernel\n+networking stack. Specifically, ``ovn-controller`` exchanges routes with\n+the kernel via Netlink and monitors network interfaces for neighbor\n+information. This separation of concerns keeps OVN focused on logical\n+network management while leveraging mature, feature-rich routing\n+implementations for protocol handling.\n+\n+OVN supports two main categories of dynamic routing integration:\n+\n+- **IP Route Exchange** --- Learning routes from and advertising routes to\n+ external routing peers through VRF routing tables on each chassis.\n+\n+- **EVPN (Ethernet VPN)** --- Extending Layer 2 and Layer 3 connectivity\n+ across the fabric by learning remote VTEPs, MAC addresses, and IP\n+ neighbors through EVPN-capable routing daemons.\n+\n+Architecture Overview\n+---------------------\n+\n+IP Route Exchange\n+~~~~~~~~~~~~~~~~~\n+\n+The following diagram shows the interaction between components involved in\n+dynamic IP route exchange. The routing protocol daemon (e.g., FRR) and\n+``ovn-controller`` both operate on each chassis. They communicate\n+indirectly through the kernel routing table in a VRF associated with each\n+logical router that has dynamic routing enabled.\n+\n+::\n+\n+ Chassis (Hypervisor)\n+ +------------------------------------------------------------------+\n+ | |\n+ | +---------------------+ +-----------------------------+ |\n+ | | Routing Daemon | | ovn-controller | |\n+ | | (e.g., FRR) | | | |\n+ | | | | | |\n+ | | Speaks BGP, OSPF, | | Monitors VRF tables via | |\n+ | | etc. with external | | Netlink for learned routes | |\n+ | | peers | | | |\n+ | | | | Installs advertised routes | |\n+ | | Installs learned | | into VRF tables via | |\n+ | | routes into VRF | | Netlink (RTPROT_OVN) | |\n+ | | tables | | | |\n+ | | | | | |\n+ | +----------+----------+ +-----+--+--------------------+ |\n+ | | | | |\n+ | | Netlink | | Netlink |\n+ | | (install routes) | | (read/write routes) |\n+ | | | | |\n+ | +----------v-------------------------v--v--------------------+ |\n+ | | Linux Kernel - VRF Routing Table | |\n+ | | (dynamic-routing-vrf-id / datapath tunnel key) | |\n+ | +------------------------------------------------------------+ |\n+ | |\n+ +------------------------------------------------------------------+\n+ |\n+ |\n+ +------------------------------------------------------------------+\n+ | OVN Southbound Database |\n+ | |\n+ | +-------------------------+ +------------------------------+ |\n+ | | Learned_Route | | Advertised_Route | |\n+ | | | | | |\n+ | | Populated by | | Populated by ovn-northd | |\n+ | | ovn-controller with | | based on LR config: | |\n+ | | routes learned from | | - connected routes | |\n+ | | the VRF routing table | | - connected-as-host routes | |\n+ | | (dynamic protocols | | - static routes | |\n+ | | only, not RTPROT_OVN) | | - NAT external IPs | |\n+ | | | | - Load Balancer VIPs | |\n+ | +-------------------------+ +------------------------------+ |\n+ | |\n+ +------------------------------------------------------------------+\n+ |\n+ |\n+ +------------------------------------------------------------------+\n+ | ovn-northd |\n+ | |\n+ | Reads Learned_Route records and generates logical flows in the |\n+ | IP routing stage of the logical router pipeline. |\n+ | |\n+ | Reads NB Logical_Router configuration and populates |\n+ | Advertised_Route records in the SB database. |\n+ | |\n+ +------------------------------------------------------------------+\n+\n+EVPN (Ethernet VPN)\n+~~~~~~~~~~~~~~~~~~~\n+\n+EVPN integration follows a different pattern from IP route exchange. An\n+important distinction is that dynamically learned EVPN information (remote\n+VTEPs, MAC addresses, IP neighbors) is **not** stored in the OVN\n+Southbound database. Instead, each ``ovn-controller`` instance processes\n+this information locally, in memory, based on what it learns through\n+Netlink from the kernel.\n+\n+::\n+\n+ Chassis (Hypervisor)\n+ +------------------------------------------------------------------+\n+ | |\n+ | +---------------------+ +-----------------------------+ |\n+ | | Routing Daemon | | ovn-controller | |\n+ | | (e.g., FRR) | | | |\n+ | | | | Monitors bridge/vxlan/ | |\n+ | | Speaks BGP EVPN | | advertise interfaces for | |\n+ | | with peers | | EVPN-enabled LSes | |\n+ | | | | | |\n+ | | Populates bridge | | Learns: | |\n+ | | FDB, ARP/ND neigh | | - Remote VTEPs (per VNI) | |\n+ | | entries, and VXLAN | | - FDB entries (MAC addrs) | |\n+ | | FDB via kernel | | - ARP/ND entries (IPs) | |\n+ | | | | | |\n+ | +----------+----------+ | Creates OVS VXLAN tunnels | |\n+ | | | (flow-based) in br-int | |\n+ | | Netlink | | |\n+ | | (FDB/neighbor | Installs bridge FDB and | |\n+ | | entries) | ARP/ND entries for local | |\n+ | | | workloads (advertise) | |\n+ | +----------v-----------+ | | |\n+ | | Linux Kernel | +------+--+-------------------+ |\n+ | | |<-- Netlink --+ | |\n+ | | - Bridge FDB table | (monitor) | OVS VXLAN tunnels |\n+ | | - ARP/ND neigh table | | |\n+ | | - VXLAN interfaces | +---------v------------------+ |\n+ | +----------------------+ | OVS br-int | |\n+ | | - VXLAN tunnel ports | |\n+ | | - OpenFlow rules for | |\n+ | | encap/decap per VNI | |\n+ | +----------------------------+ |\n+ | |\n+ +------------------------------------------------------------------+\n+\n+IP Route Exchange\n+-----------------\n+\n+Deployment Scenario\n+~~~~~~~~~~~~~~~~~~~\n+\n+The following diagram illustrates a typical deployment where a logical\n+router has dynamic routing enabled. The router is connected to multiple\n+logical switches hosting workloads, has NAT rules, load balancers, and\n+static routes configured. Through dynamic routing, OVN advertises\n+selected prefixes to the external fabric and learns external routes from\n+routing peers.\n+\n+::\n+\n+ External Network / Fabric\n+ |\n+ | BGP/OSPF peering\n+ |\n+ +------------------+-------------------+\n+ | Routing Daemon (FRR) |\n+ | on Chassis |\n+ +------------------+-------------------+\n+ |\n+ VRF table\n+ (Netlink exchange)\n+ |\n+ +------------------+-----------------------------------------------+\n+ | ovn-controller |\n+ | |\n+ | Advertises routes Learns routes from VRF |\n+ | into VRF table and writes to SB Learned_Route |\n+ +------------------+-----------------------------------------------+\n+ |\n+ OVN SB Database\n+ (Advertised_Route / Learned_Route)\n+ |\n+ +------------------+------------------------------------------------+\n+ | ovn-northd |\n+ +-------------------------------------------------------------------+\n+ | |\n+ | Logical Router (LR1) |\n+ | dynamic-routing = true |\n+ | dynamic-routing-redistribute = |\n+ | connected,static,nat,lb |\n+ | |\n+ | Advertised prefixes: Learned routes: |\n+ | |\n+ | connected: From external peers: |\n+ | 10.0.1.0/24 (from LS1) 203.0.113.0/24 |\n+ | 10.0.2.0/24 (from LS2) via 192.168.1.1 |\n+ | 10.0.3.0/24 (from LS3) 198.51.100.0/24 |\n+ | via 192.168.1.2 |\n+ | static: |\n+ | 172.16.0.0/16 |\n+ | via 10.0.1.1 |\n+ | |\n+ | nat (external IPs): |\n+ | 192.168.50.10/32 (DNAT+SNAT) |\n+ | 192.168.50.20/32 (SNAT) |\n+ | |\n+ | lb (VIPs): |\n+ | 192.168.60.100/32 (LB VIP) |\n+ | |\n+ +--------+----------------+-----------------+-----------------------+\n+ | | |\n+ +--------+-------+ +------+--------+ +------+--------+\n+ | Logical Switch | | Logical Switch| | Logical Switch|\n+ | LS1 | | LS2 | | LS3 |\n+ | 10.0.1.0/24 | | 10.0.2.0/24 | | 10.0.3.0/24 |\n+ | | | | | |\n+ | VM1 VM2 VM3 | | VM4 VM5 | | VM6 |\n+ +----------------+ +---------------+ +---------------+\n+\n+In this scenario ``ovn-northd`` populates the SB ``Advertised_Route``\n+table with entries for each prefix type selected by\n+``dynamic-routing-redistribute``. On each chassis, ``ovn-controller``\n+reads these records and installs the corresponding routes (as blackhole\n+by default, or with a specific nexthop if\n+``dynamic-routing-v4/v6-prefix-nexthop`` is set) into the VRF routing\n+table associated with the logical router. The routing daemon picks up\n+these routes and advertises them to external peers.\n+\n+Conversely, when the routing daemon learns routes from external peers, it\n+installs them into the same VRF table. ``ovn-controller`` detects these\n+new routes via Netlink (filtering out routes it installed itself using the\n+``RTPROT_OVN`` protocol marker) and creates corresponding\n+``Learned_Route`` records in the SB database. ``ovn-northd`` then\n+generates logical flows in the IP routing pipeline stage to implement\n+forwarding for these learned routes.\n+\n+IP Route Advertisement\n+----------------------\n+\n+When a logical router has ``dynamic-routing`` set to ``true``, ``ovn-northd``\n+examines the router configuration and populates the ``Advertised_Route``\n+table in the OVN Southbound database. The types of routes that are\n+advertised depend on the ``dynamic-routing-redistribute`` option, which\n+accepts a comma-separated list of the following values:\n+\n+- ``connected`` --- Subnet prefixes directly connected to the logical\n+ router ports (e.g., 10.0.1.0/24 for a port with address 10.0.1.1/24).\n+\n+- ``connected-as-host`` --- Individual host routes (/32 for IPv4, /128\n+ for IPv6) for each IP address on logical switch ports, router ports,\n+ and NAT entries associated with this router.\n+\n+- ``static`` --- All ``Logical_Router_Static_Route`` entries configured on\n+ the router.\n+\n+- ``nat`` --- The external IP of each NAT rule on this router and\n+ neighboring routers that share a distributed gateway port.\n+\n+- ``lb`` --- The VIP address of each load balancer associated with this\n+ router and neighboring routers.\n+\n+These options can also be set per logical router port, overriding the\n+router-level setting for routes associated with that specific port.\n+\n+Each ``Advertised_Route`` record includes:\n+\n+- ``datapath`` --- The logical router datapath this route belongs to.\n+- ``logical_port`` --- The port binding this route is associated with.\n+- ``ip_prefix`` --- The IP prefix of this route (e.g., 192.168.100.0/24).\n+- ``tracked_port`` --- Tracks the port OVN will forward packets for this\n+ destination to. An announcing chassis can use this to check if the\n+ destination is local and adjust route priorities accordingly.\n+\n+Route Installation on the Chassis\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+On each chassis, ``ovn-controller`` reads the ``Advertised_Route``\n+records from the Southbound database and installs corresponding routes\n+into the Linux VRF routing table associated with the logical router.\n+\n+Routes are installed via Netlink with the ``RTPROT_OVN`` protocol marker\n+so that ``ovn-controller`` can distinguish OVN-managed routes from routes\n+installed by other sources. By default, advertised routes are installed\n+as **blackhole** routes (to attract traffic into OVN for processing). If\n+``dynamic-routing-v4-prefix-nexthop`` or ``dynamic-routing-v6-prefix-nexthop``\n+is set on the logical router, routes are installed with the specified\n+nexthop address instead.\n+\n+Route Priority\n+~~~~~~~~~~~~~~\n+\n+When the ``tracked_port`` field is set on an ``Advertised_Route`` record,\n+``ovn-controller`` adjusts the route metric based on whether the tracked\n+port is locally bound on this chassis. Routes for locally bound ports\n+receive a higher priority (lower metric value), which causes the routing\n+daemon to prefer the chassis that actually hosts the workload. This\n+mechanism is particularly useful for host routes generated by the\n+``connected-as-host`` redistribution mode.\n+\n+The ``dynamic-routing-redistribute-local-only`` option further refines\n+this behavior: when set to ``true``, ``ovn-controller`` only installs\n+routes on the chassis where the ``tracked_port`` is locally bound,\n+preventing other chassis from advertising the route at all.\n+\n+IP Route Learning\n+-----------------\n+\n+``ovn-controller`` monitors the VRF routing tables associated with\n+dynamic-routing-enabled logical routers for routes installed by external\n+routing daemons. This monitoring is performed via Netlink route\n+notifications (``RTNLGRP_IPV4_ROUTE`` and ``RTNLGRP_IPV6_ROUTE``).\n+\n+When a route change is detected in a watched VRF table,\n+``ovn-controller`` dumps the table contents and processes each route.\n+The following filtering rules apply:\n+\n+- Routes with protocol ``RTPROT_OVN`` are **skipped** because they were\n+ installed by ``ovn-controller`` itself (advertised routes).\n+\n+- Routes with protocol ``RTPROT_STATIC`` or lower are **skipped** because\n+ they are not dynamic routing protocol routes.\n+\n+- Only routes installed by dynamic routing protocols (protocol value\n+ greater than ``RTPROT_STATIC``) are considered for learning.\n+\n+- Link-local prefixes are **skipped**.\n+\n+For each qualifying route, ``ovn-controller`` creates a ``Learned_Route``\n+record in the Southbound database containing the datapath, logical port,\n+IP prefix, and nexthop.\n+\n+Flow Generation by ovn-northd\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+``ovn-northd`` reads the ``Learned_Route`` table and generates logical\n+flows in the IP routing stage of the logical router processing pipeline.\n+These flows implement longest-prefix-match forwarding for the learned\n+routes. Learned routes receive a lower priority than static routes,\n+ensuring that explicitly configured routes always take precedence.\n+\n+Disabling Route Learning\n+~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Route learning can be disabled on a per-router or per-port basis by\n+setting the ``dynamic-routing-no-learning`` option to ``true``. When\n+this option is enabled, ``ovn-controller`` does not create\n+``Learned_Route`` records for the affected router or port and removes any\n+previously learned routes.\n+\n+VRF Management\n+--------------\n+\n+Each logical router with dynamic routing enabled is associated with a\n+Linux VRF (Virtual Routing and Forwarding) instance on each chassis.\n+The VRF provides an isolated routing table where ``ovn-controller`` and\n+the external routing daemon exchange routes.\n+\n+VRF Table ID\n+~~~~~~~~~~~~\n+\n+The VRF routing table ID is determined by one of the following, in order\n+of precedence:\n+\n+1. The ``dynamic-routing-vrf-id`` option on the logical router, if set to\n+ a valid integer (1-4294967295, excluding reserved table IDs such as\n+ ``RT_TABLE_MAIN`` and ``RT_TABLE_LOCAL``).\n+\n+2. The tunnel key of the logical router datapath, used as a fallback\n+ when ``dynamic-routing-vrf-id`` is not configured.\n+\n+VRF Naming\n+~~~~~~~~~~\n+\n+The VRF interface name is determined by the ``dynamic-routing-vrf-name``\n+option on the logical router. If not set, the name defaults to\n+``ovnvrf`` followed by the VRF table ID (e.g., ``ovnvrf42``). The\n+name must be a valid Linux network interface name.\n+\n+VRF Lifecycle\n+~~~~~~~~~~~~~\n+\n+When the ``dynamic-routing-maintain-vrf`` option is set to ``true`` on\n+a logical router port, ``ovn-controller`` creates and manages the VRF\n+interface on the chassis where the port is bound. This includes:\n+\n+- Creating the VRF interface via a ``RTM_NEWLINK`` Netlink message with\n+ ``IFLA_LINKINFO`` kind ``vrf`` and the appropriate ``IFLA_VRF_TABLE``\n+ value.\n+\n+- Deleting the VRF interface when dynamic routing is disabled or the\n+ port is unbound.\n+\n+If ``dynamic-routing-maintain-vrf`` is ``false`` (the default), the VRF\n+is expected to already exist on the chassis, managed by external tooling\n+or configuration management.\n+\n+EVPN (Ethernet VPN) Integration\n+-------------------------------\n+\n+EVPN extends OVN logical switches across the physical fabric using VXLAN\n+encapsulation and BGP EVPN for control-plane signaling. EVPN is enabled\n+on a logical switch by setting the ``dynamic-routing-vni`` option to a\n+valid VNI (VXLAN Network Identifier) value (0--16777215).\n+\n+When EVPN is enabled on a logical switch, the following interface names\n+must also be configured:\n+\n+- ``dynamic-routing-bridge-ifname`` --- The Linux bridge interface\n+ associated with the EVPN domain.\n+\n+- ``dynamic-routing-vxlan-ifname`` --- One or more VXLAN device interface\n+ names used for EVPN integration.\n+\n+- ``dynamic-routing-advertise-ifname`` --- The interface used for\n+ advertising local MAC and IP bindings to the routing daemon.\n+\n+Deployment Scenario\n+~~~~~~~~~~~~~~~~~~~\n+\n+The following diagram illustrates a deployment with an EVPN-enabled\n+logical switch. The logical switch is assigned a VNI (VXLAN Network\n+Identifier) and is associated with bridge, VXLAN, and advertise\n+interfaces on each chassis. Through EVPN, OVN discovers remote VTEPs and\n+learns remote MAC and IP addresses without storing this information in the\n+Southbound database.\n+\n+::\n+\n+ Chassis A Chassis B\n+ +-------------------------------+ +-------------------------------+\n+ | | | |\n+ | ovn-controller | | ovn-controller |\n+ | | | |\n+ | Logical Switch (LS-EVPN) | | Logical Switch (LS-EVPN) |\n+ | dynamic-routing-vni = 1000 | | dynamic-routing-vni = 1000 |\n+ | dynamic-routing-redistribute | | dynamic-routing-redistribute |\n+ | = fdb,ip | | = fdb,ip |\n+ | | | |\n+ | Local workloads: | | Local workloads: |\n+ | VM-A1: MAC-A1, 10.0.1.10 | | VM-B1: MAC-B1, 10.0.1.20 |\n+ | VM-A2: MAC-A2, 10.0.1.11 | | VM-B2: MAC-B2, 10.0.1.21 |\n+ | | | |\n+ | Interfaces configured: | | Interfaces configured: |\n+ | bridge-ifname: br-evpn | | bridge-ifname: br-evpn |\n+ | vxlan-ifname: vxlan1000 | | vxlan-ifname: vxlan1000 |\n+ | advertise-ifname: adv-evpn | | advertise-ifname: adv-evpn |\n+ | | | |\n+ +-------+-----------+-----------+ +-----------+-----------+-------+\n+ | | | |\n+ | | | |\n+ +-------v-----------v-----------+ +-----------v-----------v-------+\n+ | Linux Kernel | | Linux Kernel |\n+ | | | |\n+ | br-evpn (bridge) | | br-evpn (bridge) |\n+ | vxlan1000 (VXLAN VNI 1000) | | vxlan1000 (VXLAN VNI 1000) |\n+ | adv-evpn (advertise device) | | adv-evpn (advertise device) |\n+ | | | |\n+ | FDB: MAC-A1, MAC-A2 (local) | | FDB: MAC-B1, MAC-B2 (local) |\n+ | Neigh: 10.0.1.10, .11 | | Neigh: 10.0.1.20, .21 |\n+ | | | |\n+ +-------+-----------------------+ +-----------------------+-------+\n+ | |\n+ +-------v-----------------------+ +-----------------------v-------+\n+ | FRR (BGP EVPN) | | FRR (BGP EVPN) |\n+ | | | |\n+ | Reads local FDB/neigh | | Reads local FDB/neigh |\n+ | entries and advertises | | entries and advertises |\n+ | Type-2 (MAC+IP) routes | | Type-2 (MAC+IP) routes |\n+ | to peers | | to peers |\n+ | | | |\n+ | Learns remote entries | | Learns remote entries |\n+ | from peers and installs | | from peers and installs |\n+ | them into kernel FDB/neigh | | them into kernel FDB/neigh |\n+ | | | |\n+ +-------+-----------------------+ +-----------------------+-------+\n+ | |\n+ | BGP EVPN peering |\n+ +------------------------------------------------------+\n+\n+On Chassis A, ``ovn-controller`` installs static bridge FDB entries and\n+ARP/ND neighbor entries for local workloads (VM-A1, VM-A2) into the\n+kernel via Netlink on the advertise interface. FRR reads these entries\n+and advertises them as EVPN Type-2 routes to its peers.\n+\n+When FRR on Chassis A learns remote entries from Chassis B (MAC-B1,\n+MAC-B2, and their IPs), it installs them into the kernel bridge FDB and\n+neighbor tables. ``ovn-controller`` on Chassis A monitors the VXLAN and\n+bridge interfaces via Netlink to discover:\n+\n+- Remote VTEPs: the tunnel endpoints on Chassis B for VNI 1000.\n+- Remote MACs: FDB entries for MAC-B1 and MAC-B2.\n+- Remote IPs: ARP/ND entries for 10.0.1.20 and 10.0.1.21.\n+\n+``ovn-controller`` creates one flow-based OVS VXLAN tunnel port in\n+``br-int`` for each configured EVPN VXLAN port and installs OpenFlow\n+rules to encapsulate traffic destined for remote MACs/IPs using the\n+appropriate VNI and VTEP destination.\n+\n+Remote VTEP Discovery\n+~~~~~~~~~~~~~~~~~~~~~\n+\n+``ovn-controller`` monitors the VXLAN interfaces configured for each\n+EVPN-enabled logical switch via Netlink neighbor table notifications.\n+When the routing daemon (e.g., FRR) learns about remote VTEPs through\n+BGP EVPN peering, it installs neighbor entries in the kernel for the\n+VXLAN device. ``ovn-controller`` detects these entries and extracts the\n+remote VTEP IP address, destination port, and VNI.\n+\n+``ovn-controller`` creates one flow-based OVS VXLAN tunnel port in\n+``br-int`` for each configured EVPN VXLAN port (configured via\n+``ovn-evpn-vxlan-ports`` in the ``Open_vSwitch`` table).\n+\n+For each discovered remote VTEP, ``ovn-controller``:\n+\n+1. Allocates a tunnel key for the binding.\n+\n+2. Installs OpenFlow rules to encapsulate outbound traffic with the\n+ correct VNI and VTEP destination, and to decapsulate inbound traffic\n+ from the remote VTEP.\n+\n+3. Creates multicast groups per VNI for BUM (Broadcast, Unknown unicast,\n+ Multicast) traffic flooding to all remote VTEPs in the same EVPN\n+ domain.\n+\n+FDB and Neighbor Learning\n+~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+In addition to remote VTEP discovery, ``ovn-controller`` monitors the\n+bridge and VXLAN interfaces for:\n+\n+- **FDB (Forwarding Database) entries** --- MAC addresses learned\n+ through EVPN Type-2 routes, indicating which remote VTEP a given MAC\n+ address is reachable through.\n+\n+- **ARP/ND neighbor entries** --- IP-to-MAC bindings learned through\n+ EVPN Type-2 MAC+IP routes, which ``ovn-controller`` injects into the\n+ adjacent logical router pipeline for L3 forwarding.\n+\n+The ``dynamic-routing-fdb-prefer-local`` option controls the lookup\n+order for FDB entries: when set to ``true``, OVN first checks the\n+Southbound FDB table (populated through normal OVN mechanisms) before\n+falling back to the locally learned EVPN FDB cache. By default, the\n+EVPN-learned entries take precedence.\n+\n+Similarly, the ``dynamic-routing-arp-prefer-local`` option controls the\n+lookup order for ARP/ND entries: when set to ``true``, the Southbound\n+``MAC_Binding`` table is checked before the EVPN-learned neighbor cache.\n+\n+Unlike IP route exchange, dynamically learned EVPN information\n+(remote VTEPs, FDB entries, and ARP/ND neighbors) is **not** stored\n+in the OVN Southbound database. Each ``ovn-controller`` instance\n+processes this information locally, in memory. This design avoids\n+the overhead of synchronizing high-volume, rapidly changing L2/L3\n+state through the centralized database.\n+\n+Local MAC and IP Advertisement\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+The ``dynamic-routing-redistribute`` option on EVPN-enabled logical\n+switches controls what local information ``ovn-controller`` advertises\n+to the routing daemon by installing static entries into the kernel:\n+\n+- ``fdb`` --- ``ovn-controller`` installs static bridge FDB entries for\n+ all local workloads (VIF ports, container ports, virtual ports,\n+ distributed gateway ports, and gateway router ports) on the advertise\n+ interface. The routing daemon reads these entries and advertises them\n+ as EVPN Type-2 MAC routes to its peers.\n+\n+- ``ip`` --- ``ovn-controller`` installs static ARP/ND neighbor entries\n+ for all local IP-to-MAC bindings (VIF ports and router ports) on the\n+ advertise interface. The routing daemon advertises these as EVPN\n+ Type-2 MAC+IP routes.\n+\n+Advertised MAC Binding\n+~~~~~~~~~~~~~~~~~~~~~~\n+\n+The ``Advertised_MAC_Binding`` table in the Southbound database is\n+populated by ``ovn-northd`` for EVPN-enabled logical switches. It\n+contains the IP and MAC address pairs that should be announced to the\n+external network fabric. Each record includes:\n+\n+- ``datapath`` --- The logical switch this binding belongs to.\n+- ``logical_port`` --- The port binding this entry is associated with.\n+- ``ip`` --- The IP address to announce.\n+- ``mac`` --- The MAC address to announce.\n+\n+``ovn-controller`` reads these records and installs the corresponding\n+static FDB and neighbor entries on the appropriate kernel interfaces,\n+making them available to the routing daemon for EVPN advertisement.\n+\n+EVPN Source IP Configuration\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+The ``ovn-evpn-local-ip`` option in the ``Open_vSwitch`` table\n+``external_ids`` configures the source IP addresses used for EVPN VXLAN\n+tunnels. The format supports per-VNI IP assignment:\n+\n+``vni0-IPv4,vni1-IPv4,vni1-IPv6,IPv4,IPv6``\n+\n+If no VNI-specific address is provided, the default IP address is used\n+for all VNIs.\ndiff --git a/Documentation/topics/dynamic-routing/index.rst b/Documentation/topics/dynamic-routing/index.rst\nnew file mode 100644\nindex 0000000000..eb61afb4a3\n--- /dev/null\n+++ b/Documentation/topics/dynamic-routing/index.rst\n@@ -0,0 +1,31 @@\n+..\n+ Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n+ not use this file except in compliance with the License. You may obtain\n+ a copy of the License at\n+\n+ http://www.apache.org/licenses/LICENSE-2.0\n+\n+ Unless required by applicable law or agreed to in writing, software\n+ distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n+ License for the specific language governing permissions and limitations\n+ under the License.\n+\n+ Convention for heading levels in OVN documentation:\n+\n+ ======= Heading 0 (reserved for the title in a document)\n+ ------- Heading 1\n+ ~~~~~~~ Heading 2\n+ +++++++ Heading 3\n+ ''''''' Heading 4\n+\n+ Avoid deeper levels because they do not render well.\n+\n+===============\n+Dynamic Routing\n+===============\n+\n+.. toctree::\n+ :maxdepth: 2\n+\n+ architecture\ndiff --git a/Documentation/topics/index.rst b/Documentation/topics/index.rst\nindex a5748445f7..e5ba92b7ba 100644\n--- a/Documentation/topics/index.rst\n+++ b/Documentation/topics/index.rst\n@@ -37,6 +37,7 @@ OVN\n :maxdepth: 2\n \n integration.rst\n+ dynamic-routing/index\n incremental-processing/index\n high-availability\n role-based-access-control\n", "prefixes": [ "ovs-dev", "v2" ] }