Git Product home page Git Product logo

openwrt / odhcp6c Goto Github PK

View Code? Open in Web Editor NEW
76.0 23.0 79.0 543 KB

This repository is a mirror of https://git.openwrt.org/?p=project/odhcp6c.git. It is for reference only and is not active for checks-ins or reporting issues; issues should be reported at: https://bugs.openwrt.org. Pull requests will be accepted which will be merged in odhcp6c.git

License: GNU General Public License v2.0

CMake 1.11% C 96.32% Shell 2.57%

odhcp6c's Introduction

odhcp6c - Embedded DHCPv6 Client


** Abstract **

odhcp6c is a minimal DHCPv6 and RA-client for use in embedded Linux systems
especially routers. It compiles to only about 35 KB (-Os -s).


** Features **

1. IPv6 bootstrap from different environments with autodetection
	a) RA only
	b) RA + stateless DHCPv6
	c) RA + stateful DHCPv6 (either IA_NA or IA_PD or both)

2. Handling of non-temporary addresses (IA_NA)
	a) handling of valid and preferred lifetimes
	b) automatic fallback to stateless or PD-only mode

3. Support for DHCPv6 extension
	a) Reconfigure-Messages
	b) Prefix Delegation (including handling of valid and preferred lifetimes)
	c) Prefix Exclusion
	d) DNS Configuration Options
	e) NTP Options
	f) SIP Options
	g) Information-Refresh Options
	h) Configurable SOL_MAX_RT
	i) DS-Lite AFTR-Name Option
	j) Softwire address and port mapped clients (MAP, LW4over6)
	j) CER-ID (experimental)
	k) Server unicast Option

4. Support for requesting and parsing Router Advertisements
	a) parsing of prefixes, routes, MTU and RDNSS options


** Compiling **

odhcp6c uses cmake:
* To prepare a Makefile use:  "cmake ."
* To build / install use: "make" / "make install" afterwards.
* To build DEB or RPM packages use: "make package" afterwards.


** State Script **

The state script is called whenever the DHCPv6 state changes.
The script is called with the following parameters: <interface> <state>


States:
* started		The DHCPv6 client has been started
* bound			A suitable server was found and addresses or prefixes acquired		
* informed		A stateless information request returned updated information
* updated		Updated information was received from the DHCPv6 server
* ra-updated		Updated information was received from via Router Advertisement
* rebound		The DHCPv6 client switched to another server
* unbound		The DHCPv6 client lost all DHCPv6 servers and will restart
* stopped		The DHCPv6 client has been stopped


Environment:
* RDNSS			A space-separated list of recursive DNS servers
* DOMAINS		A space-separated list of DNS search domains
* SNTP_IP		A space-separated list of SNTP server IP addresses
* SNTP_FQDN		A space-separated list of SNTP server FQDNs
* SIP_IP		A space-separated list of SIP servers
* SIP_DOMAIN		A space-separated list of SIP domains
* OPTION_<num>		Custom option received as base-16
* PREFIXES		A space-separated list of prefixes currently assigned
				Format: <prefix>/<length>,preferred,valid[,excluded=<excluded-prefix>/<length>][,class=<prefix class #>]
* ADDRESSES		A space-separated list of addresses currently assigned
				Format: <address>/<length>,preferred,valid
* RA_ADDRESSES		A space-separated list of addresses from RA-prefixes
				Format: <address>/<length>,preferred,valid
* RA_ROUTES		A space-separated list of routes from the RA
				Format: <address>/<length>,gateway,valid,metric
* RA_DNS		A space-separated list of recursive DNS servers from the RA
* RA_DOMAINS		A space-separated list of DNS search domains from the RA
* RA_HOPLIMIT	Highest hop-limit received in RAs
* RA_MTU		MTU-value received in RA
* RA_REACHABLE	ND Reachability time
* RA_RETRANSMIT	ND Retransmit time
* AFTR			The DS-Lite AFTR domain name
* MAPE / MAPT / LW4O6	Softwire rules for MAPE, MAPT and LW4O6

odhcp6c's People

Contributors

alinnastac avatar bwhacks avatar davidb137 avatar dedeckeh avatar fingon avatar guijan avatar janakj avatar kaspar030 avatar koalatux avatar lperkov avatar maico-le-pape avatar neheb avatar neocturne avatar pacien avatar sbyx avatar themiron avatar viktor-iarmola avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

odhcp6c's Issues

dnsmasq request hang

dnsmasq (2.65) hangs on a request message from odhcp6c. It seems to fail around line 572 of rfc3315.c (in dnsmasq source code) where dnsmasq is expecting an option type 3 (IA_NA) and address.

Using wireshark I see a request with an attached (and empty) Non-Temporary Address (3) option, but no IA Address (5) field coming from odhcp6c. I'm not sure if this is the correct fix (I am still wading through the RFC), but I added code to parse the IA_NA record out of the server's advertisement, added it to odhcp6c's state machine and it seems to have fixed the problem. I'm not sure if the timing records are correct so instead of sending you a pull request i'm inlining a diff for you to review:

diff --git a/src/dhcpv6.c b/src/dhcpv6.c
index 8be70af..2a4594c 100644
--- a/src/dhcpv6.c
+++ b/src/dhcpv6.c
@@ -241,8 +241,8 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs)
                pa[i].type = htons(DHCPV6_OPT_IA_ADDR);
                pa[i].len = htons(sizeof(pa[i]) - 4U);
                pa[i].addr = e[i].target;
