-
Notifications
You must be signed in to change notification settings - Fork 577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
findif
doesn't properly detect interfaces
#52
Comments
I hit the same problem with a 3.x kernel on SUSE, and I can confirm that your patch fixes it. I would suggest a small tweak as follows, so it doesn't modify *best_netmask until after the procfile is successfully opened, and removes the nested 'if' (although, really, this is probably mostly academic...) diff --git a/tools/findif.c b/tools/findif.c
index 72452f7..b911ae2 100644
--- a/tools/findif.c
+++ b/tools/findif.c
@@ -198,6 +198,7 @@ SearchUsingProcRoute (char *address, struct in_addr *in
, PROCROUTE);
rc = OCF_ERR_GENERIC; goto out;
}
+ *best_netmask = 0;
while (fgets(buf, sizeof(buf), routefd) != NULL) {
if (sscanf(buf, "%[^\t]\t%lx%lx%lx%lx%lx%lx%lx"
, interface, &dest, &gw, &flags, &refcnt, &use
@@ -208,7 +209,7 @@ SearchUsingProcRoute (char *address, struct in_addr *in
rc = OCF_ERR_GENERIC; goto out;
}
if ( (in->s_addr&mask) == (in_addr_t)(dest&mask)
- && metric < best_metric) {
+ && metric <= best_metric && mask >= *best_netmask) {
best_metric = metric;
*best_netmask = mask;
strncpy(best_if, interface, best_iflen); |
Good work! Many thanks. Tim, can you please apply your version of the patch. |
Done: de3074c |
Just want to thank you, guys, for the quick resolution of the problem and commit! Nice team work :) |
See ClusterLabs#52 for discussion. Thanks to Timur Bakeyev for original diagnosis and patch. Signed-off-by: Tim Serong <tserong@suse.com>
I was a bit surprised that despite description of IPAddr[2] just and IP address never was enough for configuration and I had to supply both netmask and NIC name to get things working properly. But a lot of tutorials said that's how it should be done, so I accepted it until got a configuration where NICs had different names on two machines in a cluster and migration of IP didn't work.
I never could get such a configuration to work in Debian squeeze, but on Debian lenny it worked. After digging into the code and configuration it came out that on lenny 'cat /proc/net/route' gives routing table like:
When on squeeze the order of the information is different:
Basically, with the newer kernels the default route 0/0 comes as a first line and matches any supplied IP address/mask combination, giving interface of the default route as a match. It may be suitable result in some cases, but just incidently. Also, the code tries to take route metric into account and rejects anything that is below already found one, although 'man route' says:
Metric The 'distance' to the target (usually counted in hops). It is not used by recent kernels, but may be needed by routing daemons.
And in most cases it's value 0 for all the entries. But current code just picks the first matching line with such a metric rejecting any following better routes with the same metric (0).
So, my proposal is to make this check more relaxed in the first place and consider equal metrics suitable as well. Still in this case default route possibly would be the best choice, so I add additional constrain - pick most specific matching route(with narrower netmask).
Here is the small patch:
Testing both on lenny and squeeze gave consistent right results :)
Still, this and current code doesn't take into account, for example case when 'reject' route present in the routing table:
If desired IP happen to fall into the rejected range an '*' interface returned as a result. Well, it can easily be verified in the code, as well as on a higher level.
Regards,
Timur.
The text was updated successfully, but these errors were encountered: