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 accept a static hostid greater than 32 bits! #27

Open sgargbugreporter opened 10 years ago

sgargbugreporter commented 10 years ago

Hardware: WDR-3600 using OpenWRT Barrier Breaker 14.07

I want to provide the last 64 bits of the IPv6 address to my host using DHCPv6 using odhcpd. Have referred to: https://miceliux.com/apuntesderoot/2014/09/07/static-dhcpv6-leases-in-openwrt/

The "/etc/config/dhcp" file contains:

config host                      
    option name 'hostname'
    option mac '00:xx:xx:xx:98:03'
    option ip '10.159.93.40'      
    option duid '000100011b68071900xxxxxx9803'                                       
    option hostid 'b3e6c2dba12bdf02'

Note that the hostid is 8 octets long, i.e:

b3e6:c2db:a12b:df02

as it can be. However, this fails and odhcpd provides my host a random IPv6 address:

odhcpd[10534]: DHCPV6 SOLICIT IA_NA from 000100011b68071900xxxxxx9803 on br-lan: ok 2001:xxxx:e383:938::9e1/128 fd00:db80:0:938::9e1/128 
odhcpd[10534]: DHCPV6 REQUEST IA_NA from 000100011b68071900xxxxxx9803 on br-lan: ok 2001:xxxx:e383:938::9e1/128 fd00:db80:0:938::9e1/12

A similar case happens in the following case (9x4 = 36 bits longs):

  option hostid 'b3e6c2dbf'          

which should actually be interpreted as: 0000:000b:3e6c:2dbf but is not!

However, the following works:

 option hostid 'b3e6c2db' 

and I get:

odhcpd[10153]: DHCPV6 SOLICIT IA_NA from 000100011b68071900xxxxxx9803 on br-lan: ok 2001:xxxx:e383:938::b3e6:c2db/128 fd00:db80:0:938::b3e6:c2db/128 
odhcpd[10153]: DHCPV6 SOLICIT IA_NA from 000100011b68071900xxxxxx9803 on br-lan: ok 2001:xxxx:e383:938::b3e6:c2db/128 fd00:db80:0:938::b3e6:c2db/128 
odhcpd[10153]: DHCPV6 REQUEST IA_NA from 000100011b68071900xxxxxx9803 on br-lan: ok 2001:xxxx:e383:938::b3e6:c2db/128 fd00:db80:0:938::b3e6:c2db/128

which is being interpreted correctly as: 0000:0000:3e6c:2dbf

I wonder how is this handled? I have a /48 from he.net and I am routing a /64 from that.

V10lator commented 8 years ago

I wonder about that, too, so I looked at the sources. Here's where it's defined: https://github.com/sbyx/odhcpd/blob/master/src/odhcpd.h#L95 - Ofc. a unsigned 32 bit integer can't hold more than 32 bit. We can't simply change that as later on it gets stored in here: https://github.com/sbyx/odhcpd/blob/master/src/dhcpv6.h#L148 - Which happens to be a 32 bit variable, too. After that I stopped tracking what happens with the variable later on as the source seems to be complicated and the variable is referenced multiple times.

Let's just hope a developer jumps in and helps us. :)

saudiqbal commented 3 years ago

Hopefully someone can add 64 bit variable.

davygrvy commented 3 years ago

Greater than 64-bit would be even better. If your subnet is a /60 then you could set all 68 bits.

Store the suffix in a struct in6_addr. Don't skimp on space

          struct in6_addr {
               unsigned char   s6_addr[16];   /* IPv6 address */
           };
mikma commented 3 years ago

Greater than 64-bit would be even better. If your subnet is a /60 then you could set all 68 bits.

All IPv6 subnets are /64. OpenWrt only use other prefix lengths to relay the IPv6 prefix assignment via the kernel to odhcpd. The first /64 is reserved for the on-link subnet. If you use an IPv6 address from another /64 prefix then you can't delegate that prefix or any larger prefix that contains that /64 prefix.

Wouldn't it be better to assign the /64 you are interested in to a loopback interface, and then configure the IP suffix there? I often create an "local" interface as an loopback alias on my routers for that use.

davygrvy commented 3 years ago

What would be even better than that would be a hostid in the lease struct that had the proper space https://github.com/sbyx/odhcpd/blob/master/src/odhcpd.h#L95

davygrvy commented 3 years ago

What you can't do is set a subnet prefix GREATER than a /64 as it breaks SLAAC. A smaller prefix is fine for a larger address block. All subnets don't always have to be /64.

davygrvy commented 3 years ago

If AT&T was nice enough to grant me a /48, then I could subnet 256 /56s https://www.ripe.net/about-us/press-centre/ipv6-chart_2015.pdf

davygrvy commented 3 years ago

👍👋

davygrvy commented 3 years ago

@mikma Thank you for this change as it fully encompasses the interface ID portion of the address. But I was wondering if it could be considered to use an in6_addr rather than a uint64_t to go larger. I know it isn't exactly correct, but if I happen to have an extra 16 bits into the subnet ID to play with because my interface is set to /48, I'd love to be able to set this as my end-point address: 2001:db8::18:dead:beef:cafe:f00d

mikma commented 3 years ago

if I happen to have an extra 16 bits into the subnet ID to play with because my interface is set to /48

I think all on-link prefixes on OpenWrt are /64. If you assign a larger prefix to an interface then only the first /64 is used on-link (2001:db8::/64 in your example), the rest is used for prefix delegation, i.e. for other routers.

saudiqbal commented 3 years ago

Is it going to make it to Openwrt 20x?

mikma commented 3 years ago

This issue should be fixed by 1666769, but it seems there was a problem with the formatting of the "Fixes" line in the commit since it wasn't closed automatically.