-               pa[i].preferred = 0;
-               pa[i].valid = 0;
+               pa[i].preferred = e[i].preferred;
+               pa[i].valid = e[i].valid;
        }

        ia_na = pa;
@@ -534,6 +534,42 @@ static int dhcpv6_handle_advert(_unused enum dhcpv6_msg orig,
                                                d[1] == DHCPV6_NoPrefixAvail)
                                        cand.preference -= 2000;
                        }
+               } else if ((otype == DHCPV6_OPT_IA_NA)
+                               && olen > sizeof(struct dhcpv6_ia_hdr)) {
+                       struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-4]);
+                       uint32_t l_t1 = ntohl(ia_hdr->t1);
+                       uint32_t l_t2 = ntohl(ia_hdr->t2);
+
+                       // Test ID and T1-T2 validity
+                       if (ia_hdr->iaid != 1 || l_t2 < l_t1)
+                               continue;
+
+                       uint16_t stype, slen;
+                       uint8_t *sdata;
+                       // Test status and bail if error
+                       dhcpv6_for_each_option(&ia_hdr[1], odata + olen,
+                                       stype, slen, sdata)
+                               if (stype == DHCPV6_OPT_STATUS && slen >= 2 &&
+                                               (sdata[0] || sdata[1]))
+                                       continue;
+
+                       // Update times
+                       if (l_t1 > 0 && t1 > l_t1)
+                               t1 = l_t1;
+
+                       if (l_t2 > 0 && t2 > l_t2)
+                               t2 = l_t2;
+
+                       uint32_t n = dhcpv6_parse_ia(&ia_hdr[1], odata + olen);
+
+                       if (n < t1)
+                               t1 = n;
+
+                       if (n < t2)
+                               t2 = n;
+
+                       if (n < t3)
+                               t3 = n;
                }
        }

My dnsmasq.conf for verification:

listen-address=2001:db8:0:1::
dhcp-range=2001:db8:0:1::50,2001:db8:0:1::200
enable-ra
log-dhcp

Cross compile for kind of OpenWRT can't work.

I've found a problem while I'm compile the program.

/tmp/XiaoMi/odhcp6c/src/script.c: In function ‘s46_to_env’:
/tmp/XiaoMi/odhcp6c/src/script.c:272:2: warning: implicit declaration of function ‘open_memstream’ [-Wimplicit-function-declaration]
  FILE *fp = open_memstream(&str, &strsize);
  ^
/tmp/XiaoMi/odhcp6c/src/script.c:272:13: warning: initialization makes pointer from integer without a cast [enabled by default]
  FILE *fp = open_memstream(&str, &strsize);

After I checked the lib of my uclibc in toolchain, I found that the toolchain does not have the function...
So what should I do now? The fmemopen, open_memstream, open_wmemstream can be use..Is there any other functions can replace them instead?

Loosing prefix after valid-lft expires.

Hi,
Using LEDE or OpenWRT trunk odhcp6c somehow lets the valid-lifetime of interface expire and the prefix if the quite logically getting dropped from the interface.

This has been tested on several types of interfaces ethernet copper , SFP modules , GEPON ONU SFP
and various versions of OpenWRT and LEDE all resulting in the same loss of prefix.

Hardware Type used in DUID creation is Questionable

I have been setting up Comcast Dual Stack IPv6 with OpenWRT Barrier Breaker. odhcpc is the the default IPv6 dhcp client. When using odhcpc, I get a new prefix delegation every time odhcpc is restarted. I do not see the behavior with Wide-DHCP. Wide used a hardware type of 6 for "IEEE 802 Networks" whereas odhcpc uses type 1. I don't know if this is the issue, but I believe it could be relate.

[Feature Request] add parameter to send custom options

My ISP requires some customs (and non standards) options to be sent to get a IPv6 DHCP lease.
There is already an issue opened in openwrt tracker that reference the same problem.
Could you implement the same command line parameter as in busybox's udhcpc (-x parameter)?

Thanks,
Thomas

RA only?

The readme claims a mode which relies just on IPv6 Router Advertisements (RA). I am not able to find that mode. However, I need that because I am using my OpenWrt device not as router but as simple Wi-Fi access point. And my upstream router has no DHCPv6 server, even not a stateless one. I know, this tool is called from its shell script /package/network/ipv6/odhcp6c/files/dhcpv6.sh normally. And that script is started with options from /etc/config/network. Anyway, three teared down examples called directly from the command line, to eased debugging with Wireshark:

odhcp6c br-lan

creates continuously a DHCPv6 solicit,
because the state is is DHCPV6_UNKNOWN (-N is try).

odhcp6c -N none br-lan

creates continuously a DHCPv6 information-request,
because the state is DHCPV6_STATELESS.

odhcp6c -N none -P 64 br-lan

creates continuously a DHCPv6 solicit,
because the state is DHCPV6_UNKNOWN.

I went through the blame history and it looks like this never worked. Yes, IPv6 still works. However, I do not like to pollute my network with DHCPv6 messages; especially because in the RA, the m(anaged) and o(ther) bits are off.

Failed to send DHCPV6 message to ff02::1:2 (Address not available)

On LEDE 17.01.4 I seem to be getting:

Failed to send DHCPV6 message to ff02::1:2 (Address not available)

trying to get a DHCPv6 lease from my provider.

