summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-06-27 14:09:01 +0000
committerGerrit Code Review <review@openstack.org>2018-06-27 14:09:01 +0000
commitb66d5aed3652452473dcd3d6747068081b34968a (patch)
tree7cc1a4cdda47988a58cc7c4198aa5b3ec3a7322a
parentaa48141706c2398a3754acd26d434192c259086e (diff)
parent3538cd6bc67e1ab8d904a5f96ec729ba50d5316d (diff)
downloadironic-python-agent-b66d5aed3652452473dcd3d6747068081b34968a.tar.gz
Merge "[LLDP] Skip NICs that say they are ready but are unreadable." into stable/ocata
-rw-r--r--ironic_python_agent/netutils.py15
-rw-r--r--ironic_python_agent/tests/unit/test_netutils.py45
-rw-r--r--releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml7
3 files changed, 63 insertions, 4 deletions
diff --git a/ironic_python_agent/netutils.py b/ironic_python_agent/netutils.py
index 45b85a5d..5d38548d 100644
--- a/ironic_python_agent/netutils.py
+++ b/ironic_python_agent/netutils.py
@@ -182,10 +182,17 @@ def _get_lldp_info(interfaces):
# Create a copy of interfaces to avoid deleting while iterating.
for index, interface in enumerate(list(interfaces)):
if s == interface[1]:
- LOG.info('Found LLDP info for interface: %s',
- interface[0])
- lldp_info[interface[0]] = (
- _receive_lldp_packets(s))
+ try:
+ lldp_info[interface[0]] = _receive_lldp_packets(s)
+ except socket.error:
+ LOG.exception('Socket for network interface %s said '
+ 'that it was ready to read we were '
+ 'unable to read from the socket while '
+ 'trying to get LLDP packet. Skipping '
+ 'this network interface.', interface[0])
+ else:
+ LOG.info('Found LLDP info for interface: %s',
+ interface[0])
# Remove interface from the list, only need one packet
del interfaces[index]
diff --git a/ironic_python_agent/tests/unit/test_netutils.py b/ironic_python_agent/tests/unit/test_netutils.py
index 14c8b82e..0bdaaac8 100644
--- a/ironic_python_agent/tests/unit/test_netutils.py
+++ b/ironic_python_agent/tests/unit/test_netutils.py
@@ -13,6 +13,7 @@
# limitations under the License.
import binascii
+import socket
import mock
from oslo_config import cfg
@@ -87,6 +88,50 @@ class TestNetutils(test_base.BaseTestCase):
@mock.patch('fcntl.ioctl')
@mock.patch('select.select')
@mock.patch('socket.socket')
+ def test_get_lldp_info_socket_recv_error(self, sock_mock, select_mock,
+ fcntl_mock):
+ expected_lldp = {
+ 'eth1': [
+ (0, b''),
+ (1, b'\x04\x88Z\x92\xecTY'),
+ (2, b'\x05Ethernet1/18'),
+ (3, b'\x00x')]
+ }
+
+ interface_names = ['eth0', 'eth1']
+
+ sock1 = mock.Mock()
+ sock1.recv.side_effect = socket.error("BOOM")
+
+ sock2 = mock.Mock()
+ sock2.recv.return_value = FAKE_LLDP_PACKET
+ sock2.fileno.return_value = 5
+
+ sock_mock.side_effect = [sock1, sock2]
+
+ select_mock.side_effect = [
+ ([sock1], [], []),
+ ([sock2], [], [])
+ ]
+
+ lldp_info = netutils.get_lldp_info(interface_names)
+ self.assertEqual(expected_lldp, lldp_info)
+
+ sock1.bind.assert_called_with(('eth0', netutils.LLDP_ETHERTYPE))
+ sock2.bind.assert_called_with(('eth1', netutils.LLDP_ETHERTYPE))
+
+ sock1.recv.assert_called_with(1600)
+ sock2.recv.assert_called_with(1600)
+
+ self.assertEqual(1, sock1.close.call_count)
+ self.assertEqual(1, sock2.close.call_count)
+
+ # 2 interfaces, 2 calls to enter promiscuous mode, 1 to leave
+ self.assertEqual(6, fcntl_mock.call_count)
+
+ @mock.patch('fcntl.ioctl')
+ @mock.patch('select.select')
+ @mock.patch('socket.socket')
def test_get_lldp_info_multiple(self, sock_mock, select_mock, fcntl_mock):
expected_lldp = {
'eth1': [
diff --git a/releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml b/releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml
new file mode 100644
index 00000000..1f54af9b
--- /dev/null
+++ b/releasenotes/notes/LLDP-ignore-NICs-that-are-not-plugged-in-29213f0a701a72e4.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+ - |
+ Fixes bug in LLDP discovery code which lead to no LLDP information being
+ discovered for any network interface if one network interface raised an
+ exception, for example if the network interface incorrectly indicates its
+ ready to read. `<https://bugs.launchpad.net/ironic-python-agent/+bug/1665025>`_