Observações Iniciais
Contexto do Ambiente
Este guia foi testado no VMware 17 Pro com Ubuntu 20.04. Os exemplso básicos do repositório tutorials funcionam, mas não há garantia de instalação 100% correta em outros cenários.
Documentação oficial da comunidade P4 disponibiliza scripts de instalação. Inicialmente, consultei tutoriais desatualizados (como os descritos em blogs de 2020) e tentei usar Ubuntu 22.04, o que gerou vários problemas. Após mudar para Ubuntu 20.04 e seguir os scripts oficiais, a instalação foi concluída com sucesso.
Transefrência de Arquivos entre Máquina Hospedeira e VM
Às vezes, o git clone falha dentro da VM. Uma alternativa é baixar o repositório na máquina hospedeira e compartilhá-lo usando as Ferramentas do VMware. Contudo, scripts .sh compartilhados do Windows podem vir no formato DOS (com \r\n), causando erros de execução. Soluções:
- Converter os arquivos com
dos2unix; - Baixar um arquivo
.zipna VM e extraí-lo diretamente.
Problemas de Desempenho com make
Comandos make ou sudo make podem causar travamentos. Prováveis causas: memória RAM insuficiente ou espaço em disco reduzido. Mesmo com 25 GB livres, o problema persistiu até aumentar a memória da VM para 8 GB e ajustar as configurações de prioridade no VMware:
- Editar → Preferências → Memória → Aumentar prioridade da VM;
- Configurações da VM → Opções → Avançado → Ajustar alocação de memória.
Instalação Passo a Passo
Criar Diretório de Trabalho
mkdir ~/p4_env
cd ~/p4_env
echo "P4_HOME=$(pwd)" >> ~/.bashrc
source ~/.bashrc
Instalar Dependências
Baseie-se nos scripts oficiais do repositório p4lang/tutorials, especificamente root-dev-bootstrap.sh e root-release-bootstrap.sh. Copie apenas os comandos apt-get e pip.
Preparação
Copie o script py3localpath.py para o diretório $HOME:
cd ~/p4_env
git clone https://github.com/p4lang/tutorials
sudo cp -p tutorials/vm-ubuntu-20.04/py3localpath.py ~
Crie um script auxiliar (setup_funcs.sh) que contém as funções definidas em user-dev-bootstrap.sh e a lógica para registrar os caminhos de instalação de cada componente.
cd ~/p4_env
touch setup_funcs.sh
chmod +x setup_funcs.sh
Conteúdo do setup_funcs.sh:
#!/bin/bash
set -xe
debug_dump_many_install_files() {
local OUT_FNAME="$1"
if [ ${DEBUG_INSTALL} -ge 2 ]; then
find /usr/lib /usr/local $HOME/.local | sort > "${OUT_FNAME}"
fi
}
PY3LOCALPATH=`${HOME}/py3localpath.py`
move_usr_local_lib_python3_from_site_packages_to_dist_packages() {
local SRC_DIR="${PY3LOCALPATH}/site-packages"
local DST_DIR="${PY3LOCALPATH}/dist-packages"
if [ ! -d ${SRC_DIR} ]; then
return 0
fi
sudo rm -fr ${SRC_DIR}/__pycache__
for j in ${SRC_DIR}/*; do
k=`basename $j`
if [ -d ${SRC_DIR}/$k -a -d ${DST_DIR}/$k ]; then
sudo mv ${SRC_DIR}/$k/* ${DST_DIR}/$k/
sudo rmdir ${SRC_DIR}/$k
else
sudo mv ${SRC_DIR}/$k ${DST_DIR}/$k
fi
done
}
debug_dump_many_install_files $HOME/usr-local-1-before-protobuf.txt
Instalação dos Componentes (um por um)
Protobuf
cd ~/p4_env
git clone https://github.com/protocolbuffers/protobuf
cd protobuf
git checkout v3.18.1
git submodule update --init --recursive
./autogen.sh
./configure --prefix=/usr
NUM_CORES=`grep -c ^processor /proc/cpuinfo`
make -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..
# Atualiza o arquivo de dump
sed -i '$s|.*|debug_dump_many_install_files $HOME/usr-local-2-after-protobuf.txt|' setup_funcs.sh
./setup_funcs.sh
gRPC
cd ~/p4_env
git clone https://github.com/grpc/grpc.git
cd grpc
git checkout tags/v1.43.2
git submodule update --init --recursive
mkdir -p cmake/build
cd cmake/build
cmake ../..
make -j$(nproc)
sudo make install
cd ../..
sudo pip3 install Cython==0.29.35
sudo pip3 install -r requirements.txt
GRPC_PYTHON_BUILD_WITH_CYTHON=1 sudo pip3 install .
sudo ldconfig
cd ..
sed -i '$s|.*|debug_dump_many_install_files $HOME/usr-local-3-after-grpc.txt|' setup_funcs.sh
./setup_funcs.sh
PI / P4Runtime
Se faltar a depandência nanomsg, clone a versão adequada do repositório p4lang/PI e instale manualmente.
cd ~/p4_env
git clone https://github.com/p4lang/PI.git
cd PI
git checkout f043e6f5f4271076ad7e58aa9889c82dbfc8c3ca
git submodule update --init --recursive
./autogen.sh
./configure --with-proto
make -j$(nproc)
sudo make install
make clean
sudo ldconfig
cd ..
sed -i '$s|.*|debug_dump_many_install_files $HOME/usr-local-4-after-PI.txt|' setup_funcs.sh
./setup_funcs.sh
Bmv2
cd ~/p4_env
git clone https://github.com/p4lang/behavioral-model.git
cd behavioral-model
git checkout 6ee70b5eff7f510b32c074aaa4f00358f594fecb
./install_deps.sh
./autogen.sh
./configure --enable-debugger --with-pi --with-thrift
make -j$(nproc)
sudo make install-strip
sudo ldconfig
cd ..
sed -i '$s|.*|debug_dump_many_install_files $HOME/usr-local-5-after-behavioral-model.txt|' setup_funcs.sh
./setup_funcs.sh
P4C
Compile com apenas um processo paralelo para evitar falta de memória.
cd ~/p4_env
git clone https://github.com/p4lang/p4c
cd p4c
git checkout c7a503d5b6f5711cf61e7e2878eaa670fd90c71d
git submodule update --init --recursive
mkdir -p build
cd build
cmake .. -DENABLE_TEST_TOOLS=ON
make -j1
sudo make install
sudo ldconfig
cd ../..
sed -i '$s|.*|debug_dump_many_install_files $HOME/usr-local-6-after-p4c.txt|' setup_funcs.sh
./setup_funcs.sh
Mininet
cd ~/p4_env
git clone https://github.com/mininet/mininet mininet
cd mininet
git checkout 5b1b376336e1c6330308e64ba41baac6976b6874
# Aplica patch necessário (caso exista)
PATCH_DIR="${HOME}/patches"
if [ -f "${PATCH_DIR}/mininet-patch-for-2023-jun.patch" ]; then
patch -p1 < "${PATCH_DIR}/mininet-patch-for-2023-jun.patch"
fi
cd ..
sudo ./mininet/util/install.sh -nw
find /usr/lib /usr/local $HOME/.local | sort > $HOME/usr-local-7-after-mininet-install.txt
PTF
cd ~/p4_env
git clone https://github.com/p4lang/ptf
cd ptf
git checkout d2e2d8ad005a451ad11f9d21af50079a0552921a
sudo pip3 install .
cd ..
sed -i '$s|.*|debug_dump_many_install_files $HOME/usr-local-8-after-ptf-install.txt|' setup_funcs.sh
./setup_funcs.sh
Teste de Instalação
Execute o exemplo básico do tutorial:
cd $P4_HOME/tutorials/exercises/basic
sudo cp -p solution/basic.p4 .
Inicie o ambiente:
make run
No Mininet, teste a conectividade:
mininet> h1 ping h2
mininet> pingall
Abra terminais para os hosts:
mininet> xterm h1 h2
No terminal do h2:
./receive.py
No terminal do h1:
./send.py 10.0.2.2 "P4 is cool"
Se receber o erro /usr/bin/env python3\r: No such file or directory, converta os arquivos:
sudo apt install dos2unix
dos2unix receive.py send.py
Para sair:
mininet> exit
make stop
make clean