summaryrefslogtreecommitdiffstats
path: root/sys/netinet/raw_ip.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2010-04-27 15:07:08 +0000
committerbz <bz@FreeBSD.org>2010-04-27 15:07:08 +0000
commitc7fd54ae5aaa23136f70d1bc2685cdc3e78a315e (patch)
tree6731359ad2e0abca2a9069fceaf27fda5207cba3 /sys/netinet/raw_ip.c
parente66b2bd00b8aeff7786ee941efdd1b5c067e459c (diff)
downloadFreeBSD-src-c7fd54ae5aaa23136f70d1bc2685cdc3e78a315e.zip
FreeBSD-src-c7fd54ae5aaa23136f70d1bc2685cdc3e78a315e.tar.gz
Enhance the historic behaviour of raw sockets and jails in a way
that we allow all possible jail IPs as source address rather than forcing the "primary". While IPv6 naturally has source address selection, for legacy IP we do not go through the pain in case IP_HDRINCL was not set. People should bind(2) for that. This will, for example, allow ping(|6) -S to work correctly for non-primary addresses. Reported by: (ten 211.ru) Tested by: (ten 211.ru) MFC after: 4 days
Diffstat (limited to 'sys/netinet/raw_ip.c')
-rw-r--r--sys/netinet/raw_ip.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 1db3774..0b77b5b 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -427,11 +427,24 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
ip->ip_p = inp->inp_ip_p;
ip->ip_len = m->m_pkthdr.len;
ip->ip_src = inp->inp_laddr;
- error = prison_get_ip4(inp->inp_cred, &ip->ip_src);
- if (error != 0) {
- INP_RUNLOCK(inp);
- m_freem(m);
- return (error);
+ if (jailed(inp->inp_cred)) {
+ /*
+ * prison_local_ip4() would be good enough but would
+ * let a source of INADDR_ANY pass, which we do not
+ * want to see from jails. We do not go through the
+ * pain of in_pcbladdr() for raw sockets.
+ */
+ if (ip->ip_src.s_addr == INADDR_ANY)
+ error = prison_get_ip4(inp->inp_cred,
+ &ip->ip_src);
+ else
+ error = prison_local_ip4(inp->inp_cred,
+ &ip->ip_src);
+ if (error != 0) {
+ INP_RUNLOCK(inp);
+ m_freem(m);
+ return (error);
+ }
}
ip->ip_dst.s_addr = dst;
ip->ip_ttl = inp->inp_ip_ttl;
OpenPOWER on IntegriCloud