diff --git a/kuryr_kubernetes/cni/binding/nested.py b/kuryr_kubernetes/cni/binding/nested.py index b4cb267d0..2a9e81e23 100644 --- a/kuryr_kubernetes/cni/binding/nested.py +++ b/kuryr_kubernetes/cni/binding/nested.py @@ -21,6 +21,7 @@ import pyroute2 from kuryr_kubernetes.cni.binding import base as b_base from kuryr_kubernetes import config +from kuryr_kubernetes import exceptions from kuryr_kubernetes.handlers import health from kuryr_kubernetes import utils @@ -68,6 +69,16 @@ class NestedDriver(health.HealthHandler, b_base.BaseBindingDriver): # TODO(vikasc): evaluate whether we should have stevedore # driver for getting the link device. vm_iface_name = config.CONF.binding.link_iface + mtu = h_ipdb.interfaces[vm_iface_name].mtu + if mtu != vif.network.mtu: + # NOTE(dulek): This might happen if Neutron and DHCP agent + # have different MTU settings. See + # https://bugs.launchpad.net/kuryr-kubernetes/+bug/1863212 + raise exceptions.CNIBindingFailure( + f'MTU of interface {vm_iface_name} ({mtu}) does not ' + f'match MTU of pod network {vif.network.id} ' + f'({vif.network.mtu}). Please make sure pod network ' + f'has the same MTU as node (VM) network.') args = self._get_iface_create_args(vif) with h_ipdb.create(ifname=temp_name, diff --git a/kuryr_kubernetes/exceptions.py b/kuryr_kubernetes/exceptions.py index b2fa1d04b..868171c3f 100644 --- a/kuryr_kubernetes/exceptions.py +++ b/kuryr_kubernetes/exceptions.py @@ -76,3 +76,9 @@ class MultiPodDriverPoolConfigurationNotSupported(Exception): 2. One of the pod drivers is not supported 3. One of the pod drivers is not supported by its selected pool driver """ + + +class CNIBindingFailure(Exception): + """Exception indicates a binding/unbinding VIF failure in CNI""" + def __init__(self, message): + super(CNIBindingFailure, self).__init__(message) diff --git a/kuryr_kubernetes/tests/unit/cni/test_binding.py b/kuryr_kubernetes/tests/unit/cni/test_binding.py index 84d69d8dc..ba5a49fc7 100644 --- a/kuryr_kubernetes/tests/unit/cni/test_binding.py +++ b/kuryr_kubernetes/tests/unit/cni/test_binding.py @@ -21,6 +21,7 @@ from oslo_config import cfg from kuryr_kubernetes.cni.binding import base from kuryr_kubernetes.cni.binding import sriov from kuryr_kubernetes import constants as k_const +from kuryr_kubernetes import exceptions from kuryr_kubernetes import objects from kuryr_kubernetes.tests import base as test_base from kuryr_kubernetes.tests import fake @@ -60,6 +61,7 @@ class TestDriverMixin(test_base.TestCase): 'bridge': mock.Mock( __enter__=mock.Mock(return_value=self.m_bridge_iface), __exit__=mock.Mock(return_value=None), + mtu=1, ), 'c_interface': mock.Mock( __enter__=mock.Mock(return_value=self.m_c_iface), @@ -187,6 +189,10 @@ class TestNestedVlanDriver(TestDriverMixin, test_base.TestCase): self.assertEqual(str(self.vif.address), self.m_h_iface.address) self.m_h_iface.up.assert_called_once_with() + def test_connect_mtu_mismatch(self): + self.vif.network.mtu = 2 + self.assertRaises(exceptions.CNIBindingFailure, self._test_connect) + def test_disconnect(self): self._test_disconnect() @@ -209,6 +215,10 @@ class TestNestedMacvlanDriver(TestDriverMixin, test_base.TestCase): self.assertEqual(str(self.vif.address), self.m_h_iface.address) self.m_h_iface.up.assert_called_once_with() + def test_connect_mtu_mismatch(self): + self.vif.network.mtu = 2 + self.assertRaises(exceptions.CNIBindingFailure, self._test_connect) + def test_disconnect(self): self._test_disconnect()