Always fill UDP checksums in DHCPv6 replies
Bug #1244589 re-appeared for IPv6.
This change adds an ip6tables rule to fix the checksum of DHCPv6
response packets. Those checksums were left unfilled by virtio (as a
hypervisor internal optimization), but some picky dhcp clients (AFAIU
particularly ISC dhclient) try verifying the checksums, so they fail
to acquire an address if the checksums are left incorrect.
Change-Id: I4a045e0dcfcbd3c7959a78f1460d5bf7da0252ff
Closes-Bug: #1811639
Related-Bug: #1244589
(cherry picked from commit 26eb2509fe
)
This commit is contained in:
parent
9ad99657f3
commit
50a7a74e97
@ -1557,9 +1557,12 @@ class DeviceManager(object):
|
||||
|
||||
def fill_dhcp_udp_checksums(self, namespace):
|
||||
"""Ensure DHCP reply packets always have correct UDP checksums."""
|
||||
iptables_mgr = iptables_manager.IptablesManager(use_ipv6=False,
|
||||
iptables_mgr = iptables_manager.IptablesManager(use_ipv6=True,
|
||||
namespace=namespace)
|
||||
ipv4_rule = ('-p udp -m udp --dport %d -j CHECKSUM --checksum-fill'
|
||||
% constants.DHCP_RESPONSE_PORT)
|
||||
ipv6_rule = ('-p udp -m udp --dport %d -j CHECKSUM --checksum-fill'
|
||||
% n_const.DHCPV6_CLIENT_PORT)
|
||||
iptables_mgr.ipv4['mangle'].add_rule('POSTROUTING', ipv4_rule)
|
||||
iptables_mgr.ipv6['mangle'].add_rule('POSTROUTING', ipv6_rule)
|
||||
iptables_mgr.apply()
|
||||
|
@ -187,6 +187,9 @@ IP_ALLOWED_VERSIONS = [lib_constants.IP_VERSION_4, lib_constants.IP_VERSION_6]
|
||||
PORT_RANGE_MIN = 1
|
||||
PORT_RANGE_MAX = 65535
|
||||
|
||||
# TODO(bence romsics): move this to neutron_lib.constants
|
||||
DHCPV6_CLIENT_PORT = 546
|
||||
|
||||
# Configuration values for accept_ra sysctl, copied from linux kernel
|
||||
# networking (netdev) tree, file Documentation/networking/ip-sysctl.txt
|
||||
#
|
||||
|
@ -33,6 +33,7 @@ from neutron.agent.linux import dhcp
|
||||
from neutron.agent.linux import interface
|
||||
from neutron.agent.metadata import driver as metadata_driver
|
||||
from neutron.common import config as common_config
|
||||
from neutron.common import constants as n_const
|
||||
from neutron.common import utils
|
||||
from neutron.conf.agent import common as config
|
||||
from neutron.conf.agent import dhcp as dhcp_config
|
||||
@ -1571,8 +1572,10 @@ class TestDeviceManager(base.BaseTestCase):
|
||||
iptables_cls = iptables_cls_p.start()
|
||||
self.iptables_inst = mock.Mock()
|
||||
iptables_cls.return_value = self.iptables_inst
|
||||
self.mangle_inst = mock.Mock()
|
||||
self.iptables_inst.ipv4 = {'mangle': self.mangle_inst}
|
||||
self.mangle_inst_v4 = mock.Mock()
|
||||
self.iptables_inst.ipv4 = {'mangle': self.mangle_inst_v4}
|
||||
self.mangle_inst_v6 = mock.Mock()
|
||||
self.iptables_inst.ipv6 = {'mangle': self.mangle_inst_v6}
|
||||
|
||||
self.mock_ip_wrapper_p = mock.patch("neutron.agent.linux.ip_lib."
|
||||
"IPWrapper")
|
||||
@ -1646,12 +1649,19 @@ class TestDeviceManager(base.BaseTestCase):
|
||||
self.mock_ipv6_enabled.return_value = False
|
||||
self._test_setup_helper(False, ipv6_enabled=False)
|
||||
|
||||
def test_setup_calls_fill_dhcp_udp_checksums(self):
|
||||
def test_setup_calls_fill_dhcp_udp_checksums_v4(self):
|
||||
self._test_setup_helper(False)
|
||||
rule = ('-p udp -m udp --dport %d -j CHECKSUM --checksum-fill'
|
||||
% const.DHCP_RESPONSE_PORT)
|
||||
expected = [mock.call.add_rule('POSTROUTING', rule)]
|
||||
self.mangle_inst.assert_has_calls(expected)
|
||||
self.mangle_inst_v4.assert_has_calls(expected)
|
||||
|
||||
def test_setup_calls_fill_dhcp_udp_checksums_v6(self):
|
||||
self._test_setup_helper(False)
|
||||
rule = ('-p udp -m udp --dport %d -j CHECKSUM --checksum-fill'
|
||||
% n_const.DHCPV6_CLIENT_PORT)
|
||||
expected = [mock.call.add_rule('POSTROUTING', rule)]
|
||||
self.mangle_inst_v6.assert_has_calls(expected)
|
||||
|
||||
def test_setup_dhcp_port_doesnt_orphan_devices(self):
|
||||
with mock.patch.object(dhcp.ip_lib, 'IPDevice') as mock_IPDevice:
|
||||
|
Loading…
Reference in New Issue
Block a user