openwrt / odhcpd

This repository is a mirror of https://git.openwrt.org/?p=project/odhcpd.git. Pull requests will be accepted which will be merged in odhcpd.git
GNU General Public License v2.0
163 stars 99 forks source link

odhcpd does not pass the prefix to the client #41

Closed ghost closed 4 years ago

ghost commented 9 years ago

I have been trying to use static DHCPv6 assignment using odhcpd (git: 73a7133b6e42edc218da5b8011c580ed48c7731a) and a 6in4 tunnel.

The goal is to have the client receive 2001:470:1f12:1103::2/64. On the WAN side, a 6in4 tunnel is created. From the router, I can ping6 ipv6.google.com.

On the LAN side however the client receive 2001:470:1f12:1103::2/128. This Wireshark capture shows that the DHCP server offers the expected IPv6 address but does not include any prefix information (like DHCPV6_OPT_IA_PREFIX) option in its answer which leads the client (Ubuntu 14.04) to interpret the address as "/128".

eth0      Link encap:Ethernet  HWaddr 54:a0:50:7a:fc:df  
          inet addr:192.168.77.2  Bcast:192.168.77.255  Mask:255.255.255.0
          inet6 addr: 2001:470:1f13:1103::2/128 Scope:Global
          inet6 addr: fe80::56a0:50ff:fe7a:fcdf/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:723851 errors:0 dropped:0 overruns:0 frame:0
          TX packets:371144 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:933141282 (933.1 MB)  TX bytes:43979869 (43.9 MB)

The network configuration file looks like this:

[...]

config interface 'lan'
    option force_link '1'
    option type 'bridge'
    option proto 'static'
    option netmask '255.255.255.0'
    option ifname 'eth0.1'
    option ipaddr '192.168.77.1'
    option ip6gw '2001:470:1f13:1103::1'
    option ip6assign '64'
    option ip6hint '0'

[...]

config interface 'wan6'
    option _orig_ifname '@wan'
    option _orig_bridge 'false'
    option proto '6in4'
    option peeraddr '216.66.84.42'
    option ip6addr '2001:470:1f12:1103::2/64'
    option ip6prefix '2001:470:1f13:1103::/64'
    option ip6assign '64'
[...]
    option delegate '1'

And the DHCP configuration looks like this.

config dnsmasq
    option domainneeded '1'
    option boguspriv '1'
    option localise_queries '1'
    option rebind_protection '1'
    option rebind_localhost '1'
    option local '/lan/'
    option domain 'lan'
    option expandhosts '1'
    option authoritative '1'
    option readethers '1'
    option leasefile '/tmp/dhcp.leases'
    option resolvfile '/tmp/resolv.conf.auto'

config dhcp 'wan'
    option interface 'wan'
    option ignore '1'

config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'
    option dhcpv6 'server'
    option ra 'server'
    option ra_management '1'

config odhcpd 'odhcpd'
    option maindhcp '0'
    option leasefile '/tmp/hosts/odhcpd'
    option leasetrigger '/usr/sbin/odhcpd-update'

config host
    option name 'desktop'
    option mac '54:a0:50:7a:fc:df'
    option duid '0004eef4c651095f7f8f9139168091a4aa4c'
    option ip '192.168.77.2'
    option hostid '2'

The system seams to understand that the prefix from wan6 should be delegated to lan:

ifstatus wan6
{
    "up": true,
    "pending": false,
    "available": true,
    "autostart": true,
    "uptime": 171,
    "l3_device": "6in4-wan6",
    "proto": "6in4",
    "updated": [
        "addresses",
        "routes",
        "prefixes"
    ],
    "metric": 0,
    "delegation": true,
    "ipv4-address": [

    ],
    "ipv6-address": [
        {
            "address": "2001:470:1f12:1103::2",
            "mask": 64
        }
    ],
    "ipv6-prefix": [
        {
            "address": "2001:470:1f13:1103::",
            "mask": 64,
            "class": "wan6",
            "assigned": {
                "lan": {
                    "address": "2001:470:1f13:1103::",
                    "mask": 64
                }
            }
        }
    ],
    "ipv6-prefix-assignment": [

    ],
    "route": [
        {
            "target": "::",
            "mask": 0,
            "nexthop": "::",
            "source": "2001:470:1f12:1103::2\/64"
        },
        {
            "target": "::",
            "mask": 0,
            "nexthop": "::",
            "source": "2001:470:1f13:1103::\/64"
        },
        {
            "target": "::",
            "mask": 0,
            "nexthop": "::",
            "source": "::\/128"
        }
    ],
    "dns-server": [

    ],
    "dns-search": [

    ],
    "inactive": {
        "ipv4-address": [

        ],
        "ipv6-address": [

        ],
        "route": [

        ],
        "dns-server": [

        ],
        "dns-search": [

        ]
    },
    "data": {

    }
}

