freebsd labs

Configuring FreeBSD 9.1 as a Native IPv6 DHCP Client

Abstract

ISPs are now offering native IPv6 to their customers, which begs the question, “how do I configure my machine to use IPv6?” This blog post describes the steps to configure a FreeBSD 9.1 machine as an IPv6 DHCP client on the Comcast network.

Prerequisites

First, the machine you are configuring must have an interface on the Internet, it cannot be behind a firewall. This machine should be the firewall.

Second, disable any firewall rules. Really, I mean it. You can re-enable the rules once you have a working configuration, at which point any problems can be addressed by fixing the firewall rulesets. And for you firewall wizards out there who are not going to listen to this advice because you know better, I want to caution you that pf(4) IPv6 rulesets may not work as expected; you are better off disabling filters (or at least adopting a default-allow stance). It may save you several hours of pointless frustration.

Manual Procedure

In this example, the external interface (the one which will have the IPv6 address) is em3. First, let’s install the IPv6 DHCP client program:

sudo pkg_add -r dhcp6

Second, let’s create /usr/local/etc/dhcp6c.conf with the following contents:

interface em3 {
     send ia-pd 0;
     send ia-na 1;
};

id-assoc na 1 {
};

id-assoc pd {
  prefix-interface em0 {
    sla-id 1;
  };
};

Let’s run the client in the foreground to see if it can successfully acquire an IPv6 address (remember to substitute your interface name for em3):

sudo /usr/local/sbin/dhcp6c -fd em3

If you see a message client6_send: transmit failed: Network is unreachable, then hit ctrl-C to stop dhcp6, enable IPv6 and router advertisements on your interface, then start dhcp6 (again, substitute for em3):

sudo ifconfig em3 inet6 -ifdisabled accept_rtadv
sudo /usr/local/sbin/dhcp6c -fd em3
Sep/02/2013 18:09:28: dhcp6_ctl_authinit: failed to open /usr/local/etc/dhcp6cctlkey: No such file or directory
Sep/02/2013 18:09:28: client6_init: failed initialize control message authentication
Sep/02/2013 18:09:28: client6_init: skip opening control port
Sep/02/2013 18:09:28: add_ifprefix: invalid prefix length 64 + 16 + 64

Now, in a separate terminal session (because dhcp6c doesn’t exit once it acquires a lease), let’s use ifconfig to determine if we have acquired an IPv6 address:

ifconfig em3
em3: flags=8843 metric 0 mtu 1500
options=4219b
ether 00:00:24:ce:7b:fb
inet 24.24.190.190 netmask 0xfffffe00 broadcast 255.255.255.255
inet6 fe80::200:24ff:fece:7bfb%em3 prefixlen 64 scopeid 0xc
inet6 2001:558:6045:f6:84f:4343:4949:b3b3 prefixlen 128
nd6 options=21
media: Ethernet autoselect (1000baseT )
status: active

Notice there are two IPv6 addresses. Ignore the one that begins with fe80::200— it’s a link-local address that only works on the local subnet; it doesn’t work on the Internet. The second IPv6 address, the one beginning with 2001:558, is your Internet-accessible IP address.

Let’s test:

ping6 -c 2 ipv6.google.com
PING6(56=40+8+8 bytes) 2001:558:6045:f6:84f:4319:4958:b363 --> 2607:f8b0:4005:800::1012
16 bytes from 2607:f8b0:4005:800::1012, icmp_seq=0 hlim=56 time=14.689 ms
16 bytes from 2607:f8b0:4005:800::1012, icmp_seq=1 hlim=56 time=15.811 ms

--- ipv6.l.google.com ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 14.689/15.250/15.811/0.561 ms

Success! Now let’s make our changes permanent.

Permanent and Persistent

To make your changes persistent (i.e. IPv6 comes up on reboot), add the following to /etc/rc.conf:

ifconfig_em3_ipv6="inet6 -ifdisabled accept_rtadv"
dhcp6c_enable="YES"
dhcp6c_interfaces="em3"

Reboot:

sudo shutdown -r now

Log in and test again:

ping6 -c 2 ipv6.google.com