Allow explicitly assigned IPv6 loopback address to be used in jails

If a jail has an explicitly assigned IPv6 loopback address then allow it
to be used instead of remapping requests for the loopback adddress to the
first IPv6 address assigned to the jail.

This fixes issues where applications attempt to detect their bound port
where they requested a loopback address, which was available, but instead
the kernel remapped it to the jails first address.

This is the same fix applied to IPv4 fix by: r316313

Also:
* Correct the description of prison_check_ip6_locked to match the code.

MFC after:	2 weeks
Relnotes:	Yes
Sponsored by:	Multiplay
This commit is contained in:
smh 2017-03-31 09:10:05 +00:00
parent 6af6e1f918
commit 688581b7e7
2 changed files with 11 additions and 12 deletions

View File

@ -52,9 +52,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
20170331:
Binds and sends to the IPv4 loopback address (127.0.0.1) will now
Binds and sends to the loopback addresses, IPv6 and IPv4, will now
use any explicitly assigned loopback address available in the jail
instead of using the first assigned IPv4 address of the jail.
instead of using the first assigned address of the jail.
20170329:
The ctl.ko module no longer implements the iSCSI target frontend:

View File

@ -293,12 +293,6 @@ prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
return (EAFNOSUPPORT);
}
if (IN6_IS_ADDR_LOOPBACK(ia6)) {
bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
mtx_unlock(&pr->pr_mtx);
return (0);
}
if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
/*
* In case there is only 1 IPv6 address, and v6only is true,
@ -311,6 +305,11 @@ prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
}
error = prison_check_ip6_locked(pr, ia6);
if (error == EADDRNOTAVAIL && IN6_IS_ADDR_LOOPBACK(ia6)) {
bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
error = 0;
}
mtx_unlock(&pr->pr_mtx);
return (error);
}
@ -341,7 +340,8 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
return (EAFNOSUPPORT);
}
if (IN6_IS_ADDR_LOOPBACK(ia6)) {
if (IN6_IS_ADDR_LOOPBACK(ia6) &&
prison_check_ip6_locked(pr, ia6) == EADDRNOTAVAIL) {
bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
mtx_unlock(&pr->pr_mtx);
return (0);
@ -357,9 +357,8 @@ prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
/*
* Check if given address belongs to the jail referenced by cred/prison.
*
* Returns 0 if jail doesn't restrict IPv6 or if address belongs to jail,
* EADDRNOTAVAIL if the address doesn't belong, or EAFNOSUPPORT if the jail
* doesn't allow IPv6.
* Returns 0 if address belongs to jail,
* EADDRNOTAVAIL if the address doesn't belong to the jail.
*/
int
prison_check_ip6_locked(const struct prison *pr, const struct in6_addr *ia6)