Skip to content

Commit

Permalink
Merge pull request #13424 from miri64/examples/enh/dhcpv6-br
Browse files Browse the repository at this point in the history
examples/gnrc_border_router: add optional DHCPv6 support
  • Loading branch information
miri64 committed Feb 25, 2020
2 parents f688f84 + a0b0724 commit ec6c07d
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 16 deletions.
10 changes: 10 additions & 0 deletions 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
32 changes: 30 additions & 2 deletions examples/gnrc_border_router/Makefile
Expand Up @@ -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.
Expand All @@ -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:
Expand Down
62 changes: 49 additions & 13 deletions 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.
Expand All @@ -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:
Expand All @@ -32,14 +61,21 @@ 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`:

```bash
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.
Expand All @@ -49,22 +85,22 @@ 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:

```
> ping6 2001:db8:0:1234:0:567:8:1
```

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]
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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:

```
Expand All @@ -142,7 +178,7 @@ you can do the following:
> 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.
This prefix will be automatically added by the motes in the radio range.

Expand Down
6 changes: 5 additions & 1 deletion sys/net/application_layer/dhcpv6/client.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit ec6c07d

Please sign in to comment.