O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Simular uma rede Thread usando OpenThread no Docker

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

1. Introdução

26b7f4f6b3ea0700.png.

O OpenThread lançado pelo Google é uma implementação de código aberto do protocolo de rede Thread. O Google Nest lançou o OpenThread para disponibilizar aos desenvolvedores a tecnologia usada nos produtos Nest para acelerar o desenvolvimento de produtos para a casa conectada.

A especificação da linha de execução define um protocolo de comunicação dispositivo a dispositivo sem fio confiável, seguro e de baixo consumo energético IPv6 para aplicativos domésticos. O OpenThread implementa todas as camadas de rede Thread, incluindo IPv6, 6LoWPAN, IEEE 802.15.4 com segurança MAC, estabelecimento de link de malha e roteamento de malha.

Este codelab vai orientar você a simular uma rede Thread em dispositivos emulados usando o Docker.

O que você vai aprender

  • Como configurar o conjunto de ferramentas de compilação do OpenThread
  • Como simular uma rede Thread
  • Como autenticar nós de Thread
  • Como gerenciar uma rede Thread com o Daemon do OpenThread

O que é necessário

  • Docker
  • Conhecimento básico do Linux e do roteamento de rede

2. Configurar o Docker

Este codelab foi projetado para usar o Docker em uma máquina Linux, Mac OS X ou Windows. O Linux é o ambiente recomendado.

Instalar o Docker

Instale o Docker no SO de sua preferência.

Extrair a imagem do Docker

Depois que o Docker for instalado, abra uma janela do terminal e extraia a imagem do Docker openthread/environment. Esta imagem apresenta o OpenThread e o OpenThread Daemon pré-criados e prontos para uso neste codelab.

$ docker pull openthread/environment:latest

O download completo pode demorar alguns minutos.

Em uma janela do terminal, inicie um contêiner do Docker na imagem e conecte-se ao shell bash:

$ docker run --name codelab_otsim_ctnr -it --rm \
   --sysctl net.ipv6.conf.all.disable_ipv6=0 \
   --cap-add=net_admin openthread/environment bash

Observe as sinalizações necessárias para este codelab:

  • --sysctl net.ipv6.conf.all.disable_ipv6=0: ativa o IPv6 no contêiner.
  • --cap-add=net_admin: ativa o recurso NET_ADMIN, que permite executar operações relacionadas à rede, como adicionar rotas de IP

Uma vez no contêiner, você vai ver um prompt semelhante a este:

root@c0f3912a74ff:/#

No exemplo acima, o c0f3912a74ff é o ID do contêiner. O ID do contêiner da sua instância do contêiner do Docker será diferente do que aparece nas instruções deste codelab.

Como usar o Docker

Este codelab pressupõe que você aprendeu os conceitos básicos de uso do Docker. Você deve permanecer no contêiner do Docker durante todo o codelab.

3. Simular uma rede Thread

O aplicativo de exemplo que você usará para este codelab demonstra um aplicativo mínimo do OpenThread que expõe a interface de configuração e gerenciamento do OpenThread por meio de uma interface de linha de comando (CLI) básica.

Esse exercício guia você pelas etapas mínimas necessárias para dar ping a um dispositivo Thread emulado em outro dispositivo Thread emulado.

A figura abaixo descreve uma topologia de rede Thread básica. Para este exercício, emularemos os dois nós dentro do círculo verde: um líder de linha de execução e um roteador de linha de execução com uma única conexão entre eles.

6e3aa07675f902dc.png

Criar a rede

1. Iniciar nó 1

Se você ainda não tiver feito isso, em uma janela de terminal, inicie o contêiner do Docker e conecte-se ao shell bash:

$ docker run --name codelab_otsim_ctnr -it --rm \
   --sysctl net.ipv6.conf.all.disable_ipv6=0 \
   --cap-add=net_admin openthread/environment bash

No contêiner do Docker, crie o processo da CLI para um dispositivo Thread emulado usando o binário ot-cli-ftd.

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1

Observação: se o prompt > não for exibido depois que o comando for executado, pressione enter.

Esse binário implementa um dispositivo OpenThread. O driver de rádio IEEE 802.15.4 é implementado sobre UDP (os frames IEEE 802.15.4 são transmitidos em payloads UDP).

O argumento de 1 é um descritor de arquivo que representa os bits menos significativos do IEEE EUI-64 da configuração original para o dispositivo emulado. Esse valor também é usado ao vincular uma porta UDP para emulação de rádio IEEE 802.15.4 (porta = 9000 + descritor de arquivo). Cada instância de um dispositivo Thread emulado neste codelab usará um descritor de arquivo diferente.

