Fix dnsmasq option6 tagging logic

In attempting to fix option passing for Ironic, I discovered that
I would end up with option6:option6:59 if I passed "option6:59" or
I would end up with just "59".

According to the dnsmasq man page, "option6" labeling is mandatory.
That being said, I'll remove the transmission of "option6" from
ironic, but without fixing this issue IPv6 support for booting
baremetal nodes is broken.

Change-Id: I87c15908087111367358043f7a63dd02dd9d16ac
Story: 2004501
Task: 28219
This commit is contained in:
Julia Kreger 2018-12-02 07:22:43 -08:00 committed by Slawek Kaplonski
parent 757f29642e
commit e7f4783096
2 changed files with 57 additions and 5 deletions

View File

@ -1095,11 +1095,15 @@ class Dnsmasq(DhcpLocalProcess):
if isinstance(tag, int):
tag = self._TAG_PREFIX % tag
if not option.isdigit():
if ip_version == 4:
option = 'option:%s' % option
else:
option = 'option6:%s' % option
# NOTE(TheJulia): prepending option6 to any DHCPv6 option is
# indicated as required in the dnsmasq man page for version 2.79.
# Testing reveals that the man page is correct, option is not
# honored if not in the format "option6:$NUM". For IPv4 we
# only apply if the option is non-numeric.
if ip_version == constants.IP_VERSION_6:
option = 'option6:%s' % option
elif not option.isdigit():
option = 'option:%s' % option
if extra_tag:
tags = ('tag:' + tag, extra_tag[:-1], '%s' % option)
else:

View File

@ -901,6 +901,25 @@ class FakeV4NetworkPxe3Ports(FakeNetworkBase):
DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux3.0')]
class FakeV4NetworkPxePort(FakeNetworkBase):
def __init__(self):
self.id = 'dddddddd-dddd-dddd-dddd-dddddddddddd'
self.subnets = [FakeV4Subnet()]
self.ports = [FakePort1()]
self.namespace = 'qdhcp-ns'
self.ports[0].extra_dhcp_opts = [
DhcpOpt(opt_name='tftp-server', opt_value='192.168.0.3',
ip_version=constants.IP_VERSION_4),
DhcpOpt(opt_name='server-ip-address', opt_value='192.168.0.2',
ip_version=constants.IP_VERSION_4),
DhcpOpt(opt_name='nd98', opt_value='option-nondigit-98',
ip_version=constants.IP_VERSION_4),
DhcpOpt(opt_name='99', opt_value='option-99',
ip_version=constants.IP_VERSION_4),
DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0',
ip_version=constants.IP_VERSION_4)]
class FakeV6NetworkPxePort(FakeNetworkBase):
def __init__(self):
self.id = 'dddddddd-dddd-dddd-dddd-dddddddddddd'
@ -910,6 +929,10 @@ class FakeV6NetworkPxePort(FakeNetworkBase):
self.ports[0].extra_dhcp_opts = [
DhcpOpt(opt_name='tftp-server', opt_value='2001:192:168::1',
ip_version=constants.IP_VERSION_6),
DhcpOpt(opt_name='nd98', opt_value='option-nondigit-98',
ip_version=constants.IP_VERSION_6),
DhcpOpt(opt_name='99', opt_value='option-99',
ip_version=constants.IP_VERSION_6),
DhcpOpt(opt_name='bootfile-name', opt_value='pxelinux.0',
ip_version=constants.IP_VERSION_6)]
@ -1775,6 +1798,27 @@ class TestDnsmasq(TestBase):
self._test_output_opts_file(expected, FakeDualV4Pxe3Ports())
def test_output_opts_file_pxe_port(self):
expected = (
'tag:tag0,option:dns-server,8.8.8.8\n'
'tag:tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1,'
'0.0.0.0/0,192.168.0.1\n'
'tag:tag0,249,20.0.0.1/24,20.0.0.1,'
'0.0.0.0/0,192.168.0.1\n'
'tag:tag0,option:router,192.168.0.1\n'
'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,'
'option:tftp-server,192.168.0.3\n'
'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,'
'option:server-ip-address,192.168.0.2\n'
'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,'
'option:nd98,option-nondigit-98\n'
'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,'
'99,option-99\n'
'tag:eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee,'
'option:bootfile-name,pxelinux.0').lstrip()
self._test_output_opts_file(expected, FakeV4NetworkPxePort())
def test_output_opts_file_multiple_tags(self):
expected = (
'tag:tag0,option:dns-server,8.8.8.8\n'
@ -1804,6 +1848,10 @@ class TestDnsmasq(TestBase):
'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,'
'option6:tftp-server,2001:192:168::1\n'
'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,'
'option6:nd98,option-nondigit-98\n'
'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,'
'option6:99,option-99\n'
'tag:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh,'
'option6:bootfile-name,pxelinux.0')
expected = expected.lstrip()