Bug 6970 - getifaddrs() issues on AIX
getifaddrs() issues on AIX
Status: NEW
Product: Samba 4.1 and newer
Classification: Unclassified
Component: Other
unspecified
PPC AIX
: P3 normal
: ---
Assigned To: Stefan Metzmacher
Samba QA Contact
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-12-05 13:04 UTC by Miguel Sanders (mail account dead)
Modified: 2017-11-27 15:12 UTC (History)
9 users (show)

See Also:
fumiyas: review+


Attachments
Patch for bug 6970 (3.85 KB, patch)
2009-12-05 13:04 UTC, Miguel Sanders (mail account dead)
no flags Details
Patch for bug 6970 (II) (3.61 KB, patch)
2009-12-06 14:17 UTC, Miguel Sanders (mail account dead)
no flags Details
Patch for master and v3-6-test (4.07 KB, patch)
2012-12-18 15:25 UTC, SATOH Fumiyasu
no flags Details
proposed patch for master (4.58 KB, text/plain)
2017-06-13 12:30 UTC, Björn Jacke
no flags Details
proposed patch for master (4.59 KB, patch)
2017-11-26 09:06 UTC, SATOH Fumiyasu
no flags Details
Combined patch (4.32 KB, patch)
2017-11-27 11:43 UTC, Douglas Leeder
no flags Details
Combined patch (4.57 KB, patch)
2017-11-27 15:12 UTC, Douglas Leeder
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Miguel Sanders (mail account dead) 2009-12-05 13:04:18 UTC
Hi Samba team

I would like to report that the "interfaces / bind interfaces only" features of Samba do not function on AIX.
There are two problematic situations:
(1) Assume interfaces en1 and en2 have an IP address whereas en0 does not.
(Simplified) netstat output on AIX would show something like:
# netstat -in
Name  Mtu   Network     Address           
en1   9000  link#2      22.f1.30.0.10.6        
en1   9000  10.226.32   10.226.32.222          
en2   1500  link#3      22.f1.30.0.10.8        
en2   1500  10.226.33   10.226.33.222          
en0*  65390 link#4      22.f1.30.0.10.4        
lo0   16896 link#1                             
lo0   16896 127         127.0.0.1              
lo0   16896 ::1                                

If there is no interfaces entry in smb.conf (f.e. interfaces = en1 or interfaces = en2), smbd will simply not start.
The problem lies in the rep_getifaddrs function in lib/replace/getifaddrs.c
AIX, unlike Linux, also returns info on the layer 2 HW address of the adapter in the ifconf struct (as can be observed from the output above).
As a result, one should only call the SIOCGIFADDR ioctl if the sin_family is AF_INET. 

(2) Assume interface en2 has IP aliases.
(Simplified) netstat output on AIX would show something like:
# netstat -in
Name  Mtu   Network     Address           
en2   1500  link#3      22.f1.30.0.10.8        
en2   1500  10.226.33   10.226.33.222          
en2   1500  139.53.231  139.53.231.201         
en2   1500  139.53.231  139.53.231.107         
lo0   16896 link#1                             
lo0   16896 127         127.0.0.1              
lo0   16896 ::1                                

The IP aliases cannot be used in the interfaces entry in smb.conf.
The problem also lies in the rep_getifaddrs function in lib/replace/getifaddrs.c
AIX, unlike Linux, does not create a new interface for each IP alias.
As a result, the SIOCGIFADDR ioctl does not return any IP aliases of the network interface, only the base IP address.

The attached patch fixes both problems and was tested successfully on AIX 5.3 / 6.1
Comment 1 Miguel Sanders (mail account dead) 2009-12-05 13:04:59 UTC
Created attachment 5057 [details]
Patch for bug 6970
Comment 2 Stefan Metzmacher 2009-12-06 04:51:41 UTC
I think that patch is wrong,
on linux getifaddrs gives more than just AF_INET interfaces.

configure gives this:

checking for iface getifaddrs... lo         AF=17 
eth0       AF=17 
wmaster0   AF=17 
wlan0      AF=17 
tun48      <no address>
tun76      <no address>
tun24      <no address>
vmnet9     AF=17 
lo         IP=127.0.0.1 NETMASK=255.0.0.0
wlan0      IP=172.30.12.19 NETMASK=255.255.255.0
tun48      IP=172.30.48.9 NETMASK=255.255.255.255
tun76      IP=172.30.76.9 NETMASK=255.255.255.255
tun24      IP=192.168.24.16 NETMASK=255.255.255.255
tun24      IP=192.168.71.113 NETMASK=255.255.255.255
vmnet9     IP=172.31.9.1 NETMASK=255.255.255.0
lo         IP=::1 NETMASK=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
wlan0      IP=fe80::221:6aff:fe70:1a7e NETMASK=ffff:ffff:ffff:ffff::
yes