And the LAN interface seam to receive the prefix assignment properly (both address and mask):

 ifstatus lan
{
    "up": true,
    "pending": false,
    "available": true,
    "autostart": true,
    "uptime": 38,
    "l3_device": "br-lan",
    "proto": "static",
    "device": "br-lan",
    "updated": [
        "addresses"
    ],
    "metric": 0,
    "delegation": true,
    "ipv4-address": [
        {
            "address": "192.168.77.1",
            "mask": 24
        }
    ],
    "ipv6-address": [

    ],
    "ipv6-prefix": [

    ],
    "ipv6-prefix-assignment": [
        {
            "address": "2001:470:1f13:1103::",
            "mask": 64
        }
    ],
    "route": [

    ],
    "dns-server": [

    ],
    "dns-search": [

    ],
    "inactive": {
        "ipv4-address": [

        ],
        "ipv6-address": [

        ],
        "route": [

        ],
        "dns-server": [

        ],
        "dns-search": [

        ]
    },
    "data": {

    }
}

Running odhcpd manually over SSH gives the following:

root@OpenWrt:/tmp# ./odhcpd
odhcpd[13117]: DHCPV6 CONFIRM IA_NA from 0004eef4c651095f7f8f9139168091a4aa4c on br-lan: not on-link 2001:470:1f13:1103::2/128 
odhcpd[13117]: DHCPV6 SOLICIT IA_NA from 0004eef4c651095f7f8f9139168091a4aa4c on br-lan: ok 2001:470:1f13:1103::2/128 
odhcpd[13117]: DHCPV6 REQUEST IA_NA from 0004eef4c651095f7f8f9139168091a4aa4c on br-lan: ok 2001:470:1f13:1103::2/128 

I have not been able to figure out how the prefix is propagated in "dhcpv6-ia.c". Is the device improperly configured or is this case untested?

sbyx commented 9 years ago

DHCPv6 isn't capable of assigning addresses other than /128, the IA_PREFIX you mentioned is for delegating whole /64 prefixes to routers but not to clients. Clients learn the /64 on-link routes using RAs. Please capture the ICMPv6 traffic, specifically Router Advertisements as well.

Your network configuration is incorrect btw.

  1. Correct the ip6prefix in the wan6 section: it should be the delegated prefix. It is not the same as the address you configure on the tunnel side (ip6addr). Check your tunnel provider instructions.
  2. Remove the option ip6assign from the wan6 section (but not from the lan section)
  3. Remove the option ip6gw from the lan section (it does nothing)
ghost commented 9 years ago

DHCPv6 isn't capable of assigning addresses other than /128, the IA_PREFIX you mentioned is for delegating whole /64 prefixes to routers but not to clients. Clients learn the /64 on-link routes using RAs.

I did not know that thank you for the information. It is no wonder I was confused how odhcp is handling "a->prefix". Also, thank you for taking the time to investigate the issue as it might end up being a configuration problem on my part or an issue in Ubuntu.

Please capture the ICMPv6 traffic, specifically Router Advertisements as well.

Here is the new capture.

Your network configuration is incorrect btw.

  1. Correct the ip6prefix in the wan6 section: it should be the delegated prefix. It is not the same as the address you configure on the tunnel side (ip6addr). Check your tunnel provider instructions.

I doubled checked and I think it is correct. The tunnel is configured in the "1f12" network while the delegation is for the "1f13" network. It is easy to overlook so on Hurricane Electric configuration page, they put the difference in bold.

    option ip6addr '2001:470:1f12:1103::2/64'
    option ip6prefix '2001:470:1f13:1103::/64'

Do you still think this is wrong?

  1. Remove the option ip6assign from the wan6 section (but not from the lan section)
  2. Remove the option ip6gw from the lan section (it does nothing)

Done. Here is the new network configuration file:

[...]

config interface 'lan'
    option force_link '1'
    option type 'bridge'
    option proto 'static'
    option netmask '255.255.255.0'
    option ifname 'eth0.1'
    option ipaddr '192.168.77.1'
    option ip6assign '64'
    option ip6hint '0'

[...]

config interface 'wan6'
    option _orig_ifname '@wan'
    option _orig_bridge 'false'
    option proto '6in4'
    option peeraddr '216.66.84.42'
    option ip6addr '2001:470:1f12:1103::2/64'
    option ip6prefix '2001:470:1f13:1103::/64'
[...]
    option delegate '1'

[...]

I also tried changing my network configuration in Ubuntu from "Automatic, DHCP only" to "Automatic". The only difference is that the device takes 2 more global addresses through RA. In this case, I can "ping6 ipv6.google.com" but it manages to do so by not using the DHCPv6 address. In both cases, the device acquires 2001:470:1f13:1103::2/128 instead of 2001:470:1f13:1103::2/64.

eth0      Link encap:Ethernet  HWaddr 54:a0:50:7a:fc:df  
          inet addr:192.168.77.2  Bcast:192.168.77.255  Mask:255.255.255.0
          inet6 addr: 2001:470:1f13:1103::2/128 Scope:Global
          inet6 addr: 2001:470:1f13:1103:5dd5:84a3:2057:5434/64 Scope:Global
          inet6 addr: 2001:470:1f13:1103:56a0:50ff:fe7a:fcdf/64 Scope:Global
          inet6 addr: fe80::56a0:50ff:fe7a:fcdf/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2892 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3129 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1999868 (1.9 MB)  TX bytes:454450 (454.4 KB)
ghost commented 9 years ago

I figured out a side effect of the difference between "Automatic, DHCP only" vs "Automatic". Simply looking at the output of ifconfig is not enough. In the first case, the routing table looks like this:

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2001:470:1f13:1103::2/128      ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 1     0 eth0
::/0                           ::                         !n   -1  1  2129 lo
::1/128                        ::                         Un   0   3   156 lo
2001:470:1f13:1103::2/128      ::                         Un   0   1     0 lo
fe80::56a0:50ff:fe7a:fcdf/128  ::                         Un   0   1     4 lo
ff00::/8                       ::                         U    256 3     0 eth0
::/0                           ::                         !n   -1  1  2129 lo

While in the second case, the routing table is much better.

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2001:470:1f12:1103::/64        2001:470:1f13:1103::1      UG   1   0     0 eth0
2001:470:1f13:1103::2/128      ::                         U    256 0     0 eth0
2001:470:1f13:1103::/64        ::                         UAe  256 1     1 eth0
fe80::/64                      ::                         U    256 0     0 eth0
::/0                           fe80::200:83ff:fe8a:2000   UG   1   0     0 eth0
::/0                           fe80::200:83ff:fe8a:2000   UGDAe 1024 0   0 eth0
::/0                           ::                         !n   -1  1  2104 lo
::1/128                        ::                         Un   0   3   155 lo
2001:470:1f13:1103::2/128      ::                         Un   0   1     0 lo
2001:470:1f13:1103:56a0:50ff:fe7a:fcdf/128 ::             Un   0   1     0 lo
2001:470:1f13:1103:edc1:769c:905a:5c40/128 ::             Un   0   1    90 lo
fe80::56a0:50ff:fe7a:fcdf/128  ::                         Un   0   1    74 lo
ff00::/8                       ::                         U    256 1     0 eth0
::/0                           ::                         !n   -1  1  2104 lo

I am now back at my original problem, getting rid of the addresses from stateful configuration. If my understanding of RFC 4861 section 4.6.2 is correct, it should be possible to prevent the devices in the network from generating their own addresses. Sending a "Router Advertisement" packet including a "Prefix Information" option with the A bit cleared should in theory have the desired effect.