This is the same configuration that worked fine on OpenWRT Chaos Calmer so I'm really not sure why that address would not be available.

Any ideas?

Failed to send SOLICIT message to ff02::1:2 (Permission denied)

Hey,
I do get the following error messages from odhcp:

odhcp6c[16857]: Failed to send RS (Permission denied)
odhcp6c[16857]: Failed to send SOLICIT message to ff02::1:2 (Permission denied)

I am using a turris omnia, my netconfig looks as follows:

config interface 'loopback'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'
        option device 'lo'

config globals 'globals'
        option ula_prefix 'fd42:44d4:f241::/48'

config interface 'lan'
        option proto 'static'
        option ip6assign '64'
        option device 'br-lan'
        option _turris_mode 'managed'
        list ipaddr '192.168.178.1/24'

config interface 'wan'
        option ipaddr '192.168.8.10'
        option netmask '255.255.255.0'
        option gateway '192.168.8.1'
        option hostname 'turris'
        option proto 'pppoe'
        option device 'eth2.7'
        option keepalive '20 1'
        option username 'vodafone-vdsl.komplett/*redacted*-static'
        option password '*redacted*'
        option ipv6 '1'

config interface 'guest_turris'
        option enabled '1'
        option proto 'static'
        option ipaddr '10.111.222.1'
        option netmask '255.255.255.0'
        option device 'br-guest-turris'
        option ip6assign '64'

config interface 'wan6'
        option device '@wan'
        option reqprefix 'auto'
        option reqaddress 'try'
        option ip6gw '2a00:11:f982:2a00::1'
        option proto 'dhcpv6'

config device 'br_lan'
        option name 'br-lan'
        option bridge_empty '1'
        list ports 'lan0'
        list ports 'lan1'
        list ports 'lan2'
        list ports 'lan3'
        list ports 'lan4'
        option type 'bridge'

config device 'br_guest_turris'
        option bridge_empty '1'
        option type 'bridge'
        option name 'br-guest-turris'

config device 'dev_wan'
        option name 'eth2.7'

config route
        option gateway '192.168.178.42'
        option interface 'lan'
        option target '10.0.0.0'
        option netmask '255.0.0.0'

I did read somewhere, that ip -6 route add default dev pppoe-wan resolves the Permission denied error, which it does (not permanent that way). However, it still fails with (Address not available) afterwards.

I did see issue #55. My ISP does support IPv6 via dual stack for sure, but no link local address shows up with ifstatus wan:

{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "dynamic": false,
        "uptime": 25,
        "l3_device": "pppoe-wan",
        "proto": "pppoe",
        "device": "eth2.7",
        "updated": [
                "addresses",
                "routes"
        ],
        "metric": 0,
        "dns_metric": 0,
        "delegation": true,
        "ipv4-address": [
                {
                        "address": "176.95.*redacted*",
                        "mask": 32,
                        "ptpaddress": "84.58.120.1"
                }
        ],
        "ipv6-address": [

        ],
        "ipv6-prefix": [

        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "0.0.0.0",
                        "mask": 0,
                        "nexthop": "84.58.120.1",
                        "source": "0.0.0.0/0"
                }
        ],
        "dns-server": [
                "176.95.16.250",
                "176.95.16.251"
        ],
        "dns-search": [

        ],
        "neighbors": [

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

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [

                ],
                "dns-search": [

                ],
                "neighbors": [

                ]
        },
        "data": {

        }
}

It does work with another router (a fritzBox).

Additional info:

ip -6 addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1508 state UP qlen 1024
    inet6 fe80::da58:d7ff:fe01:9486/64 scope link 
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1024
    inet6 fe80::da58:d7ff:fe01:9487/64 scope link tentative 
       valid_lft forever preferred_lft forever
14: br-guest-turris: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2a00:11:f982:2aff::1/64 scope global deprecated dynamic 
       valid_lft 5133sec preferred_lft 0sec
    inet6 fd42:44d4:f241::1/64 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::c0f8:daff:fea5:34be/64 scope link 
       valid_lft forever preferred_lft forever
15: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fd42:44d4:f241:1::1/64 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::da58:d7ff:fe01:9486/64 scope link 
       valid_lft forever preferred_lft forever
22: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::6f0:21ff:fe45:e050/64 scope link 
       valid_lft forever preferred_lft forever
23: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::c2f8:daff:fea5:34be/64 scope link 
       valid_lft forever preferred_lft forever
24: guest_turris_1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::c0f8:daff:fea5:34be/64 scope link 
       valid_lft forever preferred_lft forever
25: guest_turris_0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::4f0:21ff:fe45:e050/64 scope link 
       valid_lft forever preferred_lft forever
854: eth2.7@eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::da58:d7ff:fe01:9487/64 scope link tentative 
       valid_lft forever preferred_lft forever

DHCPv6 PD lifetime on Japan NTT 10G Hikari

I'm using OpenWRT with NTT 10G Hikari (Flets Cross). I've encountered a specific issue regarding the DHCPv6 PD.
From the NTT DHCPv6 server, my DHCPv6 Client has been assigned a /56 PD prefix with the following lifetimes:
T1: 7200
T2: 10800
Preferred Lifetime: 12600
Valid Lifetime: 14400

