[Dnsmasq-discuss] [PATCH] --bind-dynamic and fast netlink changes

Simon Kelley simon at thekelleys.org.uk
Thu Feb 25 00:19:44 UTC 2021


On 18/02/2021 11:56, Petr Menšík wrote:
> Hi Simon and others,
> 
> I have started checking behaviour of dnsmasq on fast netlink changes,
> reported originally on RHEL7 bug[1]. Found commit 1627d577[2] helps a
> lot on RHEL 7, which is already in current version. But for some reason,
> even latest dnsmasq 2.84 does not pass my test[3] on RHEL8 (bug #1927973
> [4]).
> 
> The core of the test is repeating few times this:
> one_retry() {
> 	local MAX=254
> 	local DOWN_DELAY=0
> 	for X in `seq 1 $MAX`; do
> 		ifconfig eth0:${X} 100.123.1.${X} netmask 255.255.255.0
> 		#ip address add 100.123.1.${X} dev eth0 label eth0:${X}
> 	done && sleep $DOWN_DELAY && for X in `seq 1 $MAX`; do
> 		ifconfig eth0:${X} down
> 		#ip address del 100.123.1.${X} dev eth0 label eth0:${X}
> 	done
> }
> 
> Then checking dnsmasq stops listening on them again.
> 
> I found by analysing strace of test, it re-reads current addresses
> innecessary often. It enqueues re-reading every time multicast netlink
> arrives. That means a lot of CPU cycles, when it just sends newaddress()
> event request every time. It seems to me, just once per multicast
> messages row is enough. It needs to know just current state to run
> newaddress() just last time.
> 
> I have tested my patches with my test and it helps, works also on RHEL8.
> I think it takes a lot less netlink reading without affecting accuracy.
> Patches 1 and 2 are fixing things. Patches 3 and 4 are just attempt to
> optimize speed of netlink handling a bit. Changed netlink_multicast to
> read in a row, until EAGAIN appears. Should help to drain netlink socket
> faster, avoiding ENOBUFFS.

I need to stare at this for a bit longer, but it looks as if it's on the
right lines.

One thing to consider: the actions following a NEWROUTE event are to
resend a DNS packet when the first DNS packet triggers a modem
dial-on-demand. Modems doing dial-on-demand is pretty quaint, and
something that could probably be removed without inconveniencing anyone
in the 2020s.



> 
> I think it should handle errors better in create_listeners. If tcp fails
> to bind on address, just UDP received would listen. Problem is
> create_bound_listeners does not know it is incomplete, it would be fixed
> only by deletion of interface address and re-adding it again. But that
> is related but different problem, I have no fix candidate yet.

In newaddress, check for this error after calling
create_bound_listeners() and loop back to enumerate_interfaces() until
it gets a clean run? It that in danger of looping forever?

The nasty logic that inhibits interface enumeration more than once per
select loop in enumerate_interfaces() would have to be finessed.


> 
> When it fails, lines similar to this appear in log:
> failed to create listening socket for 100.123.1.250: Cannot assign
> requested address
> 
> What do you think? Have you ever got dnsmasq --bind-dynamic into state,
> where it required restart to continue serving correct addresses?

I'm not aware of that happening, but I suspect I don't do the sort of
things which make it happen.



Cheers,

Simon.

> 
> Also opinions welcome.
> 
> Thanks,
> Petr
> 
> 1. https://bugzilla.redhat.com/show_bug.cgi?id=1887649
> 2.
> http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=1627d577af03cdf747285e79fa747b6aaae8033f
> 3.
> https://github.com/InfrastructureServices/dnsmasq-tests/tree/master/Regression/netlink-interface-fast-changes
> 4. https://bugzilla.redhat.com/show_bug.cgi?id=1927973
> 
> 
> _______________________________________________
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
> 




More information about the Dnsmasq-discuss mailing list