Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Dec 2013 14:36:44 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r259551 - in user/ae/inet6/sys: kern sys
Message-ID:  <201312181436.rBIEajVG030760@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Dec 18 14:36:44 2013
New Revision: 259551
URL: http://svnweb.freebsd.org/changeset/base/259551

Log:
  Use struct sockaddr_in6 to keep IPv6 addresses in jail code.
  
  Since IPv6 LLAs use zone indexes in addition to the struct in6_addr,
  we couldn't use these addresses in jails (actually we could use them,
  but LLAs from different zones were the same for jail).
  The JAIL_API_VERSION now is 3. And the kernel will reject IPv6
  addresses, if they are passed from userland in old format.
  All prison_xxx_ip6() functions were changed to take struct sockaddr_in6
  instead of in6_addr. One new function prison_check_in6() added, it takes
  struct in6_addr and zone index.
  In some places the const qualifier was added.

Modified:
  user/ae/inet6/sys/kern/kern_jail.c
  user/ae/inet6/sys/sys/jail.h

Modified: user/ae/inet6/sys/kern/kern_jail.c
==============================================================================
--- user/ae/inet6/sys/kern/kern_jail.c	Wed Dec 18 12:53:48 2013	(r259550)
+++ user/ae/inet6/sys/kern/kern_jail.c	Wed Dec 18 14:36:44 2013	(r259551)
@@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$");
 #include <ddb/ddb.h>
 #ifdef INET6
 #include <netinet6/in6_var.h>
+#include <netinet6/scope6_var.h>
 #endif /* INET6 */
 #endif /* DDB */
 