The problem manifests itself at specific intervals — typically at the 4-hour, 6-hour, and most notably, the 8-hour marks. Just when NTT's DHCPv6 server sends out a reconfigure message, within about a second, I get a notice: 'daemon.notice netifd: Interface 'wan6' has lost the connection'. The connection will restore in about 10 seconds.
My ISP uses an IPv4 over IPv6 protocol, requiring a special IPv6 address as a tunnel endpoint. This issue only pops up when I assign this particular IPv6 address to the IPv4 over IPv6 tunnel interface (by using option ip6ifaceid).

The ISP provided me with a router XG-100NE, and I've also done packet capture analysis on it. I've noticed that each Renew Message behaves differently from OpenWRT. Could this be the cause?

OpenWRT:
Identity Association for Prefix Delegation
Option: Identity Association for Prefix Delegation (25)
Length: 41
IAID: 00000001
T1: 0
T2: 0
IA Prefix
Option: IA Prefix (26)
Length: 25
Preferred lifetime: 0
Valid lifetime: 0
Prefix length: 56
Prefix address: 2400:xxxx:xxxx:xx00::

ISP router:
Identity Association for Prefix Delegation
Option: Identity Association for Prefix Delegation (25)
Length: 41
IAID: 00000000
T1: 7200
T2: 10800
IA Prefix
Option: IA Prefix (26)
Length: 25
Preferred lifetime: 12600
Valid lifetime: 14400
Prefix length: 56
Prefix address: 2400:xxxx:xxxx:xx00::

IA_PD/IA_NA state info leaked when client is not bound

Hi Steven,

I recently noticed an issue where IA_PD/IA_NA state info was leaked via the dhcpv6 script to netifd although the client was not yet bound. As a consequence a prefix was assigned to the LAN by netifd; picked up by odhcpd which advertised the assigned prefix on the LAN (and thus IPv6 address were in use although the IPv6 prefix was not yet committed by the DHCPv6 server).
The issue was triggered by a DHCPv6 server on the WAN which refused to send a reply in response to a request; in the meanwhile a RA message was received by the client which triggered the dhcpv6 script and lead to IA_PD/IA_NA state info (constructed from the advertise) to be leaked to netifd.
I'm aware ra update script events can be blocked if the client is not bound by specifying the -S argument (noslaaconly uci parameter) and thus fixes the above described behavior.
As I'm not sure the -S argument was intended to circumvent such behavior I would like to hear your opinion on this matter.
Can we live with the current behavior or is it better to make a fix not to leak DHCPv6 state info when the client is not yet bound (although this would change the current behavior when the client gets unbound) ?

Thx,
Hans

odhcp6c with musl

musl

target-x86_64_musl-1.1.5/odhcp6c-2014-10-12/src/dhcpv6.c:467:9: error: missing initializer for field '__pad2' of 'struct msgh$
struct msghdr msg = {&srv, sizeof(srv), iov, cnt, NULL, 0, 0};
^
staging_dir/toolchain-x86_64_gcc-4.9-linaro_musl-1.1.5/include/bits/socket.h:8:28: note: '__pad2' declared here
socklen_t msg_controllen, __pad2;

not seeing a /60 on comcast