Is there a way to configure odhcpd to send such packets?

Searching through the odhcpd's source, I came across the following snippet at router.c#L304 that I believe provides the beginning of the answer:

        if (iface->managed < RELAYD_MANAGED_NO_AFLAG && addr->prefix <= 64)
            p->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;

If I understanding it correctly, "iface->managed" refers to "config dhcp", "option dhcpv6" in UCI. As the configuration is "server", this part of the condition is true. I do not understand the reason for the "addr->prefix <= 64" condition but I expect it to be also true.

Is there any reason why it should not be possible for the A flag to be cleared?

ghost commented 9 years ago

Sorry. Closed the issue by accident.

sbyx commented 9 years ago

Behavior is correct the /128 or /64 are irrelevant what counts is if there is an on-link route for the /64 in the routing table.

You can set option ra_management 2 in the lan section of /etc/config/dhcp to turn off the A flag.

sbyx commented 9 years ago

Also if your dhcpv6 client ever produces anything other than /128 its buggy anyway ;)

ghost commented 9 years ago

To resume the exchange for a potential third party with the same problem: As suggested, having "option ra_management '2'" in /etc/config/dhcp solved the problem. The desktop only takes the IPv6 address specified in the configuration file which makes configuring the firewall on the gateway much easier. Also unlike IPv4, to troubleshoot the issue, the output of both "ifconfig" and "route --net6" are needed.

[...]

config dhcp 'lan'
    option interface 'lan'
    option start '100'
    option limit '150'
    option leasetime '12h'
    option dhcpv6 'server'
    option ra 'server'
    option ra_management '2'

[...]

config host
    option name 'desktop'
    option mac '54:a0:50:7a:fc:df'
    option duid '0004eef4c651095f7f8f9139168091a4aa4c'
    option ip '192.168.77.2'
    option hostid '2'

While RFC 4861 is quite clear, I doubt that the average administrator knows it well enough to understand the odhcpd manpage. How about rewriting the following section in odhcpd's documentation from:

ra_management   integer 1           RA management mode
        0: no M-Flag but A-Flag, 1: both M and A, 2: M but not A

to:

ra_management   integer 1           RA management mode
                0: Devices only use stateless configuration
                1: Devices use both DHCPv6 and stateless configuration
                2: Devices only use DHCPv6 configuration

It should save people a lot of confusion until DUID are properly handled by luci.

mcprat commented 6 years ago

I can't help but resurrect this discussion...

This is the closest thing I have found similar to a problem I am having, but changing configuration, including the ra_management option, doesn't make any difference. I've given up on it already but wanted to document my version of the same problem anyway.

I have an ENS202EXT that has been running a very old Breaker Barrier build from easywrt.com Works great except for this prefix delegation problem. I don't remember exactly if it has ever worked or not.

ISP provides dual-stack with native IPv6 on a /56 length public prefix. Trying to have all routers have their own /64 or even /60. I have tried forcing both lengths on WAN and changing MAC addresses...

router has: odhcpd version 2014-08-23-24452e1e3e9adfd9d8e183db1aa589f77727f5a7 but was originally packed with: odhcpd version 2014-09-25-a6e2953843eaf6c93764f9feef10466e7a84ec85 switching versions also made no difference...

The IPv6 routing table is a mess...no default route...no line with the prefix in Next Hop

The gateway (?) shows in eth0 and lan as shown inet6 addr: fe80::8adc:96ff:fe5b:9184/64 Scope:Link

the only way I can even SEE the public prefix is with "ifstatus WAN6", "ifstatus lan" or "ip -6 route show" which has the line: unreachable 2603:3020:xxxx:xxxx::/60 dev lo proto static metric 2147483647 error -128

other routers on the same network have no problems. At this point, I'm thinking either a hard NVRAM erase, sysupgrade, or making my own completely new build since snapshots are the only thing offered.

dedeckeh commented 6 years ago

@mpratt14 I can only advice to upgrade to a more recent OpenWRT release as Barrier Breaker is a very old release and meanwhile a lot of IPv6 fixes have been made in the recent 17.01.5 and 18.06 releases