summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorJamie Gritton <jamie@FreeBSD.org>2009-05-27 14:11:23 +0000
committerJamie Gritton <jamie@FreeBSD.org>2009-05-27 14:11:23 +0000
commit0304c7316344d7e2d1dee3aa0249724ec629e8ef (patch)
treeb7f782d79e61a1bd80655a068684cb0fd9f39922 /sys/netinet6
parentd76e4550e9fb13853fb9f80dc93e423949983d2c (diff)
Notes
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c11
-rw-r--r--sys/netinet6/in6_ifattach.c25
-rw-r--r--sys/netinet6/in6_pcb.c10
3 files changed, 31 insertions, 15 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 60d56a8ae8e7..921618e888a6 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -660,7 +660,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
struct in6_ifaddr *ia, int flags)
{
INIT_VNET_INET6(ifp->if_vnet);
- INIT_VPROCG(TD_TO_VPROCG(curthread)); /* XXX V_hostname needs this */
int error = 0, hostIsNew = 0, plen = -1;
struct in6_ifaddr *oia;
struct sockaddr_in6 dst6;
@@ -1017,7 +1016,6 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
/*
* join node information group address
*/
-#define hostnamelen strlen(V_hostname)
delay = 0;
if ((flags & IN6_IFAUPDATE_DADDELAY)) {
/*
@@ -1027,10 +1025,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
delay = arc4random() %
(MAX_RTR_SOLICITATION_DELAY * hz);
}
- mtx_lock(&hostname_mtx);
- if (in6_nigroup(ifp, V_hostname, hostnamelen,
- &mltaddr.sin6_addr) == 0) {
- mtx_unlock(&hostname_mtx);
+ if (in6_nigroup(ifp, NULL, -1, &mltaddr.sin6_addr) == 0) {
imm = in6_joingroup(ifp, &mltaddr.sin6_addr, &error,
delay); /* XXX jinmei */
if (!imm) {
@@ -1044,9 +1039,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
LIST_INSERT_HEAD(&ia->ia6_memberships,
imm, i6mm_chain);
}
- } else
- mtx_unlock(&hostname_mtx);
-#undef hostnamelen
+ }
/*
* join interface-local all-nodes address.
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 4738f9149637..c1f828ba253d 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -620,23 +620,44 @@ int
in6_nigroup(struct ifnet *ifp, const char *name, int namelen,
struct in6_addr *in6)
{
+ INIT_VPROCG(TD_TO_VPROCG(curthread)); /* XXX V_hostname needs this */
const char *p;
u_char *q;
MD5_CTX ctxt;
+ int use_hostname;
u_int8_t digest[16];
char l;
char n[64]; /* a single label must not exceed 63 chars */
- if (!namelen || !name)
+ /*
+ * If no name is given and namelen is -1,
+ * we try to do the hostname lookup ourselves.
+ */
+ if (!name && namelen == -1) {
+ use_hostname = 1;
+ mtx_lock(&hostname_mtx);
+ name = V_hostname;
+ namelen = strlen(name);
+ } else
+ use_hostname = 0;
+ if (!name || !namelen) {
+ if (use_hostname)
+ mtx_unlock(&hostname_mtx);
return -1;
+ }
p = name;
while (p && *p && *p != '.' && p - name < namelen)
p++;
- if (p - name > sizeof(n) - 1)
+ if (p == name || p - name > sizeof(n) - 1) {
+ if (use_hostname)
+ mtx_unlock(&hostname_mtx);
return -1; /* label too long */
+ }
l = p - name;
strncpy(n, name, l);
+ if (use_hostname)
+ mtx_unlock(&hostname_mtx);
n[(int)l] = '\0';
for (q = n; *q; q++) {
if ('A' <= *q && *q <= 'Z')
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index e446a059416f..e5727120c2c3 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -666,7 +666,8 @@ in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr,
inp->inp_lport == lport) {
/* Found. */
if (cred == NULL ||
- inp->inp_cred->cr_prison == cred->cr_prison)
+ prison_equal_ip6(cred->cr_prison,
+ inp->inp_cred->cr_prison))
return (inp);
}
}
@@ -698,7 +699,8 @@ in6_pcblookup_local(struct inpcbinfo *pcbinfo, struct in6_addr *laddr,
LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
wildcard = 0;
if (cred != NULL &&
- inp->inp_cred->cr_prison != cred->cr_prison)
+ !prison_equal_ip6(cred->cr_prison,
+ inp->inp_cred->cr_prison))
continue;
/* XXX inp locking */
if ((inp->inp_vflag & INP_IPV6) == 0)
@@ -838,7 +840,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
* the inp here, without any checks.
* Well unless both bound with SO_REUSEPORT?
*/
- if (jailed(inp->inp_cred))
+ if (prison_flag(inp->inp_cred, PR_IP6))
return (inp);
if (tmpinp == NULL)
tmpinp = inp;
@@ -878,7 +880,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
if (faith && (inp->inp_flags & INP_FAITH) == 0)
continue;
- injail = jailed(inp->inp_cred);
+ injail = prison_flag(inp->inp_cred, PR_IP6);
if (injail) {
if (prison_check_ip6(inp->inp_cred,
laddr) != 0)