self.driver.init_l3(interface_name, ip_cidrs,
namespace=namespace)
+ # ensure that the dhcp interface is first in the list
+ if namespace is None:
+ device = ip_lib.IPDevice(interface_name, self.conf.root_helper)
+ device.route.pullup_route(interface_name)
+
return interface_name
def destroy(self, network, device_name):
return retval
+ def pullup_route(self, interface_name):
+ """
+ Ensures that the route entry for the interface is before all
+ others on the same subnet.
+ """
+ device_list = []
+ device_route_list_lines = self._run('list', 'proto', 'kernel',
+ 'dev', interface_name).split('\n')
+ for device_route_line in device_route_list_lines:
+ try:
+ subnet = device_route_line.split()[0]
+ except:
+ continue
+ subnet_route_list_lines = self._run('list', 'proto', 'kernel',
+ 'match', subnet).split('\n')
+ for subnet_route_line in subnet_route_list_lines:
+ i = iter(subnet_route_line.split())
+ while(i.next() != 'dev'):
+ pass
+ device = i.next()
+ try:
+ while(i.next() != 'src'):
+ pass
+ src = i.next()
+ except:
+ src = ''
+ if device != interface_name:
+ device_list.append((device, src))
+ else:
+ break
+
+ for (device, src) in device_list:
+ self._as_root('del', subnet, 'dev', device)
+ if (src != ''):
+ self._as_root('append', subnet, 'proto', 'kernel',
+ 'src', src, 'dev', device)
+ else:
+ self._as_root('append', subnet, 'proto', 'kernel',
+ 'dev', device)
+
class IpNetnsCommand(IpCommandBase):
COMMAND = 'netns'
default via 10.35.19.254
""")
+DEVICE_ROUTE_SAMPLE = ("10.0.0.0/24 scope link src 10.0.0.2")
+
+SUBNET_SAMPLE1 = ("10.0.0.0/24 dev qr-23380d11-d2 scope link src 10.0.0.1\n"
+ "10.0.0.0/24 dev tap1d7888a7-10 scope link src 10.0.0.2")
+SUBNET_SAMPLE2 = ("10.0.0.0/24 dev tap1d7888a7-10 scope link src 10.0.0.2\n"
+ "10.0.0.0/24 dev qr-23380d11-d2 scope link src 10.0.0.1")
+
class TestSubProcessBase(unittest.TestCase):
def setUp(self):
self.assertEquals(self.route_cmd.get_gateway(),
test_case['expected'])
+ def test_pullup_route(self):
+ # interface is not the first in the list - requires
+ # deleting and creating existing entries
+ output = [DEVICE_ROUTE_SAMPLE, SUBNET_SAMPLE1]
+
+ def pullup_side_effect(self, *args):
+ result = output.pop(0)
+ return result
+
+ self.parent._run = mock.Mock(side_effect=pullup_side_effect)
+ self.route_cmd.pullup_route('tap1d7888a7-10')
+ self._assert_sudo([], ('del', '10.0.0.0/24', 'dev', 'qr-23380d11-d2'))
+ self._assert_sudo([], ('append', '10.0.0.0/24', 'proto', 'kernel',
+ 'src', '10.0.0.1', 'dev', 'qr-23380d11-d2'))
+
+ def test_pullup_route_first(self):
+ # interface is first in the list - no changes
+ output = [DEVICE_ROUTE_SAMPLE, SUBNET_SAMPLE2]
+
+ def pullup_side_effect(self, *args):
+ result = output.pop(0)
+ return result
+
+ self.parent._run = mock.Mock(side_effect=pullup_side_effect)
+ self.route_cmd.pullup_route('tap1d7888a7-10')
+ # Check two calls - device get and subnet get
+ self.assertEqual(len(self.parent._run.mock_calls), 2)
+
class TestIpNetnsCommand(TestIPCmdBase):
def setUp(self):