1621687045.aoetools-36-11-g4a3ee18.aoe-sancheck-refine-interface-probing.patch 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. Subject: Aoe-sancheck: Refine interface probing
  2. Origin: aoetools-36-11-g4a3ee18 <https://github.com/OpenAoE/aoetools/commit/aoetools-36-11-g4a3ee18>
  3. Upstream-Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
  4. Date: Sat May 22 14:37:25 2021 +0200
  5. Forwarded: not-needed (cherry-picked)
  6. There are two issues in the ethlist function in aoe-sancheck.c:
  7. First it skips all network interfaces that do not start with "eth". This
  8. is a problem these days where people use different naming schemes like the
  9. so-called predictable interface names as mandated by udev/systemd.
  10. Second it only probes for interfaces with an interface number of up
  11. to 15. At least in current Linux, that number can take huge values and
  12. those interfaces will be ignored completely.
  13. About the first: Probe all interfaces (but lo) that support the ARP
  14. protocol, assuming that is a fair indicator for ethernet support.
  15. About the second, use the if_nameindex function to get a list of all
  16. interfaces currently known to the kernel and operate on that one.
  17. --- a/aoe-sancheck.c
  18. +++ b/aoe-sancheck.c
  19. @@ -501,23 +501,38 @@
  20. int
  21. ethlist(char **ifs, int nifs)
  22. {
  23. - int i, s, n;
  24. + int s, n;
  25. struct ifreq ifr;
  26. + struct if_nameindex *if_ni, *i;
  27. s = socket(AF_INET, SOCK_STREAM, 0);
  28. if (s < 0)
  29. return 0;
  30. +
  31. + if_ni = if_nameindex();
  32. + if (if_ni == NULL)
  33. + return 0;
  34. +
  35. n = 0;
  36. - for (i=0; i<nifs; i++) {
  37. + for (i = if_ni; ! (i->if_index == 0 && i->if_name == NULL); i++) {
  38. memset(&ifr, 0, sizeof ifr);
  39. - ifr.ifr_ifindex = i;
  40. - if (ioctl(s, SIOCGIFNAME, &ifr) < 0)
  41. + ifr.ifr_ifindex = i->if_index;
  42. + strcpy(ifr.ifr_name, i->if_name);
  43. + // get interface flags
  44. + if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
  45. + continue;
  46. + // only use interfaces that use arp protocol
  47. + if (ifr.ifr_flags & IFF_NOARP)
  48. continue;
  49. - if (strncmp(ifr.ifr_name, "eth", 3))
  50. + // skip loopback interfaces
  51. + if (ifr.ifr_flags & IFF_LOOPBACK)
  52. continue;
  53. + if (n == nifs)
  54. + break;
  55. inserteth(ifs, nifs, ifr.ifr_name);
  56. n++;
  57. }
  58. + if_freenameindex(if_ni);
  59. close(s);
  60. return n;
  61. }