Re: DHCPDv6 in non-vnet jail

From: Goran Mekić <meka_at_tilda.center>
Date: Thu, 31 Mar 2022 18:03:36 UTC
On Wed, Mar 30, 2022 at 02:45:17PM +0200, Ronald Klop wrote:
> Hi,
> 
> First. I'm not an IPv6 expert. Got it running at home. Although with SLAAC, not DHCP yet.
> Another disclaimer is that I use VNET-jails nowadays.
> But I like to try and think along with you.
> 
> What surprises me is that your non-vnet jail does not have a LINKLOCAL fe80::: address. These addresses are used for configuration in the local network (AFAIK).
> And your routing table does not contain a line like this:
> ff02::/16                         ::1                           UGRS        lo0
> 
> So how is the ff02:: multicast routed in your network?
> 
> But the tcpdump shows that the multicast solicit message is received on the non-vnet dhcp-server so that seems to work:
> 18:02:51.229813 IP6 fe80::2a0:98ff:fe7d:cad.dhcpv6-client > ff02::1:2.dhcpv6-server: dhcp6 solicit
> I don't know if the dhcp-server program also sees this request coming in on its interface. Maybe extra logging can help there.
> 
> According to https://en.wikipedia.org/wiki/DHCPv6#Example the dhcp-server would reply with a link-local fe80:: address.
> "Server replies with an advertise from [fe80::0011:22ff:fe33:5566]:547 to [fe80::aabb:ccff:fedd:eeff]:546."
> But your dhcp-server does not have an fe80::.
> 
> So I'm wondering how that would work.
> 
> More questions than answers. But I hope it helps.
> 
> Regards,
> Ronald.

Hello,

It helps narrow down the search! I created a small lab and this is
jail.conf:

path           = "/usr/jails/${name}";
exec.start     = "/bin/sh /etc/rc";
exec.stop      = "/bin/sh /etc/rc.shutdown";
exec.clean;
mount.devfs;

dhcp {
  host.hostname    = dhcp.hal9000.meka.rs;
  host.domainname  = hal9000.meka.rs;
  ip4.addr         = 'bridge0|172.16.0.250';
  ip6.addr         = 'bridge0|fd10:6c79:8ae5:8b91::3';
  ip6.addr        += 'bridge0|fe80::dead:beef';
  enforce_statfs   = 1; 
  sysvshm          = new;
  sysvsem          = new;
  devfs_ruleset    = 7;
  allow.chflags;
  allow.mount.devfs;
  allow.mount.procfs;
  allow.mount;
  allow.mount.devfs;
  allow.mount.procfs;
  allow.mount.nullfs;
  allow.mount.tmpfs;
  allow.socket_af;
  allow.raw_sockets;
  persist;
}

client {
  $id              = 10;
  host.hostname    = client.hal9000.meka.rs;
  host.domainname  = hal9000.meka.rs;
  enforce_statfs   = 1; 
  sysvshm          = new;
  sysvsem          = new;
  devfs_ruleset    = 8;
  allow.chflags;
  allow.mount.devfs;
  allow.mount.procfs;
  allow.mount;
  allow.mount.devfs;
  allow.mount.procfs;
  allow.mount.nullfs;
  allow.mount.tmpfs;
  allow.socket_af;
  allow.raw_sockets;
  persist;

  vnet;
  vnet.interface   = "epair${id}b";

  exec.prestart    = "ifconfig epair${id} create up";
  exec.prestart   += "ifconfig epair${id}a up descr vnet-${name}";
  exec.prestart   += "ifconfig bridge0 addm epair${id}a up";

  exec.prestop     = "ifconfig epair${id}b -vnet ${name}";
  exec.poststop    = "ifconfig bridge00 deletem epair${id}a";
  exec.poststop   += "ifconfig epair${id}a destroy";
}


Note the "dead:beef" address. Even if I remove that line I get the same
output of ifconfig inside dhcp jail:

ifconfig
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:ae:c5:e1:31:d0
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
	groups: lo
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	description: re0
	ether 58:9c:fc:10:ff:90
	inet 172.16.0.250 netmask 0xffffffff broadcast 172.16.0.250
	inet6 fd10:6c79:8ae5:8b91::3 prefixlen 128
	id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
	maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
	root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
	member: epair10a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
	        ifmaxaddr 0 port 5 priority 128 path cost 2000
	groups: bridge
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
pflog0: flags=141<UP,RUNNING,PROMISC> metric 0 mtu 33160
	groups: pflog
epair10a: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
	description: vnet-client
	options=8<VLAN_MTU>
	ether 02:82:6f:d8:f0:0a
	groups: epair
	media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
	status: active
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>



And this is relevant portion of /etc/rc.conf:

cloned_interfaces="bridge0"
ifconfig_bridge0="inet 172.16.0.254 netmask 255.255.255.0 description re0"
ifconfig_bridge0_ipv6="inet6 -ifdisabled auto_linklocal fd10:6c79:8ae5:8b91::1"


The following is ifconfig on host
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
	ether bc:ae:c5:e1:31:d0
	inet6 fe80::beae:c5ff:fee1:31d0%re0 prefixlen 64 scopeid 0x1
	inet6 2001:470:1f1a:ae:beae:c5ff:fee1:31d0 prefixlen 64 autoconf
	inet 192.168.111.3 netmask 0xffffff00 broadcast 192.168.111.255
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
	options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
	inet6 ::1 prefixlen 128
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
	inet 127.0.0.1 netmask 0xff000000
	groups: lo
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	description: re0
	ether 58:9c:fc:10:ff:90
	inet 172.16.0.254 netmask 0xffffff00 broadcast 172.16.0.255
	inet 172.16.0.250 netmask 0xffffffff broadcast 172.16.0.250
	inet6 fe80::5a9c:fcff:fe10:ff90%bridge0 prefixlen 64 scopeid 0x3
	inet6 fd10:6c79:8ae5:8b91::1 prefixlen 64
	inet6 fd10:6c79:8ae5:8b91::3 prefixlen 128
	inet6 fe80::dead:beef%bridge0 prefixlen 128 scopeid 0x3
	id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
	maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
	root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
	member: epair10a flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
	        ifmaxaddr 0 port 5 priority 128 path cost 2000
	groups: bridge
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
pflog0: flags=141<UP,RUNNING,PROMISC> metric 0 mtu 33160
	groups: pflog
epair10a: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
	description: vnet-client
	options=8<VLAN_MTU>
	ether 02:82:6f:d8:f0:0a
	groups: epair
	media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
	status: active
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>


I can see "dead:beef" address until I stop the dhcp jail. I can also see
that auto_linklocal produced fe80 address (the first inet6 address) on
the host but not inside the jail.

Is there something I need to configure/start on the host or jail to have
link-local address inside non-vnet jail?

Regards,
meka