Observação:use descritores de arquivos de 1 ou mais, como indicado neste codelab, ao criar o processo para um dispositivo emulado. Um descritor de arquivo 0 é reservado para outro uso.

Criar um conjunto de dados operacional e confirmá-lo como ativo. O conjunto de dados operacional é a configuração para a rede Thread que você está criando.

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 20
Channel Mask: 07fff800
Ext PAN ID: d6263b6d857647da
Mesh Local Prefix: fd61:2344:9a52:ede0/64
Network Key: e4344ca17d1dca2a33f064992f31f786
Network Name: OpenThread-c169
PAN ID: 0xc169
PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4
Security Policy: 0, onrcb
Done

Confirme que este conjunto de dados é o ativo:

> dataset commit active
Done

Mostrar a interface IPv6:

> ifconfig up
Done

Inicie a operação do protocolo Thread:

> thread start
Done

Aguarde alguns segundos e verifique se o dispositivo se tornou o Líder em linhas de execução. O líder é o dispositivo responsável por gerenciar a atribuição de IDs do roteador.

> state
leader
Done

Ver os endereços IPv6 atribuídos à interface Thread do Node 1' sua saída será diferente:

> ipaddr
fd61:2344:9a52:ede0:0:ff:fe00:fc00
fd61:2344:9a52:ede0:0:ff:fe00:5000
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
fe80:0:0:0:94da:92ea:1353:4f3b
Done

Observe os tipos específicos de endereço IPv6:

  • Começa com fd = mesh-local
  • Começa com fe80 = link-local

Os tipos de endereço locais de malha são classificados ainda mais:

  • Contém ff:fe00 = Localizador de roteadores (RLOC)
  • Não contém ff:fe00 = identificador de endpoint (EID)

Identifique o EID na saída do seu console e anote-o para uso posterior. No exemplo de saída acima, o EID é:

fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6

2. Iniciar nó 2

Abra um novo terminal e execute um shell bash no contêiner do Docker em execução para usar no Node 2.

$ docker exec -it codelab_otsim_ctnr bash

Nesse novo prompt bash, crie o processo da CLI com o argumento 2. Este é o segundo dispositivo Thread emulado:

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2

Observação: se o prompt > não for exibido depois que o comando for executado, pressione enter.

Configure a chave de rede e a ID da PAN usando as mesmas valores do conjunto de dados operacional do nó 1:

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

Confirme que este conjunto de dados é o ativo:

> dataset commit active
Done

Mostrar a interface IPv6:

> ifconfig up
Done

Inicie a operação do protocolo Thread:

> thread start
Done

O dispositivo será inicializado como um filho. Um filho do Thread é equivalente a um dispositivo final, que é um dispositivo do Thread que transmite e recebe tráfego unicast somente com um dispositivo pai.

> state
child
Done

Em dois minutos, você verá a mudança de estado de child para router. Um roteador de linha de execução é capaz de rotear tráfego entre dispositivos. Também é conhecido como pai/mãe.

> state
router
Done

Verifique a rede

Uma maneira fácil de verificar a rede mesh é analisar a tabela do roteador.

1. Verificar conectividade

No Nó 2, acesse o RLOC16. O RLOC16 são os últimos 16 bits do endereço IPv6 do RLOC do dispositivo.

> rloc16
5800
Done

No Nó 1, verifique na tabela do roteador o RLOC16 do Nó 2. Certifique-se de que o Nó 2 tenha mudado para o estado do roteador primeiro.

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In  | LQ Out  | Age | Extended MAC   |
+----+--------+----------+-----------+--------+-------+---+--------------------+
| 20 | 0x5000 |       63 |         0 |      0 |     0 |   0 | 96da92ea13534f3b |
| 22 | 0x5800 |       63 |         0 |      3 |     3 |  23 | 5a4eb647eb6bc66c |

O RLOC de 0x5800 do nó 2 & foi encontrado na tabela, confirmando que ele está conectado à malha.

2. Dê um ping no nó 1 do nó 2

Verifique a conectividade entre os dois dispositivos Thread emulados. No Nó 2, ping o EID atribuído ao Nó 1:

> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
> 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1 hlim=64 time=12ms

Pressione enter para retornar ao prompt da CLI >.

Testar a rede

Agora que você pode dar um ping entre dois dispositivos Thread emulados, teste a rede mesh colocando um nó off-line.

