Opened 2 years ago

Closed 2 years ago

#5416 closed defect (fixed)

reservation-add "Database duplicate entry error"

Reported by: cathya Owned by: marcin
Priority: high Milestone: Kea1.4
Component: Unclassified Version: git
Keywords: Cc:
CVSS Scoring: Parent Tickets:
Sensitive: no Defect Severity: Medium
Sub-Project: DHCP Feature Depending on Ticket:
Estimated Difficulty: 0 Add Hours to Ticket: 1
Total Hours: 1 Internal?: no



Attempting to add a second reservation in a different subnet within the same shared-network results in the database error above.

The rules as documented are:

Section 8.3:

"Making a reservation for a mobile host that may visit multiple
subnets requires a separate host definition in each subnet it is
expected to visit. It is not allowed to define multiple host
definitions with the same hardware address in a single subnet.
Multiple host definitions with the same hardware address are valid if
each is in a different subnet.”

Then for shared networks (section 8.4.3) we add:

"It is worth noting that Kea conducts additional checks when
processing a packet if shared networks are defined. First, instead of
simply checking if there's a reservation for a given client in his
initially selected subnet, it goes through all subnets in a shared
network looking for a reservation. This is one of the reasons why
defining a shared network may impact performance. If there is a
reservation for a client in any subnet, that particular subnet will be
picked for the client. Although it's technically not an error, it is
considered a bad practice to define reservations for the same host in
multiple subnets belonging to the same shared network."

The reason for wanting to do this is that when using shared networks, you still have to use the subnet id (rather than an ID for the shared network) when adding reservations. So in the situation where a client might obtain a lease in one of several subnets of the shared network, but where you *don't* want to add a host reservation, you just want to do something like provide a specific bootfile depending on the options that the client requests, then there's nothing you can do to 'make this so' across all subnets, other than adding the same reservation in *all* the subnets.

This, in theory, is supposed to work, even though it's not recommended. But it doesn't - it fails on attempting to add the second reservation with ""Database duplicate entry error"


Change History (9)

comment:1 Changed 2 years ago by cathya

An example of this not working is:

$ curl -X POST -H "Content-Type:
application/json" -d '{ "service": [ "dhcp4" ], "command":
"reservation-add", "arguments": { "reservation": { "subnet-id": 1,
"flex-id": "<<-- redacted -->>", "boot-file-name":
"/dev/null" } } }'
[ { "result": 0, "text": "Host added." } ]
curl -X POST -H "Content-Type:
application/json" -d '{ "service": [ "dhcp4" ], "command":
"reservation-add", "arguments": { "reservation": { "subnet-id": 2,
"flex-id": "<<-- redacted (same as in previous add) -->>", "boot-file-name":
"/dev/null" } } }'
[ { "result": 1, "text": "Database duplicate entry error" } ]

Note that the subnet-id is different for the second reservation-add. These are subnets that are part of a shared network.

comment:2 Changed 2 years ago by cathya

This turns out to be because of database constraints that don't consider that some values might be null. It was necessary to remove both of these constrainst to make it possible to add the two reservations for different subnets:

CONSTRAINT key_dhcp4_ipv4_address_subnet_id UNIQUE (ipv4_address, dhcp4_subnet_id),

CONSTRAINT key_dhcp6_identifier_subnet_id UNIQUE (dhcp_identifier, dhcp_identifier_type, dhcp6_subnet_id),

The problem with the first constraint is not that there is an attempt to use the same reservation in different subnets in the same shared network, but because the reservations have a null ipv4_address - so it's a duplication/collision between other reservations in the same subnet that is being hit.

The second one (unexpectely/oddly) is also a problem because you will have a null dhcp6_subnet_id when adding a V4 reservation - so another duplication/collision on that basis too.

Tests after removing the constraints and retrying the addition of the reservation confirmed that both of the above needed to be removed to get this to work.

But this leaves the database wide open to other duplication that shouldn't be permitted.

We need better constraints?

comment:3 Changed 2 years ago by marcin

  • Owner set to marcin
  • Status changed from new to accepted

comment:4 Changed 2 years ago by marcin

  • Milestone changed from Kea-proposed to Kea1.4

comment:5 Changed 2 years ago by marcin

Move to Kea 1.4 per Kea team call on Nov 2nd, 2017.

comment:6 Changed 2 years ago by marcin

  • Owner changed from marcin to UnAssigned
  • Status changed from accepted to reviewing

This ticket is now ready for review. I updated Postgresql schema creation scripts to use partial indexes and allow duplicate values of 0 and null. I didn't have to update the MySQL schema because, by nature of MySQL, it allows multiple null values within an indexed column. I only had to update the MySQL backend to convert 0 values to null to utilize this property of MySQL.

Proposed ChangeLog entry:

13XX.	[bug]		marcin
	Fixed a bug which prevented inserting multiple host reservations
	where IPv4 address was unspecified or when selected subnet
	identifier was not specified. This change affects both Postgres
	and MySQL backend.
	(Trac #5416, git cafe)

comment:7 Changed 2 years ago by tmark

  • Owner changed from UnAssigned to tmark

comment:8 Changed 2 years ago by tmark

  • Add Hours to Ticket changed from 0 to 1
  • Owner changed from tmark to marcin
  • Total Hours changed from 0 to 1

I did a little word smithing so please pull first.
Changes otherwise, seem fine. Units pass for mysql and postgres under Ubuntu.

comment:9 Changed 2 years ago by marcin

  • Resolution set to fixed
  • Status changed from reviewing to closed

Merged with commit 03fab8f7d5c2e8a5ea735b11ff75652aa31d791d

Note: See TracTickets for help on using tickets.