Merge "[LLDP] Skip NICs that say they are ready but are unreadable."

This commit is contained in:
Zuul 2017-12-05 19:17:31 +00:00 committed by Gerrit Code Review
commit 79d1dbed74
3 changed files with 63 additions and 4 deletions

View File

@ -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]

View File

@ -13,6 +13,7 @@
# limitations under the License.
import binascii
import socket
import mock
from oslo_config import cfg
@ -89,6 +90,50 @@ class TestNetutils(base.IronicAgentTest):
# 2 interfaces, 2 calls to enter promiscuous mode, 1 to leave
self.assertEqual(6, fcntl_mock.call_count)
@mock.patch('fcntl.ioctl', autospec=True)
@mock.patch('select.select', autospec=True)
@mock.patch('socket.socket', autospec=socket_socket_sig)
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', autospec=True)
@mock.patch('select.select', autospec=True)
@mock.patch('socket.socket', autospec=socket_socket_sig)

View File

@ -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>`_