Volte ao Nó 1 e interrompa a conversa:

> thread stop
Done

Alterne para o Nó 2 e verifique o estado. Em dois minutos, o nó 2 detecta que o líder (nó 1) está off-line, e você verá o nó 2 ser o leader da rede:

> state
router
Done
...
> state
leader
Done

Após a confirmação, interrompa a linha de execução e redefina o nó para a configuração original antes de retornar ao prompt bash do Docker. Uma redefinição para a configuração original é feita para garantir que as credenciais da rede Thread que usamos neste exercício não sejam transferidas para o próximo exercício.

> thread stop
Done
> factoryreset
>
> exit
root@c0f3912a74ff:/#

Talvez seja necessário pressionar enter algumas vezes para retornar o prompt > após um comando factoryreset. Não saia do contêiner do Docker.

Você também pode redefinir para a configuração original e sair do Nó 1:

> factoryreset
>
> exit
root@c0f3912a74ff:/#

Consulte a Referência da CLI do OpenThread para ver todos os comandos disponíveis da CLI.

4. Autenticar nós com comissionamento

No exercício anterior, você configurou uma rede Thread com dois dispositivos simulados e conectividade verificada. No entanto, isso só permite que o tráfego local de link IPv6 não autenticado passe entre dispositivos. Para rotear o tráfego IPv6 global entre eles e a Internet usando um roteador de borda do Thread, os nós precisam ser autenticados.

Para autenticar, um dispositivo precisa funcionar como um comissário. O Commissioner é o servidor de autenticação atualmente escolhido para novos dispositivos Thread e o autorizador que fornece as credenciais de rede necessárias para que os dispositivos participem da rede.

Neste exercício, usaremos a mesma topologia de dois nós de antes. Para a autenticação, o líder da linha de execução vai atuar como o comissário, o roteador de linha de execução como um Combinador.

d6a67e8a0d0b5dcb.png

Docker

Para cada nó (janela do terminal) nos exercícios restantes, verifique se você está executando o contêiner do Docker com o build OpenThread. Se você continuar do exercício anterior, ainda terá duas solicitações bash no mesmo contêiner do Docker já abertas. Caso contrário, consulte a etapa Solução de problemas do Docker ou simplesmente refaça o exercício Simular uma rede Thread.

1. Criar uma rede

No Nó 1, gere o processo da CLI:

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1

Observação: se o prompt > não for exibido depois que o comando for executado, pressione enter.

Crie um novo conjunto de dados operacional, confirme-o como o ativo e inicie a Thread:

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 12
Channel Mask: 07fff800
Ext PAN ID: e68d05794bf13052
Mesh Local Prefix: fd7d:ddf7:877b:8756/64
Network Key: a77fe1d03b0e8028a4e13213de38080e
Network Name: OpenThread-8f37
PAN ID: 0x8f37
PSKc: f9debbc1532487984b17f92cd55b21fc
Security Policy: 0, onrcb
Done

Confirme que este conjunto de dados é o ativo:

> dataset commit active
Done

Mostrar a interface IPv6:

> ifconfig up
Done

Inicie a operação do protocolo Thread:

> thread start
Done

Aguarde alguns segundos e verifique se o dispositivo se tornou um Líder em linhas de execução:

> state
leader
Done

2. Começar a função de Comissário

Enquanto ainda estiver no Node 1, inicie o papel de Comissário:

> commissioner start
Done

Permita que qualquer Combinador (usando o caractere curinga *) com a credencial de Joiner J01NME para comissionar na rede. Um Combinador é um dispositivo adicionado por um administrador humano a uma rede Thread encomendada.

> commissioner joiner add * J01NME
Done

3. Iniciar a função de Combinador

Em uma segunda janela do terminal, no contêiner do Docker, crie um novo processo da CLI. Este é o Nó 2.

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2

No nó 2, ative o papel de Combinador usando a credencial de combinador J01NME.

> ifconfig up
Done
> joiner start J01NME
Done

... aguarde alguns segundos para confirmar ...

Join success

Como combinador, o dispositivo (Nó 2) foi autenticado corretamente com o Comissário (Nó 1) e recebeu as credenciais da Rede de linhas de execução.

Agora que o Node 2 está autenticado, inicie a Thread:

> thread start
Done

4. Validar autenticação de rede

Verifique o state no Nó 2 para validar se ele agora entrou na rede. Em dois minutos, o Nó 2 fará a transição de child para router:

> state
child
Done
...
> state
router
Done