what does it give on you system?

I assume this problem could also happen on non aix system
and we need to fix this at a higher level.

metze
Comment 3 Miguel Sanders (mail account dead) 2009-12-06 05:04:55 UTC
My comments on the Linux environment might be wrong, since I only have a limited Linux config at home. (I'm an AIX guy, not a Linux guy)
Nevertheless, the code for AIX was wrong and the supplied patch fixes those problems. The patch is certainly not wrong.

Since there is a separate function rep_getifaddrs especially for AIX (#ifdef HAVE_IFACE_AIX), I don't see why you cannot apply this patch.
Comment 4 Miguel Sanders (mail account dead) 2009-12-06 05:39:02 UTC
Metze

I forgot the answer to your questions.
The configure test shows the following:

checking for iface getifaddrs... no
checking for iface AIX... en1        IP=10.226.32.222
en1        IP=10.226.32.222
en2        IP=10.226.33.222
en2        IP=10.226.33.222
en2        IP=10.226.33.222
en2        IP=10.226.33.222
en2        IP=10.226.33.222
en2        IP=10.226.33.222
en2        IP=10.226.33.222
lo0        IP=127.0.0.1
lo0        IP=127.0.0.1
lo0        IP=127.0.0.1
yes

As you can see, IP aliases are not shows.
The output is exactly what I expected since the lib/replace/test/getifaddrs.c code relies on the actual code in lib/replace/getifaddrs.c.
Moreover, if I don't detach en0 (see example above) before running configure, HAVE_IFACE_AIX will not even be set since the actual code freaks out (running SIOCGIFADDR ioctl on sin_family = AF_LINK is not allowed).

After applying the patch, the configure test shows
checking for iface AIX... en1        IP=10.226.32.222
en2        IP=10.226.33.222
en2        IP=139.53.231.201
en2        IP=139.53.231.107
en2        IP=139.53.231.106
en2        IP=139.53.231.105
en2        IP=139.53.231.103
lo0        IP=127.0.0.1
yes

Which is much better

Cheers!  
Comment 5 Stefan Metzmacher 2009-12-06 06:02:17 UTC
Thanks!

However I see two problems

-	ifc.ifc_len = sizeof(buff);
-	ifc.ifc_buf = buff;
+	if (ioctl(fd, SIOCGSIZIFCONF, &size) != 0) {
+		return -1;
+	}
+
+	ifc.ifc_len = size;
+	ifc.ifc_buf = (struct ifreq *)buff;

we have to make sure size <= sizeof(buff)

And we should not remove ipv6 addresses.
http://ipv6int.net/systems/index.html says AIX 6.1 has support
for ipv6.

I'm also wondering why configure doesn't output any NETMASK= strings...

Comment 6 Miguel Sanders (mail account dead) 2009-12-06 06:55:30 UTC
Hi Metze

Yes, you're totally right about those two remarks.
In my test code, I made a dynamic memory allocation of size "size".
But since I don't know how the Samba project handles malloc calls (either direct or via wrappers), I left that out. (Some projects have their own wrappers around malloc and so on).

You're also right about IPV6.
I'll have a look at that.
Comment 7 Miguel Sanders (mail account dead) 2009-12-06 07:11:27 UTC
I'll have a look at this tonight, OK?

Cheers!
Comment 8 Miguel Sanders (mail account dead) 2009-12-06 14:17:35 UTC
Created attachment 5060 [details]
Patch for bug 6970 (II)
Comment 9 Miguel Sanders (mail account dead) 2009-12-06 14:18:52 UTC
Hi Metze

Following your remarks, I made some modifications to the patch.
I also tested it with IPV6 addresses.

Could you have a look?

Cheers!

Miguel
Comment 10 Miguel Sanders (mail account dead) 2009-12-06 14:25:36 UTC
Metze

The reason why there is no NETMASK output in configure appears to be caused by the implementation of the SIOCGIFNETMASK ioctl.
Apparently, this ioctl does not set sin_family!
I will contact some L3 people I know and ask them if this is by design or a bug.
If it's by design, I will open an additional bug in order to rectify lib/replace/test/getifaddrs.c . 

Do you agree on this?
Comment 11 Miguel Sanders (mail account dead) 2009-12-11 03:44:35 UTC
Hi Metze

I received feedback from my L3 contact and apparently the SIOCGIFNETMASK ioctl does not set sin_family. This is by design.
Have you had a chance to look at the patch for getifaddrs() ?

Cheers

Miguel
Comment 12 Miguel Sanders (mail account dead) 2009-12-23 12:53:13 UTC
Hi

Has anyone already reviewed the updated patch?
I really would like to get this in the next release...

Thanks for your help!
Comment 13 SATOH Fumiyasu 2012-09-20 12:13:23 UTC
I'm facing the same problem on AIX 6.1 WPAR (workload partition).

The nmbd on AIX WPAR found network interfaces that are configured
for global AIX (outer AIX WPAR), then tried and failed to open it.

Network interfaces on global AIX:

  # netstat -in@
  WPAR       Name  Mtu   Network     Address            Ipkts Ierrs    Opkts Oerrs  Coll
  Global     en0   1500  link#2      X.X.X.X.X.X      38260829     0 21399190     0     0
  Global     en0   1500  10          10.0.0.32        38260829     0 21399190     0     0
  build-aix6 en0   1500  10          10.0.0.92        23323258     0 20962573     0     0
  Global     lo0   16896 link#1                         512311     0   512310     0     0
  Global     lo0   16896 127         127.0.0.1          512311     0   512310     0     0
  Global     lo0   16896 ::1%1                          512311     0   512310     0     0

The IP address 10.0.0.32 is for global AIX (Global).
The IP address 10.0.0.92 is for AIX WPAR (build-aix6).

Network interfaces on AIX WPAR (buidl-aix6):

  # netstat -in@
  netstat: illegal option -- @
  usage: netstat [-Aaon] [-f address_family]
                [-inrsu] [-f address_family] [-p proto]
                [-n] [-I interface] [interval]
  # netstat -in
  Name  Mtu   Network     Address           Ipkts Ierrs    Opkts Oerrs  Coll
  en0   1500  link#2      X.X.X.X.X.X      23323239     0 20962559     0     0
  en0   1500  10          10.0.0.92        23323239     0 20962559     0     0
  lo0   16896 link#1                         412501     0   293745     0     0
  lo0   16896 127         127.0.0.1          412501     0   293745     0     0
  lo0   16896 ::1%1                          412501     0   293745     0     0

log.nmbd by nmbd on AIX WPAR (buidl-aix6):

  [2012/09/20 20:44:02,  0] nmbd/nmbd.c:857(main)
    nmbd version 3.5.13-40.1.aix6 started.
    Copyright Andrew Tridgell and the Samba Team 1992-2010
  [2012/09/20 20:44:02.565112,  0] lib/util_sock.c:881(open_socket_in)
    bind failed on port 137 socket_addr = 10.0.0.32.
    Error = Can't assign requested address
  [2012/09/20 20:44:02.565672,  0] nmbd/nmbd_subnetdb.c:112(make_subnet)
    nmbd_subnetdb:make_subnet()
      Failed to open nmb socket on interface 10.0.0.32 for port 137.  Error was Can't assign requested address

I've tried the Miguel Sanders's patch and confirmed this bug was gone.
Comment 14 SATOH Fumiyasu 2012-09-20 12:26:34 UTC
(In reply to comment #13)
> I've tried the Miguel Sanders's patch and confirmed this bug was gone.

I've confirmed with Samba 3.5.13 + Miguel Sanders's patch +
Rolf Anders' patch at:

  http://lists.samba.org/archive/samba-technical/2011-August/078954.html

Without Rolf Anders' patch, I met the following log:

  [2012/09/20 21:17:28,  0] nmbd/nmbd.c:857(main)
    nmbd version 3.5.13-40.1.aix6 started.
    Copyright Andrew Tridgell and the Samba Team 1992-2010
  [2012/09/20 21:17:28.458766,  0] lib/interface.c:519(load_interfaces)
    ERROR: Could not determine network interfaces, you must use a interfaces config line

See also Bug 8984 - AIX 6.1 nmbd Failed to open nmb bcast socket on interface.
Comment 15 SATOH Fumiyasu 2012-09-20 15:33:32 UTC
The smbd without patches found wrong IP address 10.0.0.32
(this is for global AIX) and does not find IPv6 address ::1.

  # /path/to/smbd-without-patches -DFS -d3
  ...
  added interface en0 ip=10.0.0.32 bcast=10.0.255.255 netmask=
  added interface lo0 ip=127.0.0.1 bcast=127.255.255.255 netmask=
  add_interface: not adding duplicate interface 127.0.0.1
  loaded services
  Becoming a daemon.

The smbd with patches found correct IP address 10.0.0.92
(this is for AIX WPAR) and IPv6 address ::1.

  # /path/to/smbd-with-patches -DFS -d3
  ...
  added interface lo0 ip=::1 bcast=ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff netmask=
  added interface en0 ip=10.0.0.92 bcast=10.0.255.255 netmask=
  added interface lo0 ip=127.0.0.1 bcast=127.255.255.255 netmask=
  loaded services
  Becoming a daemon.

I don't know why "netmask=" is null string in both cases...
Comment 16 SATOH Fumiyasu 2012-09-21 03:24:42 UTC
Another getifaddrs() implementation for AIX 5.3 (and later?) found at:

  getifaddrs for AIX
  http://lists.samba.org/archive/samba-technical/2009-February/063079.html
Comment 17 SATOH Fumiyasu 2012-12-18 15:25:26 UTC
Created attachment 8357 [details]
Patch for master and v3-6-test

I've created a patch by git format-patch.
Comment 18 Björn Jacke 2017-06-13 12:30:31 UTC
Created attachment 13270 [details]
proposed patch for master

can you please test this patch? If you test this successfully we can check this in finally.
Comment 19 SATOH Fumiyasu 2017-11-26 08:05:57 UTC
(In reply to Björn Jacke from comment #18)

Thank you! I've try to build Samba 4.7.3 with your patch:

../lib/replace/getifaddrs.c: In function 'rep_getifaddrs':
../lib/replace/getifaddrs.c:302:3: error: 'ret' undeclared (first use in this function)
   ret = -1;
   ^
../lib/replace/getifaddrs.c:302:3: note: each undeclared identifier is reported only once for each function it appears in
../lib/replace/getifaddrs.c:342:4: warning: passing argument 1 of 'sockaddr_dup' discards 'const' qualifier from pointer target type [enabled by default]
    curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr);
    ^
../lib/replace/getifaddrs.c:59:25: note: expected 'struct sockaddr *' but argument is of type 'const struct sockaddr *'
 static struct sockaddr *sockaddr_dup(struct sockaddr *sa)
                         ^
../lib/replace/getifaddrs.c:364:4: warning: passing argument 1 of 'sockaddr_dup' discards 'const' qualifier from pointer target type [enabled by default]
    curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr);
    ^
../lib/replace/getifaddrs.c:59:25: note: expected 'struct sockaddr *' but argument is of type 'const struct sockaddr *'
 static struct sockaddr *sockaddr_dup(struct sockaddr *sa)
                         ^
../lib/replace/getifaddrs.c:395:3: warning: passing argument 1 of 'freeaddrinfo' from incompatible pointer type [enabled by default]
   freeaddrinfo(firstif);
   ^
In file included from ../lib/replace/system/network.h:54:0,
                 from ../lib/replace/getifaddrs.c:27:
/usr/include/netdb.h:178:17: note: expected 'struct addrinfo *' but argument is of type 'struct ifaddrs *'
 void            freeaddrinfo(struct addrinfo *);    /* RFC2133 */
                 ^
Comment 20 SATOH Fumiyasu 2017-11-26 09:06:13 UTC
Created attachment 13811 [details]
proposed patch for master

I've revised your patch and tested with Samba 4.7.3 with the patch on AIX 7.2.
It seems no problem as the following!!

# ifconfig -a
ifconfig -a
en0: flags=1e084863,c0<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,CHECKSUM_OFFLOAD(ACTIVE),LARGESEND,CHAIN>
        inet 10.0.0.94 netmask 0xffff0000 broadcast 10.0.255.255
         tcp_sendspace 131072 tcp_recvspace 65536 rfc1323 0
lo0: flags=e08084b,c0<UP,BROADCAST,LOOPBACK,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT,LARGESEND,CHAIN>
        inet 127.0.0.1 netmask 0xff000000 broadcast 127.255.255.255
        inet6 ::1%1/0
         tcp_sendspace 131072 tcp_recvspace 131072 rfc1323 1
# /usr/local/bin/testparm -s
Load smb config files from /usr/local/samba-4.7.3/etc/smb.conf
rlimit_max: increasing rlimit_max (2000) to minimum Windows limit (16384)
Loaded services file OK.
Server role: ROLE_STANDALONE

# Global parameters
[global]
        idmap config * : backend = tdb
# /usr/local/samba-4.7.3/bin/nmbd -DFS -d3
nmbd version 4.7.3 started.
Copyright Andrew Tridgell and the Samba Team 1992-2017
lp_load_ex: refreshing parameters
Initialising global parameters
rlimit_max: increasing rlimit_max (2000) to minimum Windows limit (16384)
Processing section "[global]"
Registered MSG_REQ_POOL_USAGE
Registered MSG_REQ_DMALLOC_MARK and LOG_CHANGED
lp_load_ex: refreshing parameters
Initialising global parameters
rlimit_max: increasing rlimit_max (2000) to minimum Windows limit (16384)
Processing section "[global]"
services not loaded
Becoming a daemon.
Opening sockets 137
open_sockets: Broadcast sockets opened.
added interface lo0 ip=::1 bcast= netmask=
added interface en0 ip=10.0.0.94 bcast=10.0.255.255 netmask=
added interface lo0 ip=127.0.0.1 bcast=127.255.255.255 netmask=
create_subnets: Ignoring loopback interface.
making subnet name:10.0.0.94 Broadcast address:10.0.255.255 Subnet mask:255.255.0.16
create_subnets: ignoring non IPv4 interface.
making subnet name:UNICAST_SUBNET Broadcast address:0.0.0.0 Subnet mask:0.0.0.0
making subnet name:REMOTE_BROADCAST_SUBNET Broadcast address:0.0.0.0 Subnet mask:0.0.0.0
load_lmhosts_file: Can't open lmhosts file /usr/local/samba-4.7.3/etc/lmhosts. Error was No such file or directory
Loaded hosts file /usr/local/samba-4.7.3/etc/lmhosts
add_name_to_subnet: Added netbios name *<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet 10.0.0.94
add_name_to_subnet: Added netbios name *<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet 10.0.0.94
add_name_to_subnet: Added netbios name __SAMBA__<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet 10.0.0.94
add_name_to_subnet: Added netbios name __SAMBA__<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet 10.0.0.94
create_server_on_workgroup: Created server entry BUILD-AIX72 of type 40819a03 (Samba 4.7.3) on workgroup WORKGROUP.
initiate_myworkgroup_startup: Added server name entry BUILD-AIX72 on subnet 10.0.0.94
add_name_to_subnet: Added netbios name *<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name *<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name __SAMBA__<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name __SAMBA__<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name BUILD-AIX72<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name BUILD-AIX72<03> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name BUILD-AIX72<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name WORKGROUP<00> with first IP 10.0.0.94 ttl=0 nb_flags=80 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name WORKGROUP<1e> with first IP 10.0.0.94 ttl=0 nb_flags=80 to subnet UNICAST_SUBNET
add_name_to_subnet: Added netbios name *<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet REMOTE_BROADCAST_SUBNET
add_name_to_subnet: Added netbios name *<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet REMOTE_BROADCAST_SUBNET
add_name_to_subnet: Added netbios name __SAMBA__<20> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet REMOTE_BROADCAST_SUBNET
add_name_to_subnet: Added netbios name __SAMBA__<00> with first IP 10.0.0.94 ttl=0 nb_flags= 0 to subnet REMOTE_BROADCAST_SUBNET
STATUS=daemon 'nmbd' finished starting up and ready to serve connections
send_host_announcement: type 819a03 for host BUILD-AIX72 on subnet 10.0.0.94 for workgroup WORKGROUP
added interface lo0 ip=::1 bcast= netmask=
added interface en0 ip=10.0.0.94 bcast=10.0.255.255 netmask=
added interface lo0 ip=127.0.0.1 bcast=127.255.255.239 netmask=
reload_interfaces: ignoring non IPv4 interface.
reload_interfaces: Ignoring loopback interface 127.0.0.1
reload_interfaces: ignoring non IPv4 interface.
Comment 21 Douglas Leeder 2017-11-27 11:43:12 UTC
Created attachment 13814 [details]
Combined patch

Hi,

I've been trying to solve this problem using the patches provided and have a patch that fixes it for me.

It combined the patch from this bug and bug 8984 - https://bugzilla.samba.org/show_bug.cgi?id=8984#c9

I had to do similar changes to define ret and correct const-ness.

Technically it's a patch against 4.6.6 but the file hasn't change (except white-space between 4.6.6 and master).

I have an AIX 7.2 system with IPv6 where the sit0 getting SIOCGIFNETMASK returns errno=EADDRNOTAVAIL, so I ignored that and the code works.
Comment 22 Björn Jacke 2017-11-27 14:17:33 UTC
please don't us ifdef(AIX) like constructs. If there is a reason why something should be enabled in the code or not then there should usually be a check for that. Just the name of the platform might leave the same problem open on other platforms or break that platform in with a different release.
Comment 23 Douglas Leeder 2017-11-27 15:12:53 UTC
Created attachment 13815 [details]
Combined patch

Ok, I've changed it to always calloc enough space, that should solve the problem in a safer way - since AIX strips NULL bytes from the end when calculating the length.