Hi, Apologies for not joining that discussion earlier. Been busy with the parsers rewrite recently.
The shared network mechanism available in dhcpd (using one subnet and then switching to the next one once the first one is full) is not supported yet in Kea. For some cases we can use client classification and restrict access to subnets to selected class, but that will only get you so far. There's a good reason why we don't support this capability yet. That's because shared networks significantly alters the whole logic of the DHCP server. If it was simple to implement, we would have done that long time ago. The discussion below is pretty complex stuff. It is doable, but it's tricky. This is getting into some deep parts of how Kea operates, so apologies to people who don't expect this kind of stuff on kea-users. It would be probably better for kea-dev list, but this thread started gently and just escalated quickly... :) W dniu 22.12.2016 o 14:42, Igor Smitran pisze: > In order to solve this problem: > > Is one able to create something like: > > 1. create subnet4_select hook > Inside hook based on some conditions we set NEXT_STEP_DROP/SKIP > subnet will not be selected Using NEXT_STEP_SKIP here won't help at all. This will tell Kea to not select a subnet at all. In most cases the packet will be dropped as a result. There are some border cases when the packet processing could still continue (e.g. sending some global information in response to DHCPINFORM), but this will not give you anything in your case. Using NEXT_STEP_DROP is not supported in this hook. What you can do here is to set a different subnet. Kea will use whatever subnet the hook specified in subnet4 parameter. By default that's the subnet Kea selected in the first place. The tricky part is to decide which subnet to select out of those. There are couple possible ways to solve this problem. The idea to call pickAddress is one approach. It would do allocation in the subnet selection phase, but I don't think mixing the steps is avoidable. Another thing to consider here is to use statistics. You can retrieve subnet[id].assigned-addresses and compare it with subnet[id].total-addresses. If those match, then this subnet is full and you need to pick the next subnet. This is slightly oversimplified, as you should also take declined addresses into consideration. But let's forget about them for now. This statistics check is definitely much faster than attempt to pick a lease. > 2. create lease4_select hook > subnet is not selected yet, we use getCfgSubnets4()->getAll(); and now > we have all defined subnets > then we pick first subnet that matches relayip > we call Allocator and pickaddress. in case we don't get any address we > pick another subnet and repeat > in case we go through all subnets/pools and don't get any address we > decide to DROP packet because we don't have any free lease to handout This would almost work. But there's one problem with it. The subnet has already been selected at the time lease4_select is called. So the new lease will be created with the subnet_id of previously selected subnet. You can probably override it in a hook, but then the allocation engine would use whatever the subnet was originally selected to assign options. You could almost get away with it by specifying the same option values in all subnets, so it wouldn't matter. Except the router option... it has to match the actual subnet. Otherwise your clients won't know how to reach their default gateway. So the solution will likely need to be slightly more complex than that. You would select the subnet as you described, but you would do that in select4_subnet and depending on your decision, your hook would tell Kea to use that specific subnet. Now, to not repeat the costly allocation procedure twice, you can store the lease (or just the IP address selected) in hook context. Then in another hook installed on lease4_select, you'd retrieve that information from the context and tell Kea to use that lease. This should work for new clients, but there's another problem to solve: returning clients. The trick here is that returning clients will need to be assigned the same subnet as before. Fortunately, that's easy to do. When the subnet4_select is caled, query4 contains the source packet. You need to look at its ciaddr field. If this is set, that means the client already has an address. If it has one, you can select a subnet based on that. Sounds complicated? Well, did I mention there's a reason why it was not yet implemented? I wasn't making that up. > Some help from Kea developers would be very appreciated :) One day we will implement shared subnets in the Kea code. I (or any other Kea engineer) haven't done a proper design for this yet, but I have some ideas. Please treat them with a grain of salt. Design 1: Kea code currently checks that the pools really belong to the subnet in which they're defined. In non-shared subnet deployment, that's a very useful sanity check that catches misconfiguration. With shared subnets enabled, we could simply disable that check and allow pools to belong to different classes. Kea would select subnet normally and then start allocating from the next pool within this subnet once the first pool is fully allocated. There are places in the code that try to select subnet based on the IP address. Those would have to be augmented slightly. One thing to address here is how to assign different options (in particular routers option) to clients using different pools. We already have capability to assign different options for each IPv6 pool. Similar capability would have to be developed for IPv4. Design 2: Kea allows specifying subnet_id explicitly. It rejects a configuration that has duplicate subnet_ids. In this approach, we would allow those ids to be duplicate. When a duplicate is found, those would be treated as a shared subnet. This approach would require some sort of a connection between subnets. A pointer to shared_subnet structure that lists all the subnets perhaps? The allocation engine would have to be augmented to not give up when completed through the current subnet, but rather check if this subnet is part of a shared subnet. If it is, then hop to the next subnet and try to allocated somewhere from that. In any case, there are many tricky cases, like new clients coming in, returning clients renewing, having an address not used, but reserved for client A when client B comes in, sysadmin adding reservation for client A while the address is being used by client B etc. Ok, that's it. These are my thoughts on the matter. If you were hoping for a simple trick to make it magically work - I'm sorry, I'm not aware of any. Finally, there are couple of non-technical things that may or may not be useful here. We're currently working on 1.2, which is fully scoped and it's rather unlikely we would add any new features to it. However, the discussion for 1.3 is yet to be started. I presume you'd like shared subnet to be implemented in 1.3, but the same is true for lots of other missing features. Here's the caveat. Kea is open source, but we need to fund its development somehow. Therefore we tend to pick the features that give the highest chance of getting support or development contracts signed. As such, saying "I'd like shared subnets in 1.3" is nice, but "I'm willing to sign a support contract with you if you develop shared subnets" is better. That is generally true for any not yet developed feature. Hope that helps, Tomek Mrugalski ISC _______________________________________________ Kea-users mailing list [email protected] https://lists.isc.org/mailman/listinfo/kea-users
