[Kea-users] Problems trying to implement RFC 8925 (v6-only-preferred)

Brian Candler b.candler at pobox.com
Fri Jul 28 19:12:24 UTC 2023


Hello,

I have a somewhat out-of-the-ordinary config question. I'm using 
isc-kea-dhcp4 version 2.4.0 under Ubuntu 22.04.  The full config is at 
the end of this mail.

Background: I have set up a "mostly IPv6" subnet, as per this article: 
https://labs.ripe.net/author/ondrej_caletka_1/deploying-ipv6-mostly-access-networks/

I have it working when offering IPv4 addresses to all clients. Those 
which support the v6-only-preferred option happily ignore the IPv4 
address that I offer, and will configure themselves as IPv6-only.  Neat.

However, I want to tighten this up to make it a true "IPv6-only" 
network, as follows:

(a) Only make an offer to clients which request the "v6-only-preferred" 
parameter (option 108, RFC 8925).  That is: I don't want to offer IPv4 
addresses to anyone who will actually use them.

(b) Offer yiaddr 0.0.0.0, as RFC 8925 section 3.3 says I should, instead 
of a pool address.  And preferably get rid of the pool entirely.


Problem 1: in order to test whether the client supports 
v6-only-preferred, I have to check whether 108 is included in the 
dhcp-parameter-request-list (option 55) from the request.

Unfortunately, "option[108].exists" does not work for this, because the 
client isn't sending option 108; they are only requesting option 108 as 
a response parameter.

The only solution I could come up with was this:

     "client-classes": [
         {
             "name": "rfc8925",
             "test": "substring(option[55].hex, 0, 1) == 0x6c or 
substring(option[55].hex, 1, 1) == 0x6c or substring(option[55].hex, 2, 
1) == 0x6c or substring(option[55].hex, 3, 1) == 0x6c or 
substring(option[55].hex, 4, 1) == 0x6c or substring(option[55].hex, 5, 
1) == 0x6c or substring(option[55].hex, 6, 1) == 0x6c or 
substring(option[55].hex, 7, 1) == 0x6c or substring(option[55].hex, 8, 
1) == 0x6c or substring(option[55].hex, 9, 1) == 0x6c or 
substring(option[55].hex, 10, 1) == 0x6c or substring(option[55].hex, 
11, 1) == 0x6c or substring(option[55].hex, 12, 1) == 0x6c"
         },
     ],

... and even that's not complete, in case the client requests more than 
13 options.  Is there a better way to do this?


Problem 2: how can I return a yiaddr of 0.0.0.0 ?  I thought about 
setting a static dummy flex-id, e.g.

             "reservations": [
                 {
                     "flex-id": "'any'",
                     "ip-address": "0.0.0.0"
                 }
             ]

but I'm using the open-source version of Kea, which means I don't have 
the flex_id hook.  I don't think a pool starting from 0.0.0.0 will work, 
because once that's been given out to one client, it's no longer 
available for other clients (unless I use a tiny lease time??)  In any 
case, I'd also avoid allocating addresses from a pool in the first 
place, so that the pool doesn't become exhausted.

If I can get this to work, I'd do the same for clients which support RFC 
2563 (auto-configure option), which also allows the server to return 
yiaddr 0.0.0.0.

Any clues appreciated. If Kea doesn't support this use case, maybe I 
need to cobble together something custom for this.

Thanks in advance,

Brian.

-------- 8< --------

{
"Dhcp4": {
     "interfaces-config": {
         "interfaces": [ "enp6s0" ]
     },

     "control-socket": {
         "socket-type": "unix",
         "socket-name": "/tmp/kea4-ctrl-socket"
     },

     "lease-database": {
         "type": "memfile",
         "lfc-interval": 3600
     },

     "renew-timer": 900,
     "rebind-timer": 1800,
     "valid-lifetime": 3600,

     "subnet4": [
         {
             // Subnet identifier should be unique for each subnet.
             "id": 1,

             // Subnet binds to dummy interface address (10.12.65.1)
             "subnet": "10.12.65.0/24",
             "authoritative": true,

             // Dummy pool - still needs to be big enough for all unique 
clients
             "pools": [
                 {
                     // Only give OFFERs to devices which support RFC 8925
                     "pool": "10.12.65.2 - 10.12.65.254",
                     "client-class": "rfc8925"
                 }
             ],

             // 
https://kea.readthedocs.io/en/latest/arm/dhcp4-srv.html#dhcp4-std-options-list
             "option-data": [
                 {
                     // RFC 8925: option 108
                     // (Note that client does not *send* this option, 
but includes it in
                     // the requested parameters list)
                     "name": "v6-only-preferred",
                     "data": "0"
                 },
                 {
                     // RFC 2563: option 116 (0 = DoNotAutoConfigure)
                     "name": "auto-config",
                     "data": "0"
                 }
             ],

             // TODO: How can I return yiaddr 0.0.0.0 in the OFFER?
             // TODO: If client supports RFC 2563 then also offer yiaddr 
0.0.0.0 with DoNotAutoConfigure
             "reservations": [
                 //{
                 //    "flex-id": "'any'",
                 //    "ip-address": "0.0.0.0"
                 //}
             ]
         }
     ],

     "client-classes": [
         {
             "name": "rfc8925",
             // We need to test whether option 108 is in the client's 
parameter request list (option 55).
             // That's not the same as "option[108].exists"
             // 
https://kea.readthedocs.io/en/latest/arm/classify.html#using-expressions-in-classification
             "test": "substring(option[55].hex, 0, 1) == 0x6c or 
substring(option[55].hex, 1, 1) == 0x6c or substring(option[55].hex, 2, 
1) == 0x6c or substring(option[55].hex, 3, 1) == 0x6c or 
substring(option[55].hex, 4, 1) == 0x6c or substring(option[55].hex, 5, 
1) == 0x6c or substring(option[55].hex, 6, 1) == 0x6c or 
substring(option[55].hex, 7, 1) == 0x6c or substring(option[55].hex, 8, 
1) == 0x6c or substring(option[55].hex, 9, 1) == 0x6c or 
substring(option[55].hex, 10, 1) == 0x6c or substring(option[55].hex, 
11, 1) == 0x6c or substring(option[55].hex, 12, 1) == 0x6c"
         },
     ],

     "loggers": [
     {
         "name": "kea-dhcp4",
         "output_options": [
             {
                 "output": "stdout",
                 "pattern": "%-5p %m\n",
             }
         ],
         "severity": "DEBUG",
         "debuglevel": 0
     }
   ]
}
}



More information about the Kea-users mailing list