I started this bug on the wrong daemon (see: https://github.com/sbyx/odhcpd/issues/42 )

I am building from trunk and requesting a /60 via either ip6assign or reqprefix... Not getting one. I used to get one. I will check to see if I get one from an older box on the same link.

Have a horde of other dhcp issues...

And the answer seems to be two servers are providing prefixes, but the preference 255 one is only a /64. This is me only apparently getting a /64

http://snapon.lab.bufferbloat.net/~d/comcast_dhcp_issues.cap

IPv6 network stops working after a while

I have a Teltonika RUTX11 mobile internet router. It's having issues that makes my router to loose IPv6 connectivity after a while.

root@Teltonika-RUTX11:~# ping6 ftp.sunet.se
PING ftp.sunet.se (2001:6b0:19::165): 56 data bytes
ping6: sendto: Permission denied

If I kill the odhcp6c process it will spawn a new process and IPv6 connectivity is restored for a while but in like 1-3 days It's diving again.

I have logged a task at Teltonika but they haven't been able to pinpoint where the issue is. I have tried starting the process with -v but it seems to not be able to give any more details in the logs.

The process is started with these arguments:
odhcp6c -v -s /lib/netifd/dhcpv6.script -P0 -t120 qmimux0

Is there anything I can do to enable more logging to pinpoint the issue?

The /lib/netifd/dhcpv6.script file is quite massive:

#!/bin/sh
[ -z "$2" ] && echo "Error: should be run by odhcpc6c" && exit 1
. /lib/functions.sh
. /lib/netifd/netifd-proto.sh

setup_interface () {
	local device="$1"
	local prefsig=""
	local addrsig=""

	# Apply IPv6 / ND configuration
	HOPLIMIT=$(cat /proc/sys/net/ipv6/conf/$device/hop_limit)
	[ -n "$RA_HOPLIMIT" -a -n "$HOPLIMIT" ] && [ "$RA_HOPLIMIT" -gt "$HOPLIMIT" ] && echo "$RA_HOPLIMIT" > /proc/sys/net/ipv6/conf/$device/hop_limit
	[ -n "$RA_MTU" ] && [ "$RA_MTU" -ge 1280 ] && echo "$RA_MTU" > /proc/sys/net/ipv6/conf/$device/mtu 2>/dev/null
	[ -n "$RA_REACHABLE" ] && [ "$RA_REACHABLE" -gt 0 ] && echo "$RA_REACHABLE" > /proc/sys/net/ipv6/neigh/$device/base_reachable_time_ms
	[ -n "$RA_RETRANSMIT" ] && [ "$RA_RETRANSMIT" -gt 0 ] && echo "$RA_RETRANSMIT" > /proc/sys/net/ipv6/neigh/$device/retrans_time_ms

	proto_init_update "*" 1

	# Merge RA-DNS
	for radns in $RA_DNS; do
		local duplicate=0
		for dns in $RDNSS; do
			[ "$radns" = "$dns" ] && duplicate=1
		done
		[ "$duplicate" = 0 ] && RDNSS="$RDNSS $radns"
	done

	for dns in $RDNSS; do
		proto_add_dns_server "$dns"
	done

	for radomain in $RA_DOMAINS; do
		local duplicate=0
		for domain in $DOMAINS; do
			[ "$radomain" = "$domain" ] && duplicate=1
		done
		[ "$duplicate" = 0 ] && DOMAINS="$DOMAINS $radomain"
	done

	for domain in $DOMAINS; do
		proto_add_dns_search "$domain"
	done

	for prefix in $PREFIXES; do
		proto_add_ipv6_prefix "$prefix"
		prefsig="$prefsig ${prefix%%,*}"
		local entry="${prefix#*/}"
		entry="${entry#*,}"
		entry="${entry#*,}"
		local valid="${entry%%,*}"

		if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
				-z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
			RA_ROUTES="::/0,$SERVER,$valid,4096"
		fi
	done

	for prefix in $USERPREFIX; do
		proto_add_ipv6_prefix "$prefix"
	done

	# Merge addresses
	for entry in $RA_ADDRESSES; do
		local duplicate=0
		local addr="${entry%%/*}"
		for dentry in $ADDRESSES; do
			local daddr="${dentry%%/*}"
			[ "$addr" = "$daddr" ] && duplicate=1
		done
		[ "$duplicate" = "0" ] && ADDRESSES="$ADDRESSES $entry"
	done

	for entry in $ADDRESSES; do
		local addr="${entry%%/*}"
		entry="${entry#*/}"
		local mask="${entry%%,*}"
		entry="${entry#*,}"
		local preferred="${entry%%,*}"
		entry="${entry#*,}"
		local valid="${entry%%,*}"

		proto_add_ipv6_address "$addr" "$mask" "$preferred" "$valid" 1
		addrsig="$addrsig $addr/$mask"

		if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
				-z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
			RA_ROUTES="::/0,$SERVER,$valid,4096"
		fi

		# RFC 7278
		if [ "$mask" -eq 64 -a -z "$PREFIXES" -a -n "$EXTENDPREFIX" ]; then
			proto_add_ipv6_prefix "$addr/$mask,$preferred,$valid"

			local raroutes=""
			for route in $RA_ROUTES; do
				local prefix="${route%%/*}"
				local entry="${route#*/}"
				local pmask="${entry%%,*}"
				entry="${entry#*,}"
				local gw="${entry%%,*}"

				[ -z "$gw" -a "$mask" = "$pmask" ] && {
					case "$addr" in
						"${prefix%*::}"*) continue;;
					esac
				}
				raroutes="$raroutes $route"
			done
			RA_ROUTES="$raroutes"
		fi
	done

	for entry in $RA_ROUTES; do
		local duplicate=$NOSOURCEFILTER
		local addr="${entry%%/*}"
		entry="${entry#*/}"
		local mask="${entry%%,*}"
		entry="${entry#*,}"
		local gw="${entry%%,*}"
		entry="${entry#*,}"
		local valid="${entry%%,*}"
		entry="${entry#*,}"
		local metric="${entry%%,*}"

		for xentry in $RA_ROUTES; do
			local xprefix="${xentry%%,*}"
			xentry="${xentry#*,}"
			local xgw="${xentry%%,*}"

			[ -n "$gw" -a -z "$xgw" -a "$addr/$mask" = "$xprefix" ] && duplicate=1
		done

		if [ -z "$gw" -o "$duplicate" = 1 ]; then
			proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid"
		else
			for prefix in $PREFIXES $ADDRESSES; do
				local paddr="${prefix%%,*}"
				proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid" "$paddr"
			done
		fi
	done

	proto_add_data
	[ -n "$CER" ] && json_add_string cer "$CER"
	[ -n "$PASSTHRU" ] && json_add_string passthru "$PASSTHRU"
	[ -n "$ZONE" ] && json_add_string zone "$ZONE"
	proto_close_data

	proto_send_update "$INTERFACE"

	MAPTYPE=""
	MAPRULE=""

	if [ -n "$MAPE" -a -f /lib/netifd/proto/map.sh ]; then
		MAPTYPE="map-e"
		MAPRULE="$MAPE"
	elif [ -n "$MAPT" -a -f /lib/netifd/proto/map.sh -a -f /proc/net/nat46/control ]; then
		MAPTYPE="map-t"
		MAPRULE="$MAPT"
	elif [ -n "$LW4O6" -a -f /lib/netifd/proto/map.sh ]; then
		MAPTYPE="lw4o6"
		MAPRULE="$LW4O6"
	fi

	[ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE 2>/dev/null)

	if [ "$IFACE_MAP" != 0 -a -n "$MAPTYPE" -a -n "$MAPRULE" ]; then
		[ -z "$IFACE_MAP" -o "$IFACE_MAP" = 1 ] && IFACE_MAP=${INTERFACE}_4
		json_init
		json_add_string name "$IFACE_MAP"
		json_add_string ifname "@$INTERFACE"
		json_add_string proto map
		json_add_string type "$MAPTYPE"
		json_add_string _prefsig "$prefsig"
		[ "$MAPTYPE" = lw4o6 ] && json_add_string _addrsig "$addrsig"
		json_add_string rule "$MAPRULE"
		json_add_string tunlink "$INTERFACE"
		[ -n "$ZONE_MAP" ] || ZONE_MAP=$ZONE
		[ -n "$ZONE_MAP" ] && json_add_string zone "$ZONE_MAP"
		[ -n "$ENCAPLIMIT_MAP" ] && json_add_string encaplimit "$ENCAPLIMIT_MAP"
		[ -n "$IFACE_MAP_DELEGATE" ] && json_add_boolean delegate "$IFACE_MAP_DELEGATE"
		json_close_object
		ubus call network add_dynamic "$(json_dump)"
	elif [ -n "$AFTR" -a "$IFACE_DSLITE" != 0 -a -f /lib/netifd/proto/dslite.sh ]; then
		[ -z "$IFACE_DSLITE" -o "$IFACE_DSLITE" = 1 ] && IFACE_DSLITE=${INTERFACE}_4
		json_init
		json_add_string name "$IFACE_DSLITE"
		json_add_string ifname "@$INTERFACE"
		json_add_string proto "dslite"
		json_add_string peeraddr "$AFTR"
		json_add_string tunlink "$INTERFACE"
		[ -n "$ZONE_DSLITE" ] || ZONE_DSLITE=$ZONE
		[ -n "$ZONE_DSLITE" ] && json_add_string zone "$ZONE_DSLITE"
		[ -n "$ENCAPLIMIT_DSLITE" ] && json_add_string encaplimit "$ENCAPLIMIT_DSLITE"
		[ -n "$IFACE_DSLITE_DELEGATE" ] && json_add_boolean delegate "$IFACE_DSLITE_DELEGATE"
		json_close_object
		ubus call network add_dynamic "$(json_dump)"
	elif [ "$IFACE_464XLAT" != 0 -a -f /lib/netifd/proto/464xlat.sh ]; then
		[ -z "$IFACE_464XLAT" -o "$IFACE_464XLAT" = 1 ] && IFACE_464XLAT=${INTERFACE}_4
		json_init
		json_add_string name "$IFACE_464XLAT"
		json_add_string ifname "@$INTERFACE"
		json_add_string proto "464xlat"
		json_add_string tunlink "$INTERFACE"
		json_add_string _addrsig "$addrsig"
		[ -n "$ZONE_464XLAT" ] || ZONE_464XLAT=$ZONE
		[ -n "$ZONE_464XLAT" ] && json_add_string zone "$ZONE_464XLAT"
		[ -n "$IFACE_464XLAT_DELEGATE" ] && json_add_boolean delegate "$IFACE_464XLAT_DELEGATE"
		json_close_object
		ubus call network add_dynamic "$(json_dump)"
	fi

	# TODO: $SNTP_IP $SIP_IP $SNTP_FQDN $SIP_DOMAIN
}

