Re: DHCPv6 without SLAAC
Joachim Achtzehnter
Wed Dec 31 00:06:30 2014
Hi Roy,
Further on the desire for an option to configure a specific interface on
a specific host to assign only a DHCP address, but not assign any
autonomously chosen SLAAC addresses: One way to provide this option is
illustrated by the attached patch.
This relies on the caller of dhcpcd to set the kernel parameters
(accept_ra==1, autoconf==0). This is how ifup from the ifupdown package
would configure this use case if it supported dhcpcd for IPv6. I've
tried this and it does what I want, with two small problems, which I
think are unrelated issues.
The patch is only intended as an illustration, I'm not familiar enough
with the dhcpcd implementation to know whether this is an appropriate
way to do it.
Here are the two remaining problems:
1) For some reason the DHCP address is added with a prefix length of 128
instead of 64. The router advertises a prefix with length 64.
2) The hook script does not seem to get called after the DHCP address
was bound (at least not when starting up with an existing lease), it is
only called for the receipt of the RA.
Thanks,
Joachim
--
joachima@xxxxxxxxxxxxxx http://www.netacquire.com
diff -u -r dhcpcd-6.6.7/dhcpcd.h dhcpcd-6.6.7_patched/dhcpcd.h
--- dhcpcd-6.6.7/dhcpcd.h 2014-12-19 02:45:45.000000000 -0800
+++ dhcpcd-6.6.7_patched/dhcpcd.h 2014-12-30 14:45:00.230047262 -0800
@@ -56,12 +56,16 @@
* dhcpcd can poll it for the relevant flags periodically */
#define IF_POLL_UP 100 /* milliseconds */
+/* flag bits for interface.conf flags */
+enum { CONF_NOAUTOCONF = 1 };
+
struct interface {
struct dhcpcd_ctx *ctx;
TAILQ_ENTRY(interface) next;
char name[IF_NAMESIZE];
unsigned int index;
unsigned int flags;
+ unsigned int conf;
sa_family_t family;
#ifdef __FreeBSD__
struct sockaddr_storage linkaddr;
diff -u -r dhcpcd-6.6.7/if-linux.c dhcpcd-6.6.7_patched/if-linux.c
--- dhcpcd-6.6.7/if-linux.c 2014-12-19 02:45:45.000000000 -0800
+++ dhcpcd-6.6.7_patched/if-linux.c 2014-12-30 15:00:41.924880680 -0800
@@ -1566,11 +1566,14 @@
snprintf(path, sizeof(path), "%s/%s/autoconf", prefix, ifname);
ra = check_proc_int(path);
if (ra != 1) {
+ /* allow this, it just means we want a DHCP address but no SLAAC
if (!own) {
syslog(LOG_WARNING,
"%s: IPv6 kernel autoconf disabled", ifname);
return -1;
}
+ */
+ ((struct interface *)ifp)->conf |= CONF_NOAUTOCONF;
} else if (ra != -1 && own) {
if (write_path(path, "0") == -1) {
syslog(LOG_ERR, "write_path: %s: %m", path);
diff -u -r dhcpcd-6.6.7/ipv6nd.c dhcpcd-6.6.7_patched/ipv6nd.c
--- dhcpcd-6.6.7/ipv6nd.c 2014-12-19 02:45:45.000000000 -0800
+++ dhcpcd-6.6.7_patched/ipv6nd.c 2014-12-30 14:45:17.887665635 -0800
@@ -863,8 +863,9 @@
ap->flags = IPV6_AF_NEW;
ap->prefix_len = pi->nd_opt_pi_prefix_len;
ap->prefix = pi->nd_opt_pi_prefix;
- if (pi->nd_opt_pi_flags_reserved &
- ND_OPT_PI_FLAG_AUTO)
+ if ((pi->nd_opt_pi_flags_reserved &
+ ND_OPT_PI_FLAG_AUTO) &&
+ (ifp->conf & CONF_NOAUTOCONF) == 0)
{
ap->flags |= IPV6_AF_AUTOCONF;
ap->dadcounter =
Archive administrator: postmaster@marples.name