summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2009-06-01 10:30:00 +0000
committerpjd <pjd@FreeBSD.org>2009-06-01 10:30:00 +0000
commit5243d2d206ac372ee679c11bde715a4a4f2f93fd (patch)
treece73855429371a51ef92709203be008be66b6119 /sys/netinet6
parenteb2d64c1bdd4159506f34e57ff8df73c843b7500 (diff)
downloadFreeBSD-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.h2
-rw-r--r--sys/netinet6/in6_pcb.c6
-rw-r--r--sys/netinet6/ip6_output.c15
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;
OpenPOWER on IntegriCloud