teardown_interface() {
	proto_init_update "*" 0
	proto_send_update "$INTERFACE"
}

case "$2" in
	bound)
		teardown_interface "$1"
		setup_interface "$1"
	;;
	informed|updated|rebound)
		setup_interface "$1"
	;;
	ra-updated)
		[ -n "$ADDRESSES$RA_ADDRESSES$PREFIXES$USERPREFIX" ] && setup_interface "$1"
	;;
	started|stopped|unbound)
		teardown_interface "$1"
	;;
esac

# user rules
[ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user "$@"

exit 0

odhcp6c with iWay

According to the provider I should get a /56 subnet using PD. However, it does not appear to work on current Chaos Calmer RC3 (on a WNDR4300, odhcp6c d21764d).

I made a capture of the DHCPv6 packages while running odhcp6c manually on the WAN interface:

# odhcp6c -s /lib/netifd/dhcpv6.script -Ntry -P0 -t120 eth0.2 -e -v
odhcp6c[22466]: (re)starting transaction on eth0.2
Command failed: Not found
odhcp6c[22466]: Starting SOLICIT transaction (timeout 4294967295s, max rc 0)
odhcp6c[22466]: Got a valid reply after 5ms
odhcp6c[22466]: Got a valid reply after 7ms
Command failed: Not found
odhcp6c[22466]: Starting REQUEST transaction (timeout 4294967295s, max rc 10)
odhcp6c[22466]: Send REQUEST message (elapsed 0ms, rc 0)
odhcp6c[22466]: Send REQUEST message (elapsed 955ms, rc 1)
odhcp6c[22466]: Send REQUEST message (elapsed 2835ms, rc 2)
odhcp6c[22466]: Send REQUEST message (elapsed 6665ms, rc 3)
odhcp6c[22466]: Send REQUEST message (elapsed 14675ms, rc 4)
odhcp6c[22466]: Send REQUEST message (elapsed 30705ms, rc 5)
Command failed: Not found
Command failed: Not found
odhcp6c[22466]: Send REQUEST message (elapsed 62635ms, rc 6)
Command failed: Not found
Command failed: Not found
odhcp6c[22466]: Send REQUEST message (elapsed 92515ms, rc 7)
Command failed: Not found
Command failed: Not found
odhcp6c[22466]: Send REQUEST message (elapsed 124761ms, rc 8)
Command failed: Not found
Command failed: Not found
odhcp6c[22466]: Send REQUEST message (elapsed 154545ms, rc 9)
Command failed: Not found
Command failed: Not found
odhcp6c[22466]: (re)starting transaction on eth0.2

Wireshark capture file:
https://cloud.agner.ch/public.php?service=files&t=842f0cf8d0023a348d2c334f56e34876

It seems that the replies from the servers are not accepted by odhcp6c, but it is not clear to me why... Probably due to some RFC3315 Section 15 validation?

ra_process() creating corrupted routes

With the following radvdump output:

interface wlan1
{
        AdvSendAdvert on;
        # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
        AdvManagedFlag off;
        AdvOtherConfigFlag off;
        AdvReachableTime 750000;
        AdvRetransTimer 0;
        AdvCurHopLimit 64;
        AdvDefaultLifetime 1800;
        AdvHomeAgentFlag off;
        AdvDefaultPreference medium;
        AdvSourceLLAddress on;
        AdvLinkMTU 1500;

        prefix 2620:0:1000:fd3e::/64
        {
                AdvValidLifetime 2592000;
                AdvPreferredLifetime 604800;
                AdvOnLink on;
                AdvAutonomous on;
                AdvRouterAddr off;
        }; # End of prefix definition

}; # End of interface definition

odhcp6c is creating these routes on wan6 (intercepted from /lib/netifd/dhcpv6.script):

proto_add_ipv6_route :: 0 fe80::5:73ff:fea0:690 1024 1800
proto_add_ipv6_route 2620:0:1000:fd3e:: 64  256 2592000
proto_add_ipv6_route 2620:0:1000:fd3e:2e0:b8ff:fe76:1b6 64 fe80::5:73ff:fea0:690 1024 1042

In particular, the last one is wrong, because it's routing my local /64 via the default gateway:

2620:0:1000:fd3e::/64 via fe80::5:73ff:fea0:690 dev wlan1  proto static  metric 1024

The problem is in ra_process() in ra.c. The entry variable is initialized once, and used multiple times. In this case, ND_OPT_PREFIX_INFORMATION sets target, which then leaks into the default route on the next iteration.

I think this bug is more noticeable when the upstream router runs SLAAC without DHCPv6.

ND_OPT_MTU handler blindly sets bad MTUs

Some mis-configured servers send the ND_OPT_MTU parameter as 0 or potentially other invalid values. The linux kernel does bounds checking on the MTU option and will ignore values < IPV6_MIN_MTU.

prefix lifetimes on comcast

OK, so I finally got odhcp6c up and running on debian, where life is easier to debug, and after flailing mightily against dibbler, dhclient, and wide.

Tearing apart the script, I see

RA_ROUTES=::/0,fe80::22e5:2aff:feb8:14f,1769,512 2601:646:8301:c500::/64,,345569,256 2601:646:8301:c500::/56,fe80::22e5:2aff:feb8:14f,345569,512

PREFIXES=2601:646:8301:c5f0::/60,30,60

And indeed, I see it requesting a renew (preferred lifetime of 0) every 10 seconds or so, and getting back the renew for preferred/valid 30/60 seconds....

I can't remember where we left off on this before.

DHCPv6 Declinet not sent after duplicate address is detected.

RFC 8415 https://tools.ietf.org/html/rfc8415#section-18.2.8 we MUST send DHCv6 decline if we see duplicate adddress on the network. While I was testing this when linux kernel found that address is not usable as there was a duplicate address in the network odhcp6c did not send decline.

Wanted to know if this case is not handled?

Snippet from RFC.

" The client MUST perform duplicate address detection as per
Section 5.4 of [RFC4862], which does list some exceptions, on each
of the received addresses in any IAs on which it has not performed
duplicate address detection during processing of any of the
previous Reply messages from the server. The client performs the
duplicate address detection before using the received addresses
for any traffic. If any of the addresses are found to be in use
on the link, the client sends a Decline message to the server for
those addresses as described in Section 18.2.8."

advice request for AT&T fiber oddity

When using AT&T's router/ONT combo (Arris BGW-320) in pass-thru mode, an IN_PD request is given a /64 address block. What's odd here is that the upstream DHCPv6 server returns a /60 and the AT&T is filtering, but will respond to multiple requests up to eight.

How can I get odhcp6c to do what that wide-dhcp6c script is doing on OpenWrt 19.07.7?

IPv6 ND RA update not caught

When IPv6 ND RA has some updates for DNS server and domain name (RFC 6106), seems odhcp6c could not catch it. There is no script call with ra-updated sate for new entry with RA_DNS and RA_DOMAIN env variables.

connectivity sucks

I've trouble with the current version. The last working version is from 17th October. I'm using OpenWrt on a Carambola board. The WAN interface is connected to the DSL router from my ISP (Speedport W723 from German Telekom). It advertise a /64 prefix. A Windows 7 PC is connected via WLAN to the Carambola board. The ipv6 connectivity sucks after every ~20sec for ~10sec. If I run ping continuously, I can see the gaps without connectivity. The same can be observed by firefox, which is connected to ipv6 only page. If I go back to the version from 17th October, I don't see this issue. But I've another issue. The log is flooded with messages from odhcp6c. The same occurs in the log of my DSL router (an IPv6 DHCP messages at every 5min).

Don't limit the RDNSS lifetime to the default router lifetime?

We recently hit the problem that it is not possible to specify a RDNSS record in a router advertisement when AdvDefaultLifetime is 0, as the RDNSS lifetime is bounded by the default router lifetime.

I'm aware that RFC6106 explicitly mandates this behaviour, but I don't think it makes any sense (why would a RA even contain a RDNSS record with a higher lifetime that its AdvDefaultLifetime if it's always shortened anyways?), and it makes it impossible to announce a DNS server without also announcing a default route (even when the DNS server address might be in one of the prefixes that is announced by the same RA and thus reachable without a default route).

I've been looking for other discussions about this topic; so far I've found the (unfortunately expired) RFC draft http://ietfreport.isoc.org/idref/draft-gont-6man-slaac-dns-config-issues/ which mentions the same issue in Appendix A, coming to the same conclusion that the default router lifetime shouldn't affect the RDNSS lifetime.

Starting odhcp6c as a daemon results in a continuously increasing recv buffer of raw sockets.

When starting odhcp6c as a daemon using the command "odhcp6c -s /etc/odhcp6c.script -p /var/run/eth0_odhcp6c.pid -P 0 -t 120 eth0", the DHCPv6 server sends RA packets every 10 seconds.
However, it was observed that the raw socket's receive buffer keeps increasing continuously.
After investigating the code, an error was found: the I/O signal was bound before starting the daemon, causing the daemon to not receive the I/O signal. Consequently, the raw socket's recv queue kept growing indefinitely.

I have observed that this bug seems to be persistent.

This patch is my solution, which places the initialization after creating the daemon process.

don't exit when you have child processes

Maybe it is just me, but de-parented processes make me cry. :)

Here is a patch to make odhcp6c wait for child processes to finish before exiting:

https://github.com/jimdigriz/bratwurst/blob/master/package/odhcp6c/odhcp6c-001-wait-for-children-on-stop.patch

This lets you get from within your DHCP handling script the name of the process that called you, for example as I do in:

https://github.com/jimdigriz/bratwurst/blob/master/rootfs/usr/share/dhcpc.script

RFC 8106 Support

Hello,
I just wanted to check if there is any support or plans to support for RFC 8106 section 5.1 and 5.2. I could not find it anywhere in the odhcp6c user guide.
Currently the behavior that I'm seeing is that after the lifetime expires, odhcp does not execute the script with FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF as the RA_DNS.

Thanks

What's "Command failed: Not found"

I ran this command:

odhcp6c -s /lib/netifd/dhcpv6.script -Ntry -P0 -t120 eth1.2

I got this response:

Command failed: Not found

Can the code be improved to specify what is "Not found"? What is the something that is not found?

source specific routing and /56s

My external interface gets a /56 (I changed the example script to use table 16 (dhcp))

2601:646:8301:c500::/56 from :: via fe80::22e5:2aff:feb8:14f dev eth2 metric 512 pref medium
2601:646:8301:c500::/56 from 2601:646:8301:c5f0::/60 via fe80::22e5:2aff:feb8:14f dev eth2 proto dhcp metric 512 pref medium

But I only get a "default from" what the local dhcp-pd server could fetch (a /60 in that range)

default from 2601:646:8301:c5f0::/60 via fe80::22e5:2aff:feb8:14f dev eth2 proto dhcp metric 512 pref medium

And then the /56 is just routable internally, but no default until this or some other dhcp-pd enabled server fetches another /60 AND then if it announced it, it would direct traffic back to itself.

shouldn't the "default from" be the entire /56 for the edge gateway? and an interior box not do source specific at all?

Unable to get IPv6 address from Server using ODHCP6C

Dear Community,

I am new to networking and need to implement DHCPv6 client on a non OS environment. I chose ODHCP6C as it is light weight. But before porting it to my board, looking to see this works between two PCs. I tried WIDE-DHCP6-Server & ISC-DHCP6-Server and corresponding clients and getting the IPV6 IP on the client machine.

Where as if i use ODHCP6C as client, all packets (S,A,R,R) look proper but still ipv6 address is not been found on my eth0 interface.

I am using UBUNTU 14.0 version, i observed few differences among odhcp6c and other client's SOLICIT packet's requested options and made the same in odhcp6c sources and checked it behaves same.

Since, i have spent considerable time checking multiple clients, i believe ODHCP6C is correct option for me. So, please help me out in setting up SERVER-CLIENT system using ODHCP6C and any other server (name, configuration files).
My set-up : odhcp6c-1.1/ (Release version)
Attached : capture of DHCPv6 server & client packet's exchange & ODHCPC_v_1.1 source code

Thanks for the help in advance.

Awaiting for the response..!
Thanks & regards,
Krishna Kotikalapudi,
[email protected]
dhcpv6_wideDHCPv6SER_with_ODCHP6client.zip

Filter syslog

Did you think if it's possible to decrease the level of syslog for informative message (at debug level).

IA-PD status 4 and 80+% cpu usage

I just brought up chaos calmer behind a comcast box that has already given away its /56 to another box still online. I see odhcpv6 saying it got that error code, then it retries a few ms later, and loops endlessly retrying eating 80% of cpu for as long as I cared to watch it go.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.