@@ -1140,6 +1140,14 @@ def _output_opts_file(self):
11401140 file_utils .replace_file (name , '\n ' .join (options ))
11411141 return name
11421142
1143+ def _get_ovn_metadata_port_ip (self , subnet ):
1144+ m_ports = [port for port in self .network .ports if
1145+ self ._is_ovn_metadata_port (port , self .network .id )]
1146+ if m_ports :
1147+ for fixed_ip in m_ports [0 ].fixed_ips :
1148+ if fixed_ip .subnet_id == subnet .id :
1149+ return fixed_ip .ip_address
1150+
11431151 def _generate_opts_per_subnet (self ):
11441152 options = []
11451153 subnets_without_nameservers = set ()
@@ -1193,23 +1201,33 @@ def _generate_opts_per_subnet(self):
11931201 else :
11941202 host_routes .append ("%s,%s" % (hr .destination , hr .nexthop ))
11951203
1196- # Add host routes for isolated network segments
1197-
1198- if ((self .conf .force_metadata or
1199- (isolated_subnets [subnet .id ] and
1200- self .conf .enable_isolated_metadata )) and
1201- subnet .ip_version == 4 ):
1202- subnet_dhcp_ip = subnet_to_interface_ip .get (subnet .id )
1203- if subnet_dhcp_ip :
1204+ # Determine metadata port route
1205+ if subnet .ip_version == constants .IP_VERSION_4 :
1206+ metadata_route_ip = None
1207+ # NOTE: OVN metadata port IP is used in a case when the DHCP
1208+ # agent is deployed in the ML2/OVN enviroment where the native
1209+ # ovn-controller dhcp is disabled. The ovn metadata route
1210+ # takes precedence over native force_metadata and
1211+ # enable_isolated_metadata routes settings.
1212+ ovn_metadata_port_ip = self ._get_ovn_metadata_port_ip (subnet )
1213+ if ovn_metadata_port_ip :
1214+ metadata_route_ip = ovn_metadata_port_ip
1215+
1216+ elif (self .conf .force_metadata or
1217+ (isolated_subnets [subnet .id ] and
1218+ self .conf .enable_isolated_metadata )):
1219+ subnet_dhcp_ip = subnet_to_interface_ip .get (subnet .id )
1220+ if subnet_dhcp_ip :
1221+ metadata_route_ip = subnet_dhcp_ip
1222+
1223+ if not isolated_subnets [subnet .id ] and gateway :
1224+ metadata_route_ip = gateway
1225+
1226+ if metadata_route_ip :
12041227 host_routes .append (
1205- '%s,%s' % (constants .METADATA_CIDR , subnet_dhcp_ip )
1228+ '%s,%s' % (constants .METADATA_CIDR , metadata_route_ip )
12061229 )
1207- elif not isolated_subnets [subnet .id ] and gateway :
1208- host_routes .append (
1209- '%s,%s' % (constants .METADATA_CIDR , gateway )
1210- )
12111230
1212- if subnet .ip_version == 4 :
12131231 for s in self ._get_all_subnets (self .network ):
12141232 sub_segment_id = getattr (s , 'segment_id' , None )
12151233 if (s .ip_version == 4 and
@@ -1374,13 +1392,21 @@ def has_metadata_subnet(subnets):
13741392 return True
13751393 return False
13761394
1395+ @staticmethod
1396+ def _is_ovn_metadata_port (port , network_id ):
1397+ return (port .device_id == 'ovnmeta-' + network_id and
1398+ port .device_owner == constants .DEVICE_OWNER_DISTRIBUTED )
1399+
13771400 @classmethod
13781401 def should_enable_metadata (cls , conf , network ):
13791402 """Determine whether the metadata proxy is needed for a network
13801403
1381- This method returns True for truly isolated networks (ie: not attached
1382- to a router) when enable_isolated_metadata is True, or for all the
1383- networks when the force_metadata flags is True.
1404+ If the given network contains a ovn metadata port then this method
1405+ assumes that the ovn metadata service is in use and this metadata
1406+ service is not required, method returns False. For other cases this
1407+ method returns True for truly isolated networks (ie: not attached to a
1408+ router) when enable_isolated_metadata is True, or for all the networks
1409+ when the force_metadata flags is True.
13841410
13851411 This method also returns True when enable_metadata_network is True,
13861412 and the network passed as a parameter has a subnet in the link-local
@@ -1389,6 +1415,10 @@ def should_enable_metadata(cls, conf, network):
13891415 providing access to the metadata service via logical routers built
13901416 with 3rd party backends.
13911417 """
1418+ for port in network .ports :
1419+ if cls ._is_ovn_metadata_port (port , network .id ):
1420+ return False
1421+
13921422 all_subnets = cls ._get_all_subnets (network )
13931423 dhcp_subnets = [s for s in all_subnets if s .enable_dhcp ]
13941424 if not dhcp_subnets :
0 commit comments