Description of problem: Setting socket option IP_FREEBIND with setsockopt() returns 0 (success). After this, one should be able to bind the socket to any IP address. This works with TCP sockets. With SCTP sockets, however, after setting IP_FREEBIND the set of IP addresses that the socket can be bound to is unchanged. Version-Release number of selected component (if applicable): kernel-2.6.9-1.648_EL How reproducible: Every time. Steps to Reproduce: 1. Pick an IP address that does _not_ exist in any of the host's interfaces. In this case I picked 172.21.94.188. 3. socket(PF_INET, SOCK_STREAM, 0x84 /* IPPROTO_??? */) = 3 4. setsockopt(3, SOL_IP, 0xf /* IP_??? */, [1], 4) = 0 5. bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("172.21.94.188")}, 16) = -1 EADDRNOTAVAIL (Cannot assign requested address) Actual results: In step 4, bind() returns -1 with EADDRNOTAVAIL. Expected results: Since IP_FREEBIND is set, bind() in step 4 should return 0 (success). Additional info: My net config (just in case): $ /sbin/ip a 1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:0b:db:81:c4:db brd ff:ff:ff:ff:ff:ff inet 172.21.94.189/22 brd 172.21.95.255 scope global eth0 inet6 fe80::20b:dbff:fe81:c4db/64 scope link valid_lft forever preferred_lft forever 3: sit0: <NOARP> mtu 1480 qdisc noop link/sit 0.0.0.0 brd 0.0.0.0 $ /sbin/ip r 172.21.92.0/22 dev eth0 proto kernel scope link src 172.21.94.189 169.254.0.0/16 dev eth0 scope link default via 172.21.92.1 dev eth0
These have now been reproduced under RHEL 4 RC by jere.
Created attachment 113921 [details] SCTP IP_FREEBIND patch The fix to this bug might be as trivial as - if (!sp->pf->bind_verify(sp, addr)) + if (!inet_sk(sk)->freebind && !sp->pf->bind_verify(sp, addr)) in sctp_do_bind(). It does get rid of the EADDRNOTAVAIL, but I'm not sure whether this is enough.
Created attachment 115140 [details] patch to enable IP_FREEBIND sockopt / ip_nonlocal_bind sysctl I've made this version of the patch which seems to be more in line with what the SCTP developers intended to do to support this. It also pulls in the ability to use the ip_nonlocal_bind sysctl. I've posted it upstream, and it passes all my tests here. Please give it a try and let me know if you concur.
Created attachment 115175 [details] updated version of FREEBIND patch This is an updated version of the previous patch, which more properly externalizes the ip_nonlocal_bind sysctl variable. It just got upstream acceptance, and its pretty straightforward to test (it passes my tests here just fine), so I'm going to post it internally here.
(struct sctp_opt *)sp->inet.freebind doesn't compile, since struct sctp_opt has no member named "inet". What am I doing wrong? By the way, if you do this in sctp_v4_available(), it'll work for IPv4 only, right? What about IPv6?
Upstream kernels pass a sctp_sock structure down to sctp_v4_available, as opposed to the RHEL kernel that still uses the sock_opt structure. The attached is the upstream patch. I'm working on a backport right now, but if you want you should just be able to modify the call path from sctp_bind down to sctp_v4_available to change the sctp_opt parameter to a sctp_sock parameter. You will also need to cast the sk ponter in sctp_bind appropriately and modify the bind_avail method in sctp/structs.h. As for IPv6, I ignored it as the IPv6 protocol itself appears to no support the nonlocal bind option. I suppose it could, but I'd prefer to implement that in a separate issue if you don't mind.
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on the solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHSA-2005-514.html