Hi Darren,

Thank you for taking a look at my messages. I will attempt to
clarify the situation here. Please note my replies inline to
your comments below:

On 4/22/2025 5:37 AM, Darren Ankney wrote:
> Hi Chuck,
> 
> I have read through your several messages.  I am not quite
> understanding, however.  Are you saying that you have two interfaces
> with the same IP address or that you have two interfaces and only one
> of them has an IP address normally?

It is the first case - two interfaces with the same IPv4 address. I am
doing experiments to understand better what is happening and I plan to
start a new thread that will more clearly define the issue, once I
finish my experiments. For now, suffice it to say that my current
best explanation for this issue in this configuration of two interfaces
with the same IP address is very likely alluded to by the first comment
in the implementation of the PktFilterLPF::openSocket method, which reads
(in version 2.6.1 which I am running):

...
SocketInfo
PktFilterLPF::openSocket(Iface& iface,
                         const isc::asiolink::IOAddress& addr,
                         const uint16_t port, const bool,
                         const bool) {
    // Open fallback socket first. If it fails, it will give us an indication
    // that there is another service (perhaps DHCP server) running.
    // The function will throw an exception and effectively cease opening
    // raw socket below.
    int fallback = openFallbackSocket(addr, port);
...

It seems the code as it stands was written with only one cause for the
failure of the call to openFallbackSocket(addr, port) in mind: Another
DHCP server is running. But that is not the cause for the failure in
my case. I am fairly certain this failure occurs because, when
openFallbackSocket tries to bind the fallback socket to addr:port as the
fallback socket for the second interface which has the same IPv4 address
assigned to it as the first interface configured by kea, the EADDRINUSE
error is encountered from the bind(2) system call.

Of course we cannot recover if the system administrator is running
another DHCP server on that UDP socket! But can't we find a way to
recover and find a way to, for example, use the fallback socket
we opened for the first interface as the fallback socket also for
the second interface and even for any subsequent interface that
is configured with the same IP address?

If you are not convinced this is the problem, recall the warning message
I got when trying to open the fallback socket for the second interface:

Apr 19 16:25:05 almalinux kea-dhcp4[5650]: WARN  
[kea-dhcp4.dhcpsrv.139918558259328] DHCPSRV_OPEN_SOCKET_FAIL failed to open 
socket: Failed to open socket on interface vif6.0, reason: failed to bind 
fallback socket to address 192.168.1.105, port 67, reason: Address already in 
use - is another DHCP server running?

Also, As the comment in the code above notes, this exception
effectively ceases the opening of the raw socket also. And, as
you said, no raw socket, no service for locally connected clients.
So this explanation is consistent with the observed behavior and
nothing I have seen is inconsistent with this explanation.

So what I think is happening is this:

Kea opens both the raw socket and the fallback socket for the the
first interface configured with IPv4 equal to addr, and kea opens
neither the fallback socket nor the raw socket for the second
interface configured with the same IPv4 address as the first
interface configured by kea.

I also did some testing with netstat which should show the
fallback socket(s) and it is also consistent with this
explanation. For example, as previously noted in an earlier
message in this thread, I observed this for the case when I
worked around this issue by assigning the second interface
configured for kea with an address of 192.168.1.16,
instead of the default configuration of having both interfaces
configured for kea with an address of 192.168.1.105.

user@almalinux:~$ sudo netstat -lun --program | grep kea
udp        0      0 192.168.1.16:67         0.0.0.0:*                           
2369/kea-dhcp4
udp        0      0 192.168.1.105:67        0.0.0.0:*                           
2369/kea-dhcp4
user@almalinux:~$

I expect to get something like this if I set both addresses
configured for kea to an IP address of 192.168.1.105 and when
locally connected clients to the second interface are not
served, but I have not verified this yet:

user@almalinux:~$ sudo netstat -lun --program | grep kea
udp        0      0 192.168.1.105:67        0.0.0.0:*                           
2369/kea-dhcp4
user@almalinux:~$

This would indicate that the fallback socket for the second
interface failed to open because its address, 192.168.1.105,
is already in use as the fallback for the first interface.
And again for emphasis, as the code comment noted above states,
this effectively also prevents the opening of the raw socket
for the second interface. Again, as you said, no raw socket,
no service for my locally connected clients.

There are many other ways I could verify my current theory
which is based on the comment in the code quoted above, such
as by checking for the existence of the raw socket device files
in various configurations, but that is beyond the scope of this
message. For now, I will say I plan to do more tests and
experiments as I have time and, if it seems appropriate, end
this thread and try again by starting a new thread when I have
more understanding of this specific problem, a more clear
way of explaining it, and perhaps a proposed solution.

> 
> Also, if Kea cannot open a raw socket connection, then it can only
> serve relayed traffic.  It cannot serve local traffic.  If all of your
> traffic is local, and Kea is indeed serving this traffic, then it must
> be opening raw sockets.

In my scenario described above, I think it only opens one raw socket,
and it fails to open a raw socket for subsequent interfaces that have
the same IPv4 address. This explanation is also consistent with the
observed behavior of seeing two clients successfully configured if
I assign a different IPv4 address to the second interface. In that
case, the raw socket is successfully opened on the second interface
and kea can therefore serve the locally connected clients connected
to the second interface.

> 
> You can specify an IP address on any interface like this:
> "eth0/192.0.2.1" so if you do have different IP addresses on each
> interface (perhaps not even in the same subnet) these can be specified
> in the configuration as shown.

I hope you understand now this feature is not applicable to my scenario
in which each interface has only one IPv4 address.

> 
> As far as why Kea behaves differently than ISC DHCP.  ISC DHCP had its
> own networking engine written by ISC in the distant past.  Kea uses
> current common networking libraries.  I do not know if achieving the
> same behavior is possible.

I understand this point clearly. Specifically, I understand that the
behavior of the old ISC server of using the broadcast/unspecified
address for the fallback socket is probably not feasible using
current networking libraries. I see that in the modern library, the
fallback socket is never configured to bind to the broadcast/unspecified
address.

For solving this problem using the modern networking libraries,
I might suggest investigating the feasibility of modifying the
behavior of the openFallBackSocket method so it can deal with this
particular case by somehow sharing the fallback socket that was
opened for the first interface with the raw sockets of the subsequent
interfaces that would otherwise fail because of EADDRINUSE from the
bind(2) system call. But I am not expert enough to understand if
such an approach is feasible. I hope, for example, that at least
on platforms such as Linux that have SO_BINDTODEVICE, there may
be a way forward to a solution.

I already have a patch in mind as a proof-of-concept to at least
solve the main problem this issue causes me: the wasting of
IPv4 addresses, which is the main negative side effect of the only
workaround I have at the moment, a workaround that is a
regression compared to what was possible with the old ISC dhcp
server because with kea I need to waste IPv4 addresses that I
did not need to waste when using the old ISC server. But it will
be a while before I will have confidence that the proof-of-concept
patch I have in mind could be the basis for an acceptable solution
to this issue in the official kea project.

Thank you again,

Chuck Zmudzinski

----- snip ------
-- 
ISC funds the development of this software with paid support subscriptions. 
Contact us at https://www.isc.org/contact/ for more information.

To unsubscribe visit https://lists.isc.org/mailman/listinfo/kea-users.

Kea-users mailing list
Kea-users@lists.isc.org
https://lists.isc.org/mailman/listinfo/kea-users

Reply via email to