network: allow "modify" option for DNS-Srv records

The "modify" command allows to replace an existing Srv record
(some of its elements respectively: port, priority and weight).
The primary key used to choose the modify record is the remaining
parameters, only one of them is required. Not using some of these
parameters may cause duplicate records and error message. This
logic is there because of the previous implementation (Add and
Delete options) in the function.

Tests in networkxml2xmlupdatetest.c contain replacements of an
existing DNS-Srv record and failure due to non-existing record.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/639
Signed-off-by: Adam Julis <ajulis@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Adam Julis 2024-07-09 17:23:18 +02:00 committed by Michal Privoznik
parent 09a5d8165c
commit cf934c87cc
5 changed files with 58 additions and 7 deletions

View File

@ -3257,12 +3257,6 @@ virNetworkDefUpdateDNSSrv(virNetworkDef *def,
command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST); command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
int foundCt = 0; int foundCt = 0;
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("DNS SRV records cannot be modified, only added or deleted"));
goto cleanup;
}
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0) if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "srv") < 0)
goto cleanup; goto cleanup;
@ -3312,6 +3306,27 @@ virNetworkDefUpdateDNSSrv(virNetworkDef *def,
virNetworkDNSSrvDefClear(&dns->srvs[foundIdx]); virNetworkDNSSrvDefClear(&dns->srvs[foundIdx]);
VIR_DELETE_ELEMENT(dns->srvs, foundIdx, dns->nsrvs); VIR_DELETE_ELEMENT(dns->srvs, foundIdx, dns->nsrvs);
} else if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
if (foundCt == 0) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("couldn't locate a matching DNS SRV record in network %1$s"),
def->name);
goto cleanup;
}
if (foundCt > 1) {
virReportError(VIR_ERR_OPERATION_INVALID,
_("multiple DNS SRV records matching all specified fields were found in network %1$s"),
def->name);
goto cleanup;
}
virNetworkDNSSrvDefClear(&dns->srvs[foundIdx]);
memcpy(&dns->srvs[foundIdx], &srv, sizeof(virNetworkDNSSrvDef));
memset(&srv, 0, sizeof(virNetworkDNSSrvDef));
} else { } else {
virNetworkDefUpdateUnknownCommand(command); virNetworkDefUpdateUnknownCommand(command);
goto cleanup; goto cleanup;

View File

@ -0,0 +1 @@
<srv service='name' protocol='tcp' domain='unknown-domain' target='.' port='666' priority='99' weight='10'/>

View File

@ -0,0 +1 @@
<srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1221' priority='42' weight='69'/>

View File

@ -0,0 +1,26 @@
<network>
<name>default</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward dev='eth1' mode='nat'>
<interface dev='eth1'/>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<dns>
<srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1221' priority='42' weight='69'/>
</dns>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
<host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10'/>
<host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11'/>
</dhcp>
</ip>
<ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
</ip>
<ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
</ip>
<ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
</ip>
<ip family='ipv4' address='10.24.10.1'>
</ip>
</network>

View File

@ -328,7 +328,6 @@ mymain(void)
"nat-network-dns-srv-record", "nat-network-dns-srv-record",
"nat-network-dns-srv-records", "nat-network-dns-srv-records",
VIR_NETWORK_UPDATE_COMMAND_ADD_LAST); VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
DO_TEST_FAIL("delete-missing-srv-record-service", DO_TEST_FAIL("delete-missing-srv-record-service",
"srv-record-service", "srv-record-service",
"nat-network", "nat-network",
@ -351,6 +350,15 @@ mymain(void)
"nat-network-dns-srv-record", "nat-network-dns-srv-record",
"nat-network", "nat-network",
VIR_NETWORK_UPDATE_COMMAND_DELETE); VIR_NETWORK_UPDATE_COMMAND_DELETE);
DO_TEST("modify-srv-record-protocol",
"srv-record-modify-few",
"nat-network-dns-srv-record",
"nat-network-dns-srv-modify-few",
VIR_NETWORK_UPDATE_COMMAND_MODIFY);
DO_TEST_FAIL("modify-not-existing-srv-record",
"srv-not-existing",
"nat-network-dns-srv-record",
VIR_NETWORK_UPDATE_COMMAND_MODIFY);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;