5. Redefinir configuração

Para se preparar para o próximo exercício, redefina a configuração. Em cada nó, interrompa a linha de execução, faça uma redefinição para a configuração original e saia do dispositivo emulado:

> thread stop
Done
> factoryreset
>
> exit
root@c0f3912a74ff:/#

Talvez seja necessário pressionar enter algumas vezes para retornar o prompt > após um comando factoryreset.

5. Gerenciar a rede com o OpenThread Daemon

Para este exercício, vamos simular uma instância da CLI (um único dispositivo SoC Thread incorporado) e uma instância do Radio Coprocessador (RCP).

ot-daemon é um modo do app OpenThread Posix que usa um soquete UNIX como entrada e saída. Assim, o núcleo do OpenThread pode ser executado como um serviço. O cliente pode se comunicar com esse serviço se conectando ao soquete usando a CLI do OpenThread como protocolo.

ot-ctl é uma CLI fornecida por ot-daemon para gerenciar e configurar o RCP. Usando isso, vamos conectar o RCP à rede criada pelo dispositivo Thread.

Docker

Para cada nó (janela do terminal) neste exercício, verifique se você está executando o contêiner do Docker com o build do OpenThread. Se você continuar do exercício anterior, terá duas solicitações bash no mesmo contêiner do Docker já abertas. Caso contrário, consulte a etapa Solução de problemas do Docker.

Usar ot-daemon

Este exercício usará três janelas de terminal, correspondentes ao seguinte:

  1. Instância da CLI do dispositivo Thread simulado (nó 1)
  2. Processo ot-daemon
  3. Instância da CLI ot-ctl

1. Iniciar nó 1

Na primeira janela do terminal, crie o processo da CLI para seu dispositivo Thread emulado:

root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1

Observação:se o prompt > não for exibido depois que o comando for executado, pressione enter.

Crie um novo conjunto de dados operacional, confirme-o como o ativo e inicie a Thread:

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 13
Channel Mask: 07fff800
Ext PAN ID: 97d584bcd493b824
Mesh Local Prefix: fd55:cf34:dea5:7994/64
Network Key: ba6e886c7af50598df1115fa07658a83
Network Name: OpenThread-34e4
PAN ID: 0x34e4
PSKc: 38d6fd32c866927a4dfcc06d79ae1192
Security Policy: 0, onrcb
Done

Confirme que este conjunto de dados é o ativo:

> dataset commit active
Done

Mostrar a interface IPv6:

> ifconfig up
Done

Inicie a operação do protocolo Thread:

> thread start
Done

Ver os endereços IPv6 atribuídos à interface Thread do Node 1&#39:

> ipaddr
fd55:cf34:dea5:7994:0:ff:fe00:fc00
fd55:cf34:dea5:7994:0:ff:fe00:d000
fd55:cf34:dea5:7994:460:872c:e807:c4ab
fe80:0:0:0:9cd8:aab6:482f:4cdc
Done
>

Conforme explicado na etapa Simular uma rede Thread, um endereço é link-local (fe80) e três são locais de malha (fd). O EID é o endereço local mesh que não contém ff:fe00 no endereço. Nesta saída de exemplo, o EID é fd55:cf34:dea5:7994:460:872c:e807:c4ab.

Identifique o EID específico da saída do ipaddr, que será usada para se comunicar com o nó.

2. Iniciar ot-daemon

Na segunda janela do terminal, crie um nó de dispositivo tun e defina as permissões de leitura/gravação:

root@c0f3912a74ff:/# mkdir -p /dev/net && mknod /dev/net/tun c 10 200
root@c0f3912a74ff:/# chmod 600 /dev/net/tun

Este dispositivo é usado para transmissão e recebimento de pacotes em dispositivos virtuais. Você pode receber um erro se o dispositivo já tiver sido criado. Isso é normal e pode ser ignorado.

Inicie o ot-daemon para um nó do RCP, que chamaremos de Nó 2. Use a sinalização detalhada -v para ver a saída do registro e confirmar se ela está em execução:

root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-daemon -v \
'spinel+hdlc+forkpty:///openthread/build/examples/apps/ncp/ot-rcp?forkpty-arg=2'

Quando bem-sucedido, ot-daemon no modo detalhado gera uma saída semelhante a esta:

ot-daemon[31]: Running OPENTHREAD/297a880; POSIX; Feb  1 2022 04:43:39
ot-daemon[31]: Thread version: 3
ot-daemon[31]: Thread interface: wpan0
ot-daemon[31]: RCP version: OPENTHREAD/297a880; SIMULATION; Feb  1 2022 04:42:50