@@ -139,8 +140,11 @@ static int _prison_check_ip4(const struc
 static int prison_restrict_ip4(struct prison *pr, struct in_addr *newip4);
 #endif
 #ifdef INET6
-static int _prison_check_ip6(struct prison *pr, struct in6_addr *ia6);
-static int prison_restrict_ip6(struct prison *pr, struct in6_addr *newip6);
+static int _prison_check_ip6(struct prison *, const struct sockaddr_in6 *);
+static int prison_restrict_ip6(struct prison *, struct sockaddr_in6 *);
+#define	SA6_ARE_ADDR_EQUAL(a, b)	\
+    (IN6_ARE_ADDR_EQUAL(&(a)->sin6_addr, &(b)->sin6_addr) && \
+	(a)->sin6_scope_id == (b)->sin6_scope_id)
 #endif
 
 /* Flags for prison_deref */
@@ -268,17 +272,25 @@ qcmp_v4(const void *ip1, const void *ip2
 static int
 qcmp_v6(const void *ip1, const void *ip2)
 {
-	const struct in6_addr *ia6a, *ia6b;
+	const struct sockaddr_in6 *ip6a, *ip6b;
 	int i, rc;
 
-	ia6a = (const struct in6_addr *)ip1;
-	ia6b = (const struct in6_addr *)ip2;
+	ip6a = (const struct sockaddr_in6 *)ip1;
+	ip6b = (const struct sockaddr_in6 *)ip2;
 
 	rc = 0;
 	for (i = 0; rc == 0 && i < sizeof(struct in6_addr); i++) {
-		if (ia6a->s6_addr[i] > ia6b->s6_addr[i])
+		if (ip6a->sin6_addr.s6_addr[i] >
+		    ip6b->sin6_addr.s6_addr[i])
 			rc = 1;
-		else if (ia6a->s6_addr[i] < ia6b->s6_addr[i])
+		else if (ip6a->sin6_addr.s6_addr[i] <
+		    ip6b->sin6_addr.s6_addr[i])
+			rc = -1;
+	}
+	if (rc == 0) {
+		if (ip6a->sin6_scope_id > ip6b->sin6_scope_id)
+			rc = 1;
+		else if (ip6a->sin6_scope_id < ip6b->sin6_scope_id)
 			rc = -1;
 	}
 	return (rc);
@@ -327,6 +339,7 @@ sys_jail(struct thread *td, struct jail_
 
 	case 2:	/* JAIL_API_VERSION */
 		/* FreeBSD multi-IPv4/IPv6,noIP jails. */
+	case 3:	/* in6_addr -> sockaddr_in6 */
 		error = copyin(uap->jail, &j, sizeof(struct jail));
 		if (error)
 			return (error);
@@ -358,7 +371,7 @@ kern_jail(struct thread *td, struct jail
 	struct in_addr *u_ip4;
 #endif
 #ifdef INET6
-	struct in6_addr *u_ip6;
+	struct sockaddr_in6 *u_ip6;
 #endif
 	size_t tmplen;
 	int error, enforce_statfs, fi;
@@ -403,9 +416,16 @@ kern_jail(struct thread *td, struct jail
 		return (EINVAL);
 #endif
 #ifdef INET6
+	/*
+	 * We don't support the old way, when the list of IPv6 addresses
+	 * is specified via struct in6_addr.
+	 * XXX: in some case we can (i.e. until LLA isn't used).
+	 */
+	if (j->version < 3)
+		return (EINVAL);
 	if (j->ip6s > jail_max_af_ips)
 		return (EINVAL);
-	tmplen += j->ip6s * sizeof(struct in6_addr);
+	tmplen += j->ip6s * sizeof(struct sockaddr_in6);
 #else
 	if (j->ip6s > 0)
 		return (EINVAL);
@@ -418,9 +438,9 @@ kern_jail(struct thread *td, struct jail
 #endif
 #ifdef INET6
 #ifdef INET
-	u_ip6 = (struct in6_addr *)(u_ip4 + ip4s);
+	u_ip6 = (struct sockaddr_in6 *)(u_ip4 + ip4s);
 #else
-	u_ip6 = (struct in6_addr *)(u_name + MAXHOSTNAMELEN);
+	u_ip6 = (struct sockaddr_in6 *)(u_name + MAXHOSTNAMELEN);
 #endif
 #endif
 	optiov[opt.uio_iovcnt].iov_base = "path";
@@ -480,7 +500,7 @@ kern_jail(struct thread *td, struct jail
 	optiov[opt.uio_iovcnt].iov_len = sizeof("ip6.addr");
 	opt.uio_iovcnt++;
 	optiov[opt.uio_iovcnt].iov_base = u_ip6;
-	optiov[opt.uio_iovcnt].iov_len = j->ip6s * sizeof(struct in6_addr);
+	optiov[opt.uio_iovcnt].iov_len = j->ip6s * sizeof(struct sockaddr_in6);
 	error = copyin(j->ip6, u_ip6, optiov[opt.uio_iovcnt].iov_len);
 	if (error) {
 		free(u_path, M_TEMP);
@@ -529,7 +549,7 @@ kern_jail_set(struct thread *td, struct 
 	struct in_addr *ip4;
 #endif
 #ifdef INET6
-	struct in6_addr *ip6;
+	struct sockaddr_in6 *ip6;
 #endif
 	struct vfsopt *opt;
 	struct vfsoptlist *opts;
@@ -881,14 +901,21 @@ kern_jail_set(struct thread *td, struct 
 			if (ip6s > 1)
 				qsort(ip6 + 1, ip6s - 1, sizeof(*ip6), qcmp_v6);
 			for (ii = 0; ii < ip6s; ii++) {
-				if (IN6_IS_ADDR_UNSPECIFIED(&ip6[ii])) {
+				if (IN6_IS_ADDR_UNSPECIFIED(&ip6[ii].sin6_addr)) {
 					error = EINVAL;
 					goto done_free;
 				}
-				if ((ii+1) < ip6s &&
-				    (IN6_ARE_ADDR_EQUAL(&ip6[0], &ip6[ii+1]) ||
-				     IN6_ARE_ADDR_EQUAL(&ip6[ii], &ip6[ii+1])))
-				{
+				if (ip6[ii].sin6_family != AF_INET6 ||
+				    ip6[ii].sin6_len != sizeof(*ip6) ||
+				    sa6_checkzone(&ip6[ii]) != 0) {
+					error = EINVAL;
+					goto done_free;
+				}
+				if ((ii + 1) < ip6s && (
+				    SA6_ARE_ADDR_EQUAL(&ip6[0],
+					&ip6[ii + 1]) ||
+				    SA6_ARE_ADDR_EQUAL(&ip6[ii],
+					&ip6[ii + 1]))) {
 					error = EINVAL;
 					goto done_free;
 				}
@@ -1272,8 +1299,8 @@ kern_jail_set(struct thread *td, struct 
 				if (ppr->pr_ip6 != NULL) {
 					pr->pr_ip6s = ppr->pr_ip6s;
 					pr->pr_ip6 = malloc(pr->pr_ip6s *
-					    sizeof(struct in6_addr), M_PRISON,
-					    M_WAITOK);
+					    sizeof(struct sockaddr_in6),
+					    M_PRISON, M_WAITOK);
 					bcopy(ppr->pr_ip6, pr->pr_ip6,
 					    pr->pr_ip6s * sizeof(*pr->pr_ip6));
 				}
@@ -1465,7 +1492,7 @@ kern_jail_set(struct thread *td, struct 
 			 * subset of the parent's list.
 			 */
 			for (ij = 0; ij < ppr->pr_ip6s; ij++)
-				if (IN6_ARE_ADDR_EQUAL(&ip6[0],
+				if (SA6_ARE_ADDR_EQUAL(&ip6[0],
 				    &ppr->pr_ip6[ij]))
 					break;
 			if (ij == ppr->pr_ip6s) {
@@ -1474,11 +1501,11 @@ kern_jail_set(struct thread *td, struct 
 			}
 			if (ip6s > 1) {
 				for (ii = ij = 1; ii < ip6s; ii++) {
-					if (IN6_ARE_ADDR_EQUAL(&ip6[ii],
-					     &ppr->pr_ip6[0]))
+					if (SA6_ARE_ADDR_EQUAL(&ip6[ii],
+					    &ppr->pr_ip6[0]))
 						continue;
 					for (; ij < ppr->pr_ip6s; ij++)
-						if (IN6_ARE_ADDR_EQUAL(
+						if (SA6_ARE_ADDR_EQUAL(
 						    &ip6[ii], &ppr->pr_ip6[ij]))
 							break;
 					if (ij == ppr->pr_ip6s)
@@ -2989,7 +3016,7 @@ prison_check_ip4(const struct ucred *cre
 
 #ifdef INET6
 static int
-prison_restrict_ip6(struct prison *pr, struct in6_addr *newip6)
+prison_restrict_ip6(struct prison *pr, struct sockaddr_in6 *newip6)
 {
 	int ii, ij, used;
 	struct prison *ppr;
@@ -3031,7 +3058,7 @@ prison_restrict_ip6(struct prison *pr, s
 	} else if (pr->pr_ip6s > 0) {
 		/* Remove addresses that aren't in the parent. */
 		for (ij = 0; ij < ppr->pr_ip6s; ij++)
-			if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0],
+			if (SA6_ARE_ADDR_EQUAL(&pr->pr_ip6[0],
 			    &ppr->pr_ip6[ij]))
 				break;
 		if (ij < ppr->pr_ip6s)
@@ -3042,12 +3069,12 @@ prison_restrict_ip6(struct prison *pr, s
 			ii = 0;
 		}
 		for (ij = 1; ii < pr->pr_ip6s; ) {
-			if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[ii],
+			if (SA6_ARE_ADDR_EQUAL(&pr->pr_ip6[ii],
 			    &ppr->pr_ip6[0])) {
 				ii++;
 				continue;
 			}
-			switch (ij >= ppr->pr_ip4s ? -1 :
+			switch (ij >= ppr->pr_ip6s ? -1 :
 				qcmp_v6(&pr->pr_ip6[ii], &ppr->pr_ip6[ij])) {
 			case -1:
 				bcopy(pr->pr_ip6 + ii + 1, pr->pr_ip6 + ii,
@@ -3072,6 +3099,16 @@ prison_restrict_ip6(struct prison *pr, s
 }
 
 /*
+ * Copy only significant fields of struct sockaddr_in6.
+ */
+static void
+prison_copy_ip6(const struct sockaddr_in6 *src, struct sockaddr_in6 *dst)
+{
+
+	dst->sin6_addr = src->sin6_addr;
+	dst->sin6_scope_id = src->sin6_scope_id;
+}
+/*
  * Pass back primary IPv6 address for this jail.
  *
  * If not restricted return success but do not alter the address.  Caller has
@@ -3080,7 +3117,7 @@ prison_restrict_ip6(struct prison *pr, s
  * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
  */
 int
-prison_get_ip6(struct ucred *cred, struct in6_addr *ia6)
+prison_get_ip6(struct ucred *cred, struct sockaddr_in6 *ia6)
 {
 	struct prison *pr;
 
@@ -3100,7 +3137,7 @@ prison_get_ip6(struct ucred *cred, struc
 		return (EAFNOSUPPORT);
 	}
 
-	bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
+	prison_copy_ip6(&pr->pr_ip6[0], ia6);
 	mtx_unlock(&pr->pr_mtx);
 	return (0);
 }
@@ -3113,10 +3150,10 @@ prison_get_ip6(struct ucred *cred, struc
  * Return EAFNOSUPPORT, in case this jail does not allow IPv6.
  */
 int
-prison_saddrsel_ip6(struct ucred *cred, struct in6_addr *ia6)
+prison_saddrsel_ip6(struct ucred *cred, struct sockaddr_in6 *ia6)
 {
+	struct sockaddr_in6 addr;
 	struct prison *pr;
-	struct in6_addr lia6;
 	int error;
 
 	KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
@@ -3129,14 +3166,14 @@ prison_saddrsel_ip6(struct ucred *cred, 
 	if (pr->pr_flags & PR_IP6_SADDRSEL)
 		return (1);
 
-	lia6 = in6addr_any;
-	error = prison_get_ip6(cred, &lia6);
+	addr = sa6_any;
+	error = prison_get_ip6(cred, &addr);
 	if (error)
 		return (error);
-	if (IN6_IS_ADDR_UNSPECIFIED(&lia6))
+	if (IN6_IS_ADDR_UNSPECIFIED(&addr.sin6_addr))
 		return (1);
 
-	bcopy(&lia6, ia6, sizeof(struct in6_addr));
+	prison_copy_ip6(&addr, ia6);
 	return (0);
 }
 
@@ -3176,7 +3213,7 @@ prison_equal_ip6(struct prison *pr1, str
  * doesn't allow IPv6.
  */
 int
-prison_local_ip6(struct ucred *cred, struct in6_addr *ia6, int v6only)
+prison_local_ip6(struct ucred *cred, struct sockaddr_in6 *ia6, int v6only)
 {
 	struct prison *pr;
 	int error;
@@ -3197,19 +3234,19 @@ prison_local_ip6(struct ucred *cred, str
 		return (EAFNOSUPPORT);
 	}
 
-	if (IN6_IS_ADDR_LOOPBACK(ia6)) {
-		bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
+	if (IN6_IS_ADDR_LOOPBACK(&ia6->sin6_addr)) {
+		prison_copy_ip6(&pr->pr_ip6[0], ia6);
 		mtx_unlock(&pr->pr_mtx);
 		return (0);
 	}
 
-	if (IN6_IS_ADDR_UNSPECIFIED(ia6)) {
+	if (IN6_IS_ADDR_UNSPECIFIED(&ia6->sin6_addr)) {
 		/*
 		 * In case there is only 1 IPv6 address, and v6only is true,
 		 * then bind directly.
 		 */
 		if (v6only != 0 && pr->pr_ip6s == 1)
-			bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
+			prison_copy_ip6(&pr->pr_ip6[0], ia6);
 		mtx_unlock(&pr->pr_mtx);
 		return (0);
 	}
@@ -3225,7 +3262,7 @@ prison_local_ip6(struct ucred *cred, str
  * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
  */
 int
-prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
+prison_remote_ip6(struct ucred *cred, struct sockaddr_in6 *ia6)
 {
 	struct prison *pr;
 
@@ -3245,8 +3282,8 @@ prison_remote_ip6(struct ucred *cred, st
 		return (EAFNOSUPPORT);
 	}
 
-	if (IN6_IS_ADDR_LOOPBACK(ia6)) {
-		bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
+	if (IN6_IS_ADDR_LOOPBACK(&ia6->sin6_addr)) {
+		prison_copy_ip6(&pr->pr_ip6[0], ia6);
 		mtx_unlock(&pr->pr_mtx);
 		return (0);
 	}
@@ -3266,14 +3303,14 @@ prison_remote_ip6(struct ucred *cred, st
  * doesn't allow IPv6.
  */
 static int
-_prison_check_ip6(struct prison *pr, struct in6_addr *ia6)
+_prison_check_ip6(struct prison *pr, const struct sockaddr_in6 *ia6)
 {
 	int i, a, z, d;
 
 	/*
 	 * Check the primary IP.
 	 */
-	if (IN6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], ia6))
+	if (SA6_ARE_ADDR_EQUAL(&pr->pr_ip6[0], ia6))
 		return (0);
 
 	/*
@@ -3296,7 +3333,7 @@ _prison_check_ip6(struct prison *pr, str
 }
 
 int
-prison_check_ip6(struct ucred *cred, struct in6_addr *ia6)
+prison_check_ip6(struct ucred *cred, const struct sockaddr_in6 *ia6)
 {
 	struct prison *pr;
 	int error;
@@ -3321,6 +3358,20 @@ prison_check_ip6(struct ucred *cred, str
 	mtx_unlock(&pr->pr_mtx);
 	return (error);
 }
+
+int
+prison_check_in6(struct ucred *cred, const struct in6_addr *ia6,
+    uint32_t zoneid)
+{
+	struct sockaddr_in6 addr;
+
+	/* XXX: do we need better initialization? */
+	addr.sin6_addr = *ia6;
+	if (IN6_IS_ADDR_LINKLOCAL(ia6))
+		addr.sin6_scope_id = zoneid;
+	return (prison_check_ip6(cred, &addr));
+}
+
 #endif
 
 /*
@@ -3388,13 +3439,10 @@ prison_check_af(struct ucred *cred, int 
  * the jail doesn't allow the address family.  IPv4 Address passed in in NBO.
  */
 int
-prison_if(struct ucred *cred, struct sockaddr *sa)
+prison_if(struct ucred *cred, const struct sockaddr *sa)
 {
 #ifdef INET
-	struct sockaddr_in *sai;
-#endif
-#ifdef INET6
-	struct sockaddr_in6 *sai6;
+	const struct sockaddr_in *sai;
 #endif
 	int error;
 
@@ -3411,14 +3459,14 @@ prison_if(struct ucred *cred, struct soc
 	{
 #ifdef INET
 	case AF_INET:
-		sai = (struct sockaddr_in *)sa;
+		sai = (const struct sockaddr_in *)sa;
 		error = prison_check_ip4(cred, &sai->sin_addr);
 		break;
 #endif
 #ifdef INET6
 	case AF_INET6:
-		sai6 = (struct sockaddr_in6 *)sa;
-		error = prison_check_ip6(cred, &sai6->sin6_addr);
+		error = prison_check_ip6(cred,
+		    (const struct sockaddr_in6 *)sa);
 		break;
 #endif
 	default:
@@ -4033,7 +4081,7 @@ sysctl_jail_list(SYSCTL_HANDLER_ARGS)
 	int ip4s = 0;
 #endif
 #ifdef INET6
-	struct in6_addr *ip6 = NULL;
+	struct sockaddr_in6 *ip6 = NULL;
 	int ip6s = 0;
 #endif
 	int descend, error;
@@ -4065,12 +4113,12 @@ sysctl_jail_list(SYSCTL_HANDLER_ARGS)
 			if (ip6s < cpr->pr_ip6s) {
 				ip6s = cpr->pr_ip6s;
 				mtx_unlock(&cpr->pr_mtx);
-				ip6 = realloc(ip6, ip6s *
-				    sizeof(struct in6_addr), M_TEMP, M_WAITOK);
+				ip6 = realloc(ip6, ip6s * sizeof(*ip6),
+				    M_TEMP, M_WAITOK);
 				goto again;
 			}
 			bcopy(cpr->pr_ip6, ip6,
-			    cpr->pr_ip6s * sizeof(struct in6_addr));
+			    cpr->pr_ip6s * sizeof(*ip6));
 		}
 #endif
 		if (cpr->pr_ref == 0) {
@@ -4106,7 +4154,7 @@ sysctl_jail_list(SYSCTL_HANDLER_ARGS)
 #ifdef INET6
 		if (xp->pr_ip6s > 0) {
 			error = SYSCTL_OUT(req, ip6,
-			    xp->pr_ip6s * sizeof(struct in6_addr));
+			    xp->pr_ip6s * sizeof(*ip6));
 			if (error)
 				break;
 		}
@@ -4364,8 +4412,8 @@ SYSCTL_JAIL_PARAM(_ip4, saddrsel, CTLTYP
 #ifdef INET6
 SYSCTL_JAIL_PARAM_SYS_NODE(ip6, CTLFLAG_RDTUN,
     "Jail IPv6 address virtualization");
-SYSCTL_JAIL_PARAM_STRUCT(_ip6, addr, CTLFLAG_RW, sizeof(struct in6_addr),
-    "S,in6_addr,a", "Jail IPv6 addresses");
+SYSCTL_JAIL_PARAM_STRUCT(_ip6, addr, CTLFLAG_RW, sizeof(struct sockaddr_in6),
+    "S,sockaddr_in6,a", "Jail IPv6 addresses");
 SYSCTL_JAIL_PARAM(_ip6, saddrsel, CTLTYPE_INT | CTLFLAG_RW,
     "B", "Do (not) use IPv6 source address selection rather than the "
     "primary jail IPv6 address.");
@@ -4630,9 +4678,10 @@ db_show_prison(struct prison *pr)
 #ifdef INET6
 	db_printf(" ip6s            = %d\n", pr->pr_ip6s);
 	for (ii = 0; ii < pr->pr_ip6s; ii++)
-		db_printf(" %s %s\n",
+		db_printf(" %s %s%%%d\n",
 		    ii == 0 ? "ip6.addr        =" : "                 ",
-		    ip6_sprintf(ip6buf, &pr->pr_ip6[ii]));
+		    ip6_sprintf(ip6buf, &pr->pr_ip6[ii].sin6_addr),
+		    pr->pr_ip6[ii].sin6_scope_id);
 #endif
 }
 

Modified: user/ae/inet6/sys/sys/jail.h
==============================================================================
--- user/ae/inet6/sys/sys/jail.h	Wed Dec 18 12:53:48 2013	(r259550)
+++ user/ae/inet6/sys/sys/jail.h	Wed Dec 18 14:36:44 2013	(r259551)
@@ -47,9 +47,9 @@ struct jail {
 	uint32_t	ip4s;
 	uint32_t	ip6s;
 	struct in_addr	*ip4;
-	struct in6_addr	*ip6;
+	struct sockaddr_in6 *ip6;
 };
-#define	JAIL_API_VERSION	2
+#define	JAIL_API_VERSION	3
 
 /*
  * For all xprison structs, always keep the pr_version an int and
@@ -81,7 +81,7 @@ struct xprison {
 	 * IPv4 and IPv6 addesses. Offsets are based numbers of addresses.
 	 */
 	struct in_addr	 pr_ip4[];
-	struct in6_addr	 pr_ip6[];
+	struct sockaddr_in6 pr_ip6[];
 #endif
 };
 #define	XPRISON_VERSION		3
@@ -168,7 +168,7 @@ struct prison {
 	int		 pr_ip4s;			/* (p) number of v4 IPs */
 	int		 pr_ip6s;			/* (p) number of v6 IPs */
 	struct in_addr	*pr_ip4;			/* (p) v4 IPs of jail */
-	struct in6_addr	*pr_ip6;			/* (p) v6 IPs of jail */
+	struct sockaddr_in6 *pr_ip6;			/* (p) v6 IPs of jail */
 	struct prison_racct *pr_prison_racct;		/* (c) racct jail proxy */
 	void		*pr_sparep[3];
 	int		 pr_childcount;			/* (a) number of child jails */
@@ -387,15 +387,18 @@ int prison_remote_ip4(struct ucred *cred
 int prison_check_ip4(const struct ucred *, const struct in_addr *);
 int prison_saddrsel_ip4(struct ucred *, struct in_addr *);
 #ifdef INET6
+struct in6_addr;
+struct sockaddr_in6;
 int prison_equal_ip6(struct prison *, struct prison *);
-int prison_get_ip6(struct ucred *, struct in6_addr *);
-int prison_local_ip6(struct ucred *, struct in6_addr *, int);
-int prison_remote_ip6(struct ucred *, struct in6_addr *);
-int prison_check_ip6(struct ucred *, struct in6_addr *);
-int prison_saddrsel_ip6(struct ucred *, struct in6_addr *);
+int prison_get_ip6(struct ucred *, struct sockaddr_in6 *);
+int prison_local_ip6(struct ucred *, struct sockaddr_in6 *, int);
+int prison_remote_ip6(struct ucred *, struct sockaddr_in6 *);
+int prison_check_ip6(struct ucred *, const struct sockaddr_in6 *);
+int prison_check_in6(struct ucred *, const struct in6_addr *, uint32_t);
+int prison_saddrsel_ip6(struct ucred *, struct sockaddr_in6 *);
 #endif
 int prison_check_af(struct ucred *cred, int af);
-int prison_if(struct ucred *cred, struct sockaddr *sa);
+int prison_if(struct ucred *cred, const struct sockaddr *sa);
 char *prison_name(struct prison *, struct prison *);
 int prison_priv_check(struct ucred *cred, int priv);
 int sysctl_jail_param(SYSCTL_HANDLER_ARGS);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312181436.rBIEajVG030760>