diff --git a/examples/gnrc_border_router/Kconfig b/examples/gnrc_border_router/Kconfig new file mode 100644 index 000000000000..a45569e9a3f2 --- /dev/null +++ b/examples/gnrc_border_router/Kconfig @@ -0,0 +1,10 @@ +if MODULE_ETHOS +config GNRC_DHCPV6_CLIENT_6LBR_STATIC_ROUTE + default y + depends on MODULE_GNRC_DHCPV6_CLIENT_6LBR && KCONFIG_MODULE_GNRC_DHCPV6 +config GNRC_NETIF_IPV6_ADDRS_NUMOF + # CONFIG_GNRC_DHCPV6_CLIENT_6LBR_STATIC_ROUTE=1 requires one more address + # for `fe80::2`. + default 3 + depends on KCONFIG_MODULE_GNRC_NETIF +endif # MODULE_ETHOS diff --git a/examples/gnrc_border_router/Makefile b/examples/gnrc_border_router/Makefile index 48262568e85d..52581de201eb 100644 --- a/examples/gnrc_border_router/Makefile +++ b/examples/gnrc_border_router/Makefile @@ -50,8 +50,15 @@ USEMODULE += shell USEMODULE += shell_commands USEMODULE += ps -# include UHCP client -USEMODULE += gnrc_uhcpc +USE_DHCPV6 ?= 0 + +ifeq (1,$(USE_DHCPV6)) + # include DHCPv6 client for 6LoWPAN border router + USEMODULE += gnrc_dhcpv6_client_6lbr +else + # include UHCP client + USEMODULE += gnrc_uhcpc +endif # Optionally include RPL as a routing protocol. When includede gnrc_uhcpc will # configure the node as a RPL DODAG root when receiving a prefix. @@ -68,24 +75,45 @@ TAP ?= tap0 IPV6_PREFIX ?= 2001:db8::/64 ifeq (native,$(BOARD)) +ifneq (1,$(USE_DHCPV6)) TERMDEPS += uhcpd-daemon .PHONY: uhcpd-daemon uhcpd-daemon: host-tools $(RIOTTOOLS)/uhcpd/bin/uhcpd $(TAP) $(IPV6_PREFIX) & +endif # USE_DHCPV6 else # We override the `make term` command to use ethos +ifeq (1,$(USE_DHCPV6)) +TERMPROG ?= sudo $(RIOTTOOLS)/ethos/ethos +TERMFLAGS ?= $(TAP) $(PORT) $(ETHOS_BAUDRATE) +else # USE_DHCPV6 TERMPROG ?= sudo sh $(RIOTTOOLS)/ethos/start_network.sh TERMFLAGS ?= $(PORT) $(TAP) $(IPV6_PREFIX) +endif +STATIC_ROUTES ?= 1 # We depend on the ethos host tools to run the border router, we build them # if necessary TERMDEPS += host-tools endif +# As there is an 'Kconfig' we want to explicitly disable Kconfig by setting +# the variable to empty +SHOULD_RUN_KCONFIG ?= + include $(RIOTBASE)/Makefile.include +ifndef CONFIG_GNRC_DHCPV6_CLIENT_6LBR_STATIC_ROUTE +ifeq (1,$(STATIC_ROUTES)) + CFLAGS += -DCONFIG_GNRC_DHCPV6_CLIENT_6LBR_STATIC_ROUTE=1 + # CONFIG_GNRC_DHCPV6_CLIENT_6LBR_STATIC_ROUTE=1 requires one more address for + # `fe80::2`. + CFLAGS += -DCONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF=3 +endif +endif + .PHONY: host-tools host-tools: diff --git a/examples/gnrc_border_router/README.md b/examples/gnrc_border_router/README.md index ccefaeda328a..1cc15dc4e93e 100644 --- a/examples/gnrc_border_router/README.md +++ b/examples/gnrc_border_router/README.md @@ -1,8 +1,9 @@ # gnrc_border_router using automatic configuration -This setup uses a single serial interface, ethos (Ethernet Over Serial) -and UHCP (micro Host Configuration Protocol). +This setup uses a single serial interface, ethos (Ethernet Over Serial) +and UHCP (micro Host Configuration Protocol) (using DHCPv6 alternatively is also +possible). Ethos multiplexes serial data to separate ethernet packets from shell commands. -UHCP is in charge of configuring the wireless interface prefix +UHCP is in charge of configuring the wireless interface prefix and routes on the BR. The script `start_network.sh` enables a *ready-to-use* BR in only one command. @@ -11,6 +12,34 @@ The script `start_network.sh` enables a *ready-to-use* BR in only one command. This functionality works only on Linux machines. Mac OSX support will be added in the future (lack of native `tap` interface). +If you want to use DHCPv6, you also need a DHCPv6 server configured for prefix +delegation from the interface facing the border router. With the [KEA] DHCPv6 +server e.g. you can use the following configuration: + +```json +"Dhcp6": +{ + "interfaces-config": { + "interfaces": [ "tap0" ] + }, + ... + "subnet6": [ + { "interface": "tap0", + "subnet": "2001:db8::/16", + "pd-pools": [ { "prefix": "2001:db8::", + "prefix-len": 16, + "delegated-len": 64 } ] }, + ] + ... +} +``` + +Note that when working with TAP interfaces you might need to restart your DHCPv6 +server once *after* you started the border router application (see below), since +Linux might not recognize the interface as connected. + +[KEA]: https://kea.isc.org/ + ## Setup First, you need to compile `ethos`. Go to `/dist/tools/ethos` and type: @@ -32,6 +61,13 @@ Afterwards, proceed to compile and flash `gnrc_border_router` to your board: make clean all flash ``` +If you want to use DHCPv6 instead of UHCP compile with the environment variable +`USE_DHCPV6` set to 1 + +```bash +USE_DHCPV6=1 make clean all flash +``` + ## Usage Start the `start_network.sh` script by doing on `dist/tools/ethos`: @@ -39,7 +75,7 @@ Start the `start_network.sh` script by doing on `dist/tools/ethos`: sudo sh start_network.sh /dev/ttyACMx tap0 2001:db8::/64 ``` -This will execute the needed commands to setup a `tap` interface +This will execute the needed commands to setup a `tap` interface and configure the BR. Notice that this will also configure `2001:db8::/64` as a prefix. This prefix should be announced to other motes through the wireless interface. @@ -49,7 +85,7 @@ This is done through the same serial interface. By typing `help` you will get the list of available shell commands. At this point you should be able to ping motes using their global address. -For instance, if you use the [`gnrc_networking`](https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_networking) example on the mote, you can +For instance, if you use the [`gnrc_networking`](https://github.com/RIOT-OS/RIOT/tree/master/examples/gnrc_networking) example on the mote, you can ping it from your machine with: ``` @@ -57,14 +93,14 @@ ping it from your machine with: ``` Just replace this address by your mote's address. -Using `ifconfig` on the shell of your mote shows you the addresses of your +Using `ifconfig` on the shell of your mote shows you the addresses of your mote, for instance: ``` Iface 7 HWaddr: 59:72 Channel: 26 Page: 0 NID: 0x23 - Long HWaddr: 5a:46:10:6e:f2:f5:d9:72 - TX-Power: 0dBm State: IDLE max. Retrans.: 3 CSMA Retries: 4 - AUTOACK CSMA MTU:1280 HL:64 6LO RTR RTR_ADV IPHC + Long HWaddr: 5a:46:10:6e:f2:f5:d9:72 + TX-Power: 0dBm State: IDLE max. Retrans.: 3 CSMA Retries: 4 + AUTOACK CSMA MTU:1280 HL:64 6LO RTR RTR_ADV IPHC Source address length: 8 Link type: wireless inet6 addr: ff02::1/128 scope: local [multicast] @@ -74,7 +110,7 @@ Iface 7 HWaddr: 59:72 Channel: 26 Page: 0 NID: 0x23 inet6 addr: ff02::2/128 scope: local [multicast] ``` -The script also sets up a ULA (Unique Local Address) address on your +The script also sets up a ULA (Unique Local Address) address on your Linux `tap0` network interface. You can check your ULA on your PC with `ifconfig` Linux command. On this example, such address can be pinged from 6lo motes: @@ -89,7 +125,7 @@ Thus far, IPv6 communication with between your PC and your motes is enabled. You can use `ethos` as a standalone driver, if you want to setup the BR manually. ## Setup -To select ethos as the serial driver, be sure that the `Makefile` +To select ethos as the serial driver, be sure that the `Makefile` has the following: ```make @@ -133,7 +169,7 @@ make clean all flash On this RIOT BR two interfaces are present. A wired interface represents the serial link between Linux and your mote. A wireless interface represents the 802.15.4 radio link. -In order to route packets between this two interfaces, +In order to route packets between this two interfaces, you can do the following: ``` @@ -142,7 +178,7 @@ you can do the following: > fibroute add :: via dev 6 ``` -By adding the address to the wireless interface the prefix will be +By adding the address to the wireless interface the prefix will be disseminated. This prefix will be automatically added by the motes in the radio range. diff --git a/sys/net/application_layer/dhcpv6/client.c b/sys/net/application_layer/dhcpv6/client.c index 7546395baa73..e6f8e061a7ae 100644 --- a/sys/net/application_layer/dhcpv6/client.c +++ b/sys/net/application_layer/dhcpv6/client.c @@ -411,7 +411,7 @@ static int _preparse_advertise(uint8_t *adv, size_t len, uint8_t **buf) if ((cid == NULL) || (sid == NULL) || (ia_pd == NULL)) { DEBUG("DHCPv6 client: ADVERTISE does not contain either server ID, " "client ID or IA_PD option\n"); - return false; + return -1; } if (!_check_status_opt(status) || !_check_cid_opt(cid)) { return -1; @@ -466,6 +466,10 @@ static void _parse_advertise(uint8_t *adv, size_t len) /* might not have been executed when not received in first retransmission * window => redo even if already done */ if (_preparse_advertise(adv, len, NULL) < 0) { + uint32_t delay = _irt_us(DHCPV6_SOL_TIMEOUT, true); + /* SOLICIT new server */ + timer.callback = _post_solicit_servers; + xtimer_set(&timer, delay); return; } DEBUG("DHCPv6 client: scheduling REQUEST\n");