@@ -1140,6 +1140,14 @@ def _output_opts_file(self):
1140
1140
file_utils .replace_file (name , '\n ' .join (options ))
1141
1141
return name
1142
1142
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
+
1143
1151
def _generate_opts_per_subnet (self ):
1144
1152
options = []
1145
1153
subnets_without_nameservers = set ()
@@ -1193,23 +1201,33 @@ def _generate_opts_per_subnet(self):
1193
1201
else :
1194
1202
host_routes .append ("%s,%s" % (hr .destination , hr .nexthop ))
1195
1203
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 :
1204
1227
host_routes .append (
1205
- '%s,%s' % (constants .METADATA_CIDR , subnet_dhcp_ip )
1228
+ '%s,%s' % (constants .METADATA_CIDR , metadata_route_ip )
1206
1229
)
1207
- elif not isolated_subnets [subnet .id ] and gateway :
1208
- host_routes .append (
1209
- '%s,%s' % (constants .METADATA_CIDR , gateway )
1210
- )
1211
1230
1212
- if subnet .ip_version == 4 :
1213
1231
for s in self ._get_all_subnets (self .network ):
1214
1232
sub_segment_id = getattr (s , 'segment_id' , None )
1215
1233
if (s .ip_version == 4 and
@@ -1374,13 +1392,21 @@ def has_metadata_subnet(subnets):
1374
1392
return True
1375
1393
return False
1376
1394
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
+
1377
1400
@classmethod
1378
1401
def should_enable_metadata (cls , conf , network ):
1379
1402
"""Determine whether the metadata proxy is needed for a network
1380
1403
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.
1384
1410
1385
1411
This method also returns True when enable_metadata_network is True,
1386
1412
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):
1389
1415
providing access to the metadata service via logical routers built
1390
1416
with 3rd party backends.
1391
1417
"""
1418
+ for port in network .ports :
1419
+ if cls ._is_ovn_metadata_port (port , network .id ):
1420
+ return False
1421
+
1392
1422
all_subnets = cls ._get_all_subnets (network )
1393
1423
dhcp_subnets = [s for s in all_subnets if s .enable_dhcp ]
1394
1424
if not dhcp_subnets :
0 commit comments