From 996741ebb81e5457470f9515336b3c7bbd0ca391 Mon Sep 17 00:00:00 2001 From: Ante Karamatic Date: Mon, 4 Feb 2013 14:02:25 +0100 Subject: [PATCH] Be smarter when figuring out broadcast address In most cases, broadcast is set when IP is set, but sometimes it can be ommitted. In those cases we should figure it out based on CIDR, and not assume it. Change-Id: Ia8c07898ddf0eb19f5d552a304d8f38915fc3560 Fixes: bug #1090621 --- quantum/agent/linux/ip_lib.py | 13 ++++++-- quantum/tests/unit/test_linux_ip_lib.py | 41 ++++++++++++++++++++----- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/quantum/agent/linux/ip_lib.py b/quantum/agent/linux/ip_lib.py index 78157d39ee..4065b44fff 100644 --- a/quantum/agent/linux/ip_lib.py +++ b/quantum/agent/linux/ip_lib.py @@ -14,6 +14,8 @@ # License for the specific language governing permissions and limitations # under the License. +import netaddr + from quantum.agent.linux import utils from quantum.common import exceptions @@ -273,8 +275,15 @@ class IpAddrCommand(IpDeviceCommandBase): broadcast = '::' else: version = 4 - broadcast = parts[3] - scope = parts[5] + if parts[2] == 'brd': + broadcast = parts[3] + scope = parts[5] + else: + # sometimes output of 'ip a' might look like: + # inet 192.168.100.100/24 scope global eth0 + # and broadcast needs to be calculated from CIDR + broadcast = str(netaddr.IPNetwork(parts[1]).broadcast) + scope = parts[3] retval.append(dict(cidr=parts[1], broadcast=broadcast, diff --git a/quantum/tests/unit/test_linux_ip_lib.py b/quantum/tests/unit/test_linux_ip_lib.py index 5b6710f07d..d622e80869 100644 --- a/quantum/tests/unit/test_linux_ip_lib.py +++ b/quantum/tests/unit/test_linux_ip_lib.py @@ -54,6 +54,24 @@ ADDR_SAMPLE = (""" valid_lft forever preferred_lft forever """) +ADDR_SAMPLE2 = (""" +2: eth0: mtu 1500 qdisc mq state UP qlen 1000 + link/ether dd:cc:aa:b9:76:ce brd ff:ff:ff:ff:ff:ff + inet 172.16.77.240/24 scope global eth0 + inet6 2001:470:9:1224:5595:dd51:6ba2:e788/64 scope global temporary dynamic + valid_lft 14187sec preferred_lft 3387sec + inet6 2001:470:9:1224:fd91:272:581e:3a32/64 scope global temporary """ + """deprecated dynamic + valid_lft 14187sec preferred_lft 0sec + inet6 2001:470:9:1224:4508:b885:5fb:740b/64 scope global temporary """ + """deprecated dynamic + valid_lft 14187sec preferred_lft 0sec + inet6 2001:470:9:1224:dfcc:aaff:feb9:76ce/64 scope global dynamic + valid_lft 14187sec preferred_lft 3387sec + inet6 fe80::dfcc:aaff:feb9:76ce/64 scope link + valid_lft forever preferred_lft forever +""") + GATEWAY_SAMPLE1 = (""" default via 10.35.19.254 metric 100 10.35.16.0/22 proto kernel scope link src 10.35.17.97 @@ -493,9 +511,12 @@ class TestIpAddrCommand(TestIPCmdBase): dynamic=False, cidr='fe80::dfcc:aaff:feb9:76ce/64', broadcast='::')] - self.parent._run = mock.Mock(return_value=ADDR_SAMPLE) - self.assertEqual(self.addr_cmd.list(), expected) - self._assert_call([], ('show', 'tap0')) + test_cases = [ADDR_SAMPLE, ADDR_SAMPLE2] + + for test_case in test_cases: + self.parent._run = mock.Mock(return_value=test_case) + self.assertEqual(self.addr_cmd.list(), expected) + self._assert_call([], ('show', 'tap0')) def test_list_filtered(self): expected = [ @@ -503,11 +524,15 @@ class TestIpAddrCommand(TestIPCmdBase): dynamic=False, cidr='172.16.77.240/24', broadcast='172.16.77.255')] - output = '\n'.join(ADDR_SAMPLE.split('\n')[0:4]) - self.parent._run.return_value = output - self.assertEqual(self.addr_cmd.list('global', filters=['permanent']), - expected) - self._assert_call([], ('show', 'tap0', 'permanent', 'scope', 'global')) + test_cases = [ADDR_SAMPLE, ADDR_SAMPLE2] + + for test_case in test_cases: + output = '\n'.join(test_case.split('\n')[0:4]) + self.parent._run.return_value = output + self.assertEqual(self.addr_cmd.list('global', + filters=['permanent']), expected) + self._assert_call([], ('show', 'tap0', 'permanent', 'scope', + 'global')) class TestIpRouteCommand(TestIPCmdBase):