Problem using bz's multi-IP/IPv6/No-IP Jail Patch (7-STABLE)

Jamie Gritton jamie at FreeBSD.org
Thu Mar 12 14:38:48 PDT 2009


I wrote:
> Kage wrote:
> 
>> Encountering more issues now.  Binding just an IPv6 address to a jail
>> shows up in jls -v, but when I run ifconfig -a in the jail, I get an
>> error I've never encountered, and doesn't show up on any Google
>> search:
>>
>> [root at nub:/etc] jls -v
>>    JID  Hostname                      Path
>>         Name                          State
>>         CPUSetID
>>         IP Address(es)
>>      9  jail.template.tld             /usr/jails/TEMPLATE
>>                                       ALIVE
>>         10
>>         2610:150:c248:dead:beef:c0ff:eec0:deaa
>>
>> [root at jail:/] ifconfig -a
>> ifconfig: socket(family 2,SOCK_DGRAM): Protocol not supported
> 
> Recent patches reject sockets in jails that have no addresses in the
> socket's family.  So if you jail has no IPv6 addresses, you won't be
> able to create any IPv6 sockets.  Likewise your case: if that jail has
> no IPv4 addresses, then it's an IPv4-less jail, and IPv4 sockets won't
> work (Protocol not supported).  For actual network connections, this
> makes sense: you won't be able to bind or connect with this socket, as
> there are no IPv4 addresses in the system.
> 
> But ifconfig is a different situation.  It just needs a socket of some
> sort, and AF_INET has always worked, because any networked system always
> has IPv4 support.  But in an IPv4-less system (which an IPv4-less jail
> not acts like), this default isn't useful.  Something will need to be
> fixed.  I'm not sure if that something is ifconfig or the kernel.

Here's a patch for ifconfig.  It allows "ifconfig -a" and a few other
similar informative ifconfig options to run inside an IPv4-less jail
(of course trying to set anything still fails).  Outside of a jail, you
should see no change.  Apply it inside your /usr/src tree, and install
it both in the root system (under /sbin) and in your jails
(/usr/jails/TEMPLATE or wherever).  Just in case I broke something, keep
a copy of the old one :-).  But I've tested it on my own system so I
don't expect anything to be broken.

This is under review and I expect to be able to commit it to Current
shortly, then MFC it a week or so after that.  If you have any trouble
with it, feel free to ask me - I'm the one who broke ifconfig in the
first place.

- Jamie
-------------- next part --------------
Index: sbin/ifconfig/ifgroup.c
===================================================================
--- isbin/ifconfig/fgroup.c	(revision 189318)
+++ sbin/ifconfig/ifgroup.c	(working copy)
@@ -131,9 +131,9 @@
 	int			 len, cnt = 0;
 	int			 s;
 
-	s = socket(AF_INET, SOCK_DGRAM, 0);
+	s = socket(AF_LOCAL, SOCK_DGRAM, 0);
 	if (s == -1)
-		err(1, "socket(AF_INET,SOCK_DGRAM)");
+		err(1, "socket(AF_LOCAL,SOCK_DGRAM)");
 	bzero(&ifgr, sizeof(ifgr));
 	strlcpy(ifgr.ifgr_name, groupname, sizeof(ifgr.ifgr_name));
 	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
Index: sbin/ifconfig/ifclone.c
===================================================================
--- sbin/ifconfig/ifclone.c	(revision 189318)
+++ sbin/ifconfig/ifclone.c	(working copy)
@@ -54,9 +54,9 @@
 	int idx;
 	int s;
 
-	s = socket(AF_INET, SOCK_DGRAM, 0);
+	s = socket(AF_LOCAL, SOCK_DGRAM, 0);
 	if (s == -1)
-		err(1, "socket(AF_INET,SOCK_DGRAM)");
+		err(1, "socket(AF_LOCAL,SOCK_DGRAM)");
 
 	memset(&ifcr, 0, sizeof(ifcr));
 
Index: sbin/ifconfig/ifconfig.c
===================================================================
--- sbin/ifconfig/ifconfig.c	(revision 189318)
+++ sbin/ifconfig/ifconfig.c	(working copy)
@@ -441,22 +441,23 @@
 	DEF_CMD("ifdstaddr", 0, setifdstaddr);
 
 static int
-ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *afp)
+ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp)
 {
-	const struct afswtch *nafp;
+	const struct afswtch *afp, *nafp;
 	const struct cmd *p;
 	struct callback *cb;
 	int s;
 
 	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
+	afp = uafp != NULL ? uafp : af_getbyname("inet");
 top:
-	if (afp == NULL)
-		afp = af_getbyname("inet");
 	ifr.ifr_addr.sa_family =
 		afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ?
-		AF_INET : afp->af_af;
+		AF_LOCAL : afp->af_af;
 
-	if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+	if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 &&
+	    (uafp != NULL || errno != EPROTONOSUPPORT ||
+	     (s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0))
 		err(1, "socket(family %u,SOCK_DGRAM", ifr.ifr_addr.sa_family);
 
 	while (argc > 0) {
@@ -803,11 +804,12 @@
 
 	if (afp == NULL) {
 		allfamilies = 1;
-		afp = af_getbyname("inet");
-	} else
+		ifr.ifr_addr.sa_family = AF_LOCAL;
+	} else {
 		allfamilies = 0;
-
-	ifr.ifr_addr.sa_family = afp->af_af == AF_LINK ? AF_INET : afp->af_af;
+		ifr.ifr_addr.sa_family =
+		    afp->af_af == AF_LINK ? AF_LOCAL : afp->af_af;
+	}
 	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
 
 	s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0);


More information about the freebsd-jail mailing list