Deixe o terminal aberto e em execução em segundo plano. Não é preciso inserir mais comandos.

3. Use o ot-ctl para participar da rede

Ainda não encomendamos o Nó 2 (o RCP ot-daemon) a nenhuma rede Thread. É aí que entra o ot-ctl. O ot-ctl usa a mesma CLI que o app de CLI do OpenThread. Portanto, você pode controlar os nós ot-daemon da mesma forma que os outros dispositivos simulados do Thread.

Abra uma terceira janela de terminal e execute o contêiner atual:

$ docker exec -it codelab_otsim_ctnr bash

No contêiner, inicie ot-ctl:

root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-ctl
>

Você usará o ot-ctl nessa terceira janela de terminal para gerenciar o Nó 2 (o nó do RCP) iniciado na segunda janela do terminal com ot-daemon. Verifique o state do nó 2:

> state
disabled
Done

Acesse o eui64 do nó 2 e para restringir a mesclagem ao Joiner específico:

> eui64
18b4300000000001
Done

No Nó 1 (primeira janela do terminal), inicie o Comissário e restrinja a participação apenas a esse eui64:

> commissioner start
Done
> commissioner joiner add 18b4300000000001 J01NME
Done

Na terceira janela do terminal, abra a interface de rede do nó 2 e conecte-se à rede:

> ifconfig up
Done
> joiner start J01NME
Done

... aguarde alguns segundos para confirmar ...

Join success

Como Combinador, o RCP (nó 2) foi autenticado com sucesso pelo Comissário (nó 1) e recebeu as credenciais da rede Thread.

Agora junte-se ao Nó 2 na rede Thread (na terceira janela do terminal):

> thread start
Done

4. Validar autenticação de rede

No terceiro terminal, verifique o state no Nó 2 para validar se ele agora entrou na rede. Em dois minutos, o Nó 2 fará a transição de child para router:

> state
child
Done
...
> state
router
Done

5. Validar a conectividade

Na terceira janela do terminal, saia de ot-ctl usando o comando Ctrl+D ou exit e volte ao console bash do container. Neste console, dê um ping no nó 1 usando o EID com o comando ping6. Se a instância do RCP ot-daemon for mesclada e se comunicar com a rede Thread, o ping terá êxito:

root@c0f3912a74ff:/# ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab
PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms
--- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms

6. Solução de problemas do Docker

Se você tiver fechado o contêiner do Docker

bash prompts, talvez seja necessário verificar se ele está em execução e reiniciar / inserir novamente, conforme necessário.

Para mostrar quais contêineres do Docker estão em execução:

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
505fc57ffc72        environment       "bash"              10 minutes ago      Up 10 minutes                           codelab_otsim_ctnr

Para mostrar todos os contêineres do Docker (em execução e interrompidos):

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
505fc57ffc72        environment       "bash"              10 minutes ago      Up 10 minutes                           codelab_otsim_ctnr

Se você não vir o contêiner codelab_otsim_ctnr na saída de qualquer um dos comandos docker ps, execute-o novamente:

$ docker run --name codelab_otsim_ctnr -it --rm \
   --sysctl net.ipv6.conf.all.disable_ipv6=0 \
   --cap-add=net_admin openthread/environment bash

Se o contêiner estiver parado (listado em docker ps -a, mas não docker ps), reinicie-o:

$ docker start -i codelab_otsim_ctnr

Se o contêiner do Docker já estiver em execução (listado em docker ps), reconecte-se ao contêiner em cada terminal:

$ docker exec -it codelab_otsim_ctnr bash

"Operação não permitida"

Se você encontrar erros Operation not permitted ao criar novos nós do OpenThread (usando o comando mknod), verifique se está executando o Docker como usuário raiz, de acordo com os comandos fornecidos neste codelab. Este codelab não é compatível com a execução do Docker no modo sem acesso root.

7. Parabéns!

Você simula a primeira rede Thread usando o OpenThread. Incrível!

Neste codelab, você aprendeu a:

  • Iniciar e gerenciar o contêiner do Docker de simulação do OpenThread
  • Simular uma rede Thread
  • Autenticar nós de Thread
  • Gerenciar uma rede Thread com o Daemon do OpenThread

Para saber mais sobre o Thread e o OpenThread, confira estas referências:

Ou tente usar o OpenThread Border Router em um contêiner do Docker.