Merge pull request #13424 from miri64/examples/enh/dhcpv6-br

examples/gnrc_border_router: add optional DHCPv6 support
This commit is contained in:
Martine Lenders 2020-02-25 20:08:31 +01:00 committed by GitHub
commit ec6c07d35d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 16 deletions

View File

@ -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

View File

@ -50,8 +50,15 @@ USEMODULE += shell
USEMODULE += shell_commands USEMODULE += shell_commands
USEMODULE += ps USEMODULE += ps
# include UHCP client USE_DHCPV6 ?= 0
USEMODULE += gnrc_uhcpc
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 # Optionally include RPL as a routing protocol. When includede gnrc_uhcpc will
# configure the node as a RPL DODAG root when receiving a prefix. # configure the node as a RPL DODAG root when receiving a prefix.
@ -68,24 +75,45 @@ TAP ?= tap0
IPV6_PREFIX ?= 2001:db8::/64 IPV6_PREFIX ?= 2001:db8::/64
ifeq (native,$(BOARD)) ifeq (native,$(BOARD))
ifneq (1,$(USE_DHCPV6))
TERMDEPS += uhcpd-daemon TERMDEPS += uhcpd-daemon
.PHONY: uhcpd-daemon .PHONY: uhcpd-daemon
uhcpd-daemon: host-tools uhcpd-daemon: host-tools
$(RIOTTOOLS)/uhcpd/bin/uhcpd $(TAP) $(IPV6_PREFIX) & $(RIOTTOOLS)/uhcpd/bin/uhcpd $(TAP) $(IPV6_PREFIX) &
endif # USE_DHCPV6
else else
# We override the `make term` command to use ethos # 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 TERMPROG ?= sudo sh $(RIOTTOOLS)/ethos/start_network.sh
TERMFLAGS ?= $(PORT) $(TAP) $(IPV6_PREFIX) TERMFLAGS ?= $(PORT) $(TAP) $(IPV6_PREFIX)
endif
STATIC_ROUTES ?= 1
# We depend on the ethos host tools to run the border router, we build them # We depend on the ethos host tools to run the border router, we build them
# if necessary # if necessary
TERMDEPS += host-tools TERMDEPS += host-tools
endif 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 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 .PHONY: host-tools
host-tools: host-tools:

View File

@ -1,8 +1,9 @@
# gnrc_border_router using automatic configuration # gnrc_border_router using automatic configuration
This setup uses a single serial interface, ethos (Ethernet Over Serial) This setup uses a single serial interface, ethos (Ethernet Over Serial)
and UHCP (micro Host Configuration Protocol). and UHCP (micro Host Configuration Protocol) (using DHCPv6 alternatively is also
possible).
Ethos multiplexes serial data to separate ethernet packets from shell commands. 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. and routes on the BR.
The script `start_network.sh` enables a *ready-to-use* BR in only one command. 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. This functionality works only on Linux machines.
Mac OSX support will be added in the future (lack of native `tap` interface). 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 ## Setup
First, you need to compile `ethos`. First, you need to compile `ethos`.
Go to `/dist/tools/ethos` and type: 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 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 ## Usage
Start the `start_network.sh` script by doing on `dist/tools/ethos`: 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 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. and configure the BR.
Notice that this will also configure `2001:db8::/64` as a prefix. Notice that this will also configure `2001:db8::/64` as a prefix.
This prefix should be announced to other motes through the wireless interface. 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. 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. 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: 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. 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: mote, for instance:
``` ```
Iface 7 HWaddr: 59:72 Channel: 26 Page: 0 NID: 0x23 Iface 7 HWaddr: 59:72 Channel: 26 Page: 0 NID: 0x23
Long HWaddr: 5a:46:10:6e:f2:f5:d9:72 Long HWaddr: 5a:46:10:6e:f2:f5:d9:72
TX-Power: 0dBm State: IDLE max. Retrans.: 3 CSMA Retries: 4 TX-Power: 0dBm State: IDLE max. Retrans.: 3 CSMA Retries: 4
AUTOACK CSMA MTU:1280 HL:64 6LO RTR RTR_ADV IPHC AUTOACK CSMA MTU:1280 HL:64 6LO RTR RTR_ADV IPHC
Source address length: 8 Source address length: 8
Link type: wireless Link type: wireless
inet6 addr: ff02::1/128 scope: local [multicast] 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] 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. Linux `tap0` network interface.
You can check your ULA on your PC with `ifconfig` Linux command. You can check your ULA on your PC with `ifconfig` Linux command.
On this example, such address can be pinged from 6lo motes: 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. You can use `ethos` as a standalone driver, if you want to setup the BR manually.
## Setup ## 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: has the following:
```make ```make
@ -133,7 +169,7 @@ make clean all flash
On this RIOT BR two interfaces are present. On this RIOT BR two interfaces are present.
A wired interface represents the serial link between Linux and your mote. A wired interface represents the serial link between Linux and your mote.
A wireless interface represents the 802.15.4 radio link. 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: you can do the following:
``` ```
@ -142,7 +178,7 @@ you can do the following:
> fibroute add :: via <link-local of tap> dev 6 > fibroute add :: via <link-local of tap> 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. disseminated.
This prefix will be automatically added by the motes in the radio range. This prefix will be automatically added by the motes in the radio range.

View File

@ -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)) { if ((cid == NULL) || (sid == NULL) || (ia_pd == NULL)) {
DEBUG("DHCPv6 client: ADVERTISE does not contain either server ID, " DEBUG("DHCPv6 client: ADVERTISE does not contain either server ID, "
"client ID or IA_PD option\n"); "client ID or IA_PD option\n");
return false; return -1;
} }
if (!_check_status_opt(status) || !_check_cid_opt(cid)) { if (!_check_status_opt(status) || !_check_cid_opt(cid)) {
return -1; 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 /* might not have been executed when not received in first retransmission
* window => redo even if already done */ * window => redo even if already done */
if (_preparse_advertise(adv, len, NULL) < 0) { 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; return;
} }
DEBUG("DHCPv6 client: scheduling REQUEST\n"); DEBUG("DHCPv6 client: scheduling REQUEST\n");