diff options
author | pjd <pjd@FreeBSD.org> | 2009-06-01 10:30:00 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2009-06-01 10:30:00 +0000 |
commit | 5243d2d206ac372ee679c11bde715a4a4f2f93fd (patch) | |
tree | ce73855429371a51ef92709203be008be66b6119 /sys/netinet6 | |
parent | eb2d64c1bdd4159506f34e57ff8df73c843b7500 (diff) | |
download | FreeBSD-src-5243d2d206ac372ee679c11bde715a4a4f2f93fd.zip FreeBSD-src-5243d2d206ac372ee679c11bde715a4a4f2f93fd.tar.gz |
- Rename IP_NONLOCALOK IP socket option to IP_BINDANY, to be more consistent
with OpenBSD (and BSD/OS originally). We can't easly do it SOL_SOCKET option
as there is no more space for more SOL_SOCKET options, but this option also
fits better as an IP socket option, it seems.
- Implement this functionality also for IPv6 and RAW IP sockets.
- Always compile it in (don't use additional kernel options).
- Remove sysctl to turn this functionality on and off.
- Introduce new privilege - PRIV_NETINET_BINDANY, which allows to use this
functionality (currently only unjail root can use it).
Discussed with: julian, adrian, jhb, rwatson, kmacy
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6.h | 2 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.c | 6 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 15 |
3 files changed, 21 insertions, 2 deletions
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 751569c..eadfc09 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -477,6 +477,8 @@ struct route_in6 { * the source address. */ +#define IPV6_BINDANY 64 /* bool: allow bind to any address */ + /* * The following option is private; do not use it from user applications. * It is deliberately defined to the same value as IP_MSFILTER. diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index e572712..800564c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -163,11 +163,13 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, if (so->so_options & SO_REUSEADDR) reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { - struct ifaddr *ia = NULL; + struct ifaddr *ia; sin6->sin6_port = 0; /* yech... */ - if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0) + if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == NULL && + (inp->inp_flags & INP_BINDANY) == 0) { return (EADDRNOTAVAIL); + } /* * XXX: bind to an anycast address might accidentally diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 8f2e632c..7f6aae4 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1405,6 +1405,14 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt) case IPV6_RECVTCLASS: case IPV6_V6ONLY: case IPV6_AUTOFLOWLABEL: + case IPV6_BINDANY: + if (optname == IPV6_BINDANY && td != NULL) { + error = priv_check(td, + PRIV_NETINET_BINDANY); + if (error) + break; + } + if (optlen != sizeof(int)) { error = EINVAL; break; @@ -1558,6 +1566,9 @@ do { \ OPTSET(IN6P_AUTOFLOWLABEL); break; + case IPV6_BINDANY: + OPTSET(INP_BINDANY); + break; } break; @@ -1831,6 +1842,10 @@ do { \ case IPV6_AUTOFLOWLABEL: optval = OPTBIT(IN6P_AUTOFLOWLABEL); break; + + case IPV6_BINDANY: + optval = OPTBIT(INP_BINDANY); + break; } if (error) break; |