Roy's Blog

A Hacker's musings on Code | Tech | Life

dhcpcd now manages routing in a sane manner across multiple interfaces on BSD. It always has on Linux due to it's route metric support, but as BSD doesn't have this it's a little more tricky. We basically maintain a routing table built from all the DHCP options per interface and change it accordingly. As such, dhcpcd now prefers wired over wireless and changes back to wireless if the cable is removed (assuming both on the same subnet) and this works really well :DIt's now starting to look quite stable and all the features in dhcpcd-4 appear to be working still so I've released an experimental version to get some feedback. BSD users can get a rc.d script here.So, lets have it!

Continue reading...

Metrics

tech

You tag something with a metric. The same somethings with a lower metric take precedence over the same somethings with a higher metric.

dhcpcd has been able to apply metrics to routes on Linux so that we can prefer to route packets over wired instead of wireless. dhcpcd-git is now able to distinguish wired from wireless and can make a metric accordingly.

But how do we teach configuration files about this? Well, dhcpcd-git has an environment variable sent to each script telling it about the preferred order of interfaces (based on carrier, if we have a lease or not and metric). This works well, and we can now prefer wired nameservers over wireless ones in /etc/resolv.conf. Well, we can at least put them first in the list.

Whilst doing this, it struct me that resolvconf has no means of preferring configurations other than a static interface-order file. This is not good for automatic foo! So openresolv now understands the -m <metric> option and the IF_METRIC environment variable so it can tag resolv.confs by priority. If no metric is specified, it takes priority. If >1 interface on the same metric then we take lexical order.

Continue reading...

Event Loops

tech

Well, support for multiple instances in dhcpcd is coming along nicely, but I've had to pretty much re-write the entire state handling code. The existing code was wait for data or timeout. Then drop into case statements depending on if we timed out and what our current state is.The new code is now based around an event loop, where we register functions to call when we get data or a time has passed. We pass all functions an interface structure, which now holds the state and options (previously the state held the interface and options). This handling lease expiry times a lot easier - we simply set 3 timeout per interface (renew, rebind, expire) and let the event loop do its job.This new structure should also make it easier to add DHCPv6 support - it should just be a matter of registering new functions to listen on IPv6 connected sockets and then selecting a DHCPv6 server over a DHCPv4 one. As this new code is quite a big change and I think I'm making life easier for DHCPv6 later on we'll probably skip 4.1 and move straight onto 5.0, adding DHCPv6 support in 5.1.Hopefully I'll commit this to git over the next few days - I just need to ensure that cable link events correctly move to the right state. The only thing that will be known to be broken in the first commit to git will probably be rebinding the interface on the command line as I'll probably need to move to using a control socket. We'll need one for dynamically adding and removing interfaces anyway.

Continue reading...