|
10 | 10 | # License for the specific language governing permissions and limitations
|
11 | 11 | # under the License.
|
12 | 12 |
|
13 |
| -from oslo_log import log |
14 |
| - |
15 |
| -from ovsdbapp.backend.ovs_idl import idlutils |
16 |
| -from ovsdbapp import constants as ovsdbapp_const |
17 |
| - |
18 | 13 | from neutron_lib.callbacks import events
|
19 | 14 | from neutron_lib.callbacks import registry
|
20 | 15 | from neutron_lib.callbacks import resources
|
21 | 16 | from neutron_lib import constants as const
|
22 | 17 | from neutron_lib.plugins import constants as plugin_constants
|
23 | 18 | from neutron_lib.plugins import directory
|
| 19 | +from oslo_log import log |
| 20 | +from oslo_utils import strutils |
| 21 | +from ovsdbapp.backend.ovs_idl import idlutils |
| 22 | +from ovsdbapp import constants as ovsdbapp_const |
24 | 23 |
|
25 | 24 | from neutron.common.ovn import constants as ovn_const
|
| 25 | +from neutron.common.ovn import exceptions as ovn_exc |
26 | 26 | from neutron.common.ovn import utils as ovn_utils
|
| 27 | +from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf |
27 | 28 | from neutron.db import ovn_revision_numbers_db as db_rev
|
28 | 29 | from neutron import manager
|
29 | 30 | from neutron.objects import port_forwarding as port_forwarding_obj
|
@@ -130,7 +131,41 @@ def _port_forwarding_created(self, ovn_txn, nb_ovn, pf_obj,
|
130 | 131 | "Switch %s failed as it is not found",
|
131 | 132 | lb_name, ls_name)
|
132 | 133 |
|
| 134 | + def _validate_router_networks(self, nb_ovn, router_id): |
| 135 | + if not ovn_conf.is_ovn_distributed_floating_ip(): |
| 136 | + return |
| 137 | + rtr_name = 'neutron-{}'.format(router_id) |
| 138 | + ovn_lr = nb_ovn.get_lrouter(rtr_name) |
| 139 | + if not ovn_lr: |
| 140 | + return |
| 141 | + for lrouter_port in ovn_lr.ports: |
| 142 | + is_ext_gw = strutils.bool_from_string( |
| 143 | + lrouter_port.external_ids.get(ovn_const.OVN_ROUTER_IS_EXT_GW)) |
| 144 | + if is_ext_gw: |
| 145 | + # NOTE(slaweq): This is external gateway port of the router and |
| 146 | + # this not needs to be checked |
| 147 | + continue |
| 148 | + ovn_network_name = lrouter_port.external_ids.get( |
| 149 | + ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY) |
| 150 | + if not ovn_network_name: |
| 151 | + continue |
| 152 | + network_id = ovn_network_name.replace('neutron-', '') |
| 153 | + if not network_id: |
| 154 | + continue |
| 155 | + if ovn_utils.is_provider_network(network_id): |
| 156 | + LOG.warning("Port forwarding configured in the router " |
| 157 | + "%(router_id)s will not work properly as " |
| 158 | + "distributed floating IPs are enabled " |
| 159 | + "and at least one provider network " |
| 160 | + "(%(network_id)s) is connected to that router. " |
| 161 | + "See bug https://launchpad.net/bugs/2028846 for " |
| 162 | + "more details.", { |
| 163 | + 'router_id': router_id, |
| 164 | + 'network_id': network_id}) |
| 165 | + return |
| 166 | + |
133 | 167 | def port_forwarding_created(self, ovn_txn, nb_ovn, pf_obj):
|
| 168 | + self._validate_router_networks(nb_ovn, pf_obj.router_id) |
134 | 169 | pf_objs = pf_obj.unroll_port_ranges()
|
135 | 170 | is_range = len(pf_objs) > 1
|
136 | 171 | for pf_obj in pf_objs:
|
@@ -192,10 +227,27 @@ def port_forwarding_deleted(self, ovn_txn, nb_ovn, pf_obj):
|
192 | 227 | class OVNPortForwarding(object):
|
193 | 228 |
|
194 | 229 | def __init__(self, l3_plugin):
|
| 230 | + self._validate_configuration() |
195 | 231 | self._l3_plugin = l3_plugin
|
196 | 232 | self._pf_plugin_property = None
|
197 | 233 | self._handler = OVNPortForwardingHandler()
|
198 | 234 |
|
| 235 | + def _validate_configuration(self): |
| 236 | + """This method checks if Neutron config is compatible with OVN and PFs. |
| 237 | +
|
| 238 | + It stops process in case when provider network types (vlan/flat) |
| 239 | + are enabled as tenant networks AND distributed floating IPs are enabled |
| 240 | + as this configuration is not working fine with FIP PFs in ML2/OVN case. |
| 241 | + """ |
| 242 | + try: |
| 243 | + ovn_utils.validate_port_forwarding_configuration() |
| 244 | + except ovn_exc.InvalidPortForwardingConfiguration: |
| 245 | + LOG.warning("Neutron configuration is invalid for port " |
| 246 | + "forwardings and ML2/OVN backend. " |
| 247 | + "It is not valid to use together provider network " |
| 248 | + "types (vlan/flat) as tenant networks, distributed " |
| 249 | + "floating IPs and port forwardings.") |
| 250 | + |
199 | 251 | @property
|
200 | 252 | def _pf_plugin(self):
|
201 | 253 | if self._pf_plugin_property is None:
|
|
0 commit comments