chore: initial ovn commit
diff --git a/roles/neutron/defaults/main.yml b/roles/neutron/defaults/main.yml
index c7d21b3..b82e0b6 100644
--- a/roles/neutron/defaults/main.yml
+++ b/roles/neutron/defaults/main.yml
@@ -19,6 +19,9 @@
 neutron_helm_release_namespace: openstack
 neutron_helm_values: {}
 
+# OVN support
+neutron_ovn_enabled: "{{ ovn_enabled | default(false) | bool }}"
+
 # List of networks to provision inside OpenStack
 neutron_networks: []
 
diff --git a/roles/neutron/tasks/main.yml b/roles/neutron/tasks/main.yml
index 18266f6..b1741a4 100644
--- a/roles/neutron/tasks/main.yml
+++ b/roles/neutron/tasks/main.yml
@@ -36,6 +36,15 @@
         name: "{{ neutron_helm_release_name }}"
         namespace: "{{ neutron_helm_release_namespace }}"
 
+- name: Generate Helm values
+  ansible.builtin.set_fact:
+    _neutron_helm_values: "{{ __neutron_helm_values }}"
+
+- name: Add OVN configuration
+  when: neutron_ovn_enabled | bool
+  ansible.builtin.set_fact:
+    _neutron_helm_values: "{{ _neutron_helm_values | combine(__neutron_ovn_helm_values, recursive=True) }}"
+
 - name: Deploy Helm chart
   run_once: true
   kubernetes.core.helm:
diff --git a/roles/neutron/vars/main.yml b/roles/neutron/vars/main.yml
index a4cd93f..5ce4997 100644
--- a/roles/neutron/vars/main.yml
+++ b/roles/neutron/vars/main.yml
@@ -12,7 +12,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-_neutron_helm_values:
+__neutron_helm_values:
   endpoints: "{{ openstack_helm_endpoints }}"
   images:
     tags: "{{ atmosphere_images | vexxhost.atmosphere.openstack_helm_image_tags('neutron') }}"
@@ -65,3 +65,56 @@
   manifests:
     ingress_server: false
     service_ingress_server: false
+
+__neutron_ovn_helm_values:
+  network:
+    backend:
+      # - openvswitch
+      - ovn
+  conf:
+    neutron:
+      DEFAULT:
+        service_plugins: qos,ovn-router,segments,trunk
+      ovn:
+        dns_servers: "{{ neutron_coredns_cluster_ip | default('10.96.0.20') }}"
+        enable_distributed_floating_ip: true
+        ovn_metadata_enabled: true
+        ovn_nb_connection: "{% for n in range(ovn_helm_values.get('pod', {}).get('replicas', {}).get('ovn_ovsdb_nb', 3)) %}tcp:ovn-ovsdb-nb-{{ n }}.{{ neutron_helm_release_namespace }}.svc.cluster.local:6643{% if not loop.last %},{% endif %}{% endfor %}"
+        ovn_sb_connection: "{% for n in range(ovn_helm_values.get('pod', {}).get('replicas', {}).get('ovn_ovsdb_sb', 3)) %}tcp:ovn-ovsdb-sb-{{ n }}.{{ neutron_helm_release_namespace }}.svc.cluster.local:6642{% if not loop.last %},{% endif %}{% endfor %}"
+    plugins:
+      ml2_conf:
+        ml2:
+          type_drivers: flat,vlan,vxlan,geneve
+          tenant_network_types: geneve
+        ml2_type_geneve:
+          vni_ranges: 1:65536
+          max_header_size: 38
+  manifests:
+    daemonset_dhcp_agent: false
+    daemonset_l3_agent: false
+    daemonset_metadata_agent: false
+    daemonset_ovn_metadata_agent: true
+    daemonset_ovs_agent: false
+
+  # conf:
+  #   plugins:
+  #     ml2_conf:
+  #       ml2:
+  #         extension_drivers: port_security
+  #         mechanism_drivers: ovn
+  #   ovn_metadata_agent:
+  #     DEFAULT:
+  #       nova_metadata_port: 8775
+  #       metadata_proxy_shared_secret: "{{ openstack_helm_endpoints['compute_metadata']['secret'] }}"
+  #       metadata_workers: 8
+  #       nova_metadata_host: __NOVA_METADATA_SERVICE_HOST__
+  #     cache:
+  #       enabled: true
+  #       backend: dogpile.cache.memcached
+  #     ovs:
+  #       ovsdb_connection: tcp:127.0.0.1:6640
+  #       ovsdb_timeout: 180
+  #     ovn:
+  #       ovn_metadata_enabled: true
+  #       ovn_nb_connection: tcp:__OVN_NB_DB_SERVICE_HOST__:__OVN_NB_DB_SERVICE_PORT__
+  #       ovn_sb_connection: tcp:__OVN_SB_DB_SERVICE_HOST__:__OVN_SB_DB_SERVICE_PORT__