Skip to content

Commit

Permalink
Merge pull request #66 from ResidenciaTICBrisa/connect-to-nao
Browse files Browse the repository at this point in the history
Conecta máquina virtual aos NAOv4 e NAOv6
  • Loading branch information
damarcones authored Oct 14, 2023
2 parents f62153a + af9b4bc commit 3074edd
Show file tree
Hide file tree
Showing 10 changed files with 372 additions and 4 deletions.
68 changes: 66 additions & 2 deletions scripts/vms/ubuntu-14/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ These scripts need the following packages to be installed on the host's system
|qemu-utils |6.2.0 |
|qemu-system-gui |6.2.0 |
|qemu-block-extra|6.2.0 |
|ovmf |2022.11|
|libguestfs-tools|1.48.6 |
|ovmf |2022.02|
|libguestfs-tools|1.46.2 |
|iproute2 |5.15 |
|nftables |1.0.2 |

The scripts assume that KVM-based accelerated virtualisation is enabled on the
host machine. This requires a compatible processor and it may require a
Expand Down Expand Up @@ -232,3 +234,65 @@ SDK was added to the *worktree*. It is the default toolchain configuration.
- `NAOQI_QIBUILD_CTC_CONFIG`: the name of the configuration in the *worktree*.
It can be used to replace the C++ SDK as the project's toolchain in order to
create a binary that can be transfered to the robot.

### Basic project setup

The following steps will create and build a C++ SDK-based project on the
configured *worktree*:

```bash
cd "${NAO_QIBUILD_WORKSPACE}"
qisrc create my-project
cd my-project
qibuild configure
qibuild make
```

The C++ SDK is configured as the default toolchain. If you wish to set up a
project with an explicit configuration and build setup, you may run:

```bash
cd "${NAO_QIBUILD_WORKSPACE}"
qisrc create my-project
cd my-project
qibuild configure -c "${NAOQI_CPP_QIBUILD_CONFIG}" my-project
qibuild make -c "${NAOQI_CPP_QIBUILD_CONFIG}" my-project
```

Compiling a project that will be run on the robot requires an explicit
configuration to replace the default toolchain by the cross-compilation one
(NAO CTC):

```bash
cd "${NAO_QIBUILD_WORKSPACE}"
qisrc create my-project
cd my-project
qibuild configure -c "${NAOQI_QIBUILD_CTC_CONFIG}"
qibuild make -c "${NAOQI_QIBUILD_CTC_CONFIG}"
```

## Connecting to the Robot

There are three scripts that are used when connecting the Virtual Machine to
your NAO:

1. `enable-nat-bridge-network.sh`: this script must be run with elevated
privileges to set a bridge with a bound DHCP server and a NAT masquerade up
2. `run-nat-bridge.sh`: this script executes the VM with connectivity to the
previously configured bridge. This is achieved by a `tap` device that QEMU will
automatically add to the bridge using `/usr/lib/qemu/qemu-bridge-helper` and
`/etc/qemu/bridge.conf`. It may be executed by a common user.
3. `disable-nat-bridge-network.sh`: this script must be run with elevated
privileges to undo all the modifications made by the NAT enabler script.

### Warning to Docker users

Docker overrides all user firewall configurations. The scripts currently
require a standard firewall configuration, so it will be necessary to remove
all tables and rules created by Docker. It is recommended to stop Docker with
`systemctl stop docker.service docker.socket` to avoid a surprise firewall
reconfiguration event.

You should be able to reset nftables to its standard configuration using the
command: `nft flush ruleset`. This will break the network for the containers
until the machine or the Docker service unit are restarted.
15 changes: 15 additions & 0 deletions scripts/vms/ubuntu-14/disable-nat-bridge-network.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

source './env-vars.sh'

chmod -v 0755 /usr/lib/qemu/qemu-bridge-helper
rm -v /etc/qemu/bridge.conf

sysctl "net.ipv4.conf.${BRIDGE}.forwarding=0"
sysctl "net.ipv6.conf.${BRIDGE}.forwarding=0"

ip link set "${BRIDGE}" down
ip link delete "${BRIDGE}" type bridge

nft delete table inet "${QEMU_NAT_TABLE}"
nft delete table inet "${QEMU_FILTER_TABLE}"
34 changes: 34 additions & 0 deletions scripts/vms/ubuntu-14/enable-nat-bridge-network.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

source './env-vars.sh'

abort_if_iproute2_not_found
abort_if_nftables_not_found
abort_if_interface_not_found

chmod -v 4755 /usr/lib/qemu/qemu-bridge-helper
printf 'allow %s\n' "${BRIDGE}" > /etc/qemu/bridge.conf
chmod -v 0644 /etc/qemu/bridge.conf

ip link add "${BRIDGE}" type bridge
ip link set "${BRIDGE}" up
# Must be in a different network than your current one
ip address add "${BRIDGE_IP}" dev "${BRIDGE}"

sysctl "net.ipv4.conf.${BRIDGE}.forwarding=1"
sysctl "net.ipv6.conf.${BRIDGE}.forwarding=1"

nft add table inet "${QEMU_FILTER_TABLE}"
nft add chain inet "${QEMU_FILTER_TABLE}" input '{ type filter hook input priority filter; }'
nft add chain inet "${QEMU_FILTER_TABLE}" output '{ type filter hook output priority filter; }'
nft add chain inet "${QEMU_FILTER_TABLE}" forward '{ type filter hook forward priority filter; policy drop; }'
nft add rule inet "${QEMU_FILTER_TABLE}" forward iifname "${BRIDGE}" oifname "${INTERFACE}" log accept
nft add rule inet "${QEMU_FILTER_TABLE}" forward ct state related,established log accept

nft add table inet "${QEMU_NAT_TABLE}"
nft add chain inet "${QEMU_NAT_TABLE}" postrouting '{ type nat hook postrouting priority srcnat; policy accept; }'
nft add chain inet "${QEMU_NAT_TABLE}" prerouting '{ type nat hook prerouting priority dstnat; policy accept; }'
nft add chain inet "${QEMU_NAT_TABLE}" output '{ type nat hook output priority -100; policy accept; }'
nft add rule inet "${QEMU_NAT_TABLE}" postrouting oifname "${INTERFACE}" log masquerade

dnsmasq --interface="${BRIDGE}" --bind-interfaces --dhcp-range="${DNSMASQ_IP_START},${DNSMASQ_IP_END},${DNSMASQ_IP_MASK}" --no-daemon
43 changes: 43 additions & 0 deletions scripts/vms/ubuntu-14/env-vars.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ readonly USB_VENDOR_ID=""
readonly USB_PRODUCT_ID=""
readonly USB_FILE="/dev/bus/usb/${USB_HOST_BUS}/${USB_HOST_ADDRESS}"

readonly BRIDGE="qemubr0"
readonly INTERFACE=""
readonly BRIDGE_IP="10.14.1.15/16"
readonly DNSMASQ_IP_START="10.14.1.16"
readonly DNSMASQ_IP_END="10.14.1.254"
readonly DNSMASQ_IP_MASK="255.255.0.0"
readonly VM_MAC="52:54:00:00:04:01"
readonly QEMU_NAT_TABLE="qemu-nat"
readonly QEMU_FILTER_TABLE="qemu-filter"

readonly UNSET_WARNING="is unset or empty"

echo "BIOS_LOCATION=${BIOS_LOCATION:?${UNSET_WARNING}}"
Expand All @@ -52,6 +62,16 @@ echo "CPU_MODEL=${CPU_MODEL:?${UNSET_WARNING}}"
echo "CPU_NUMBER=${CPU_NUMBER:?${UNSET_WARNING}}"
echo "MACHINE_MEMORY_SIZE=${MACHINE_MEMORY_SIZE:?${UNSET_WARNING}}"

echo "BRIDGE=${BRIDGE:?${UNSET_WARNING}}"
echo "INTERFACE=${INTERFACE:?${UNSET_WARNING}}"
echo "BRIDGE_IP=${BRIDGE_IP:?${UNSET_WARNING}}"
echo "DNSMASQ_IP_START=${DNSMASQ_IP_START:?${UNSET_WARNING}}"
echo "DNSMASQ_IP_END=${DNSMASQ_IP_END:?${UNSET_WARNING}}"
echo "DNSMASQ_IP_MASK=${DNSMASQ_IP_MASK:?${UNSET_WARNING}}"
echo "VM_MAC=${VM_MAC:?${UNSET_WARNING}}"
echo "QEMU_NAT_TABLE=${QEMU_NAT_TABLE:?${UNSET_WARNING}}"
echo "QEMU_FILTER_TABLE=${QEMU_FILTER_TABLE:?${UNSET_WARNING}}"

abort_if_bios_not_found() {
if [[ ! -e "${BIOS_LOCATION}" ]]; then
echo "UEFI/BIOS not found on '${BIOS_LOCATION}'"
Expand Down Expand Up @@ -104,4 +124,27 @@ abort_if_usb_misconfigured() {
fi
}

abort_if_iproute2_not_found() {
if ! command -v ip >/dev/null; then
echo "'ip' not found"
echo "Please install 'iproute2'"
exit 6
fi
}

abort_if_nftables_not_found() {
if ! command -v nft >/dev/null; then
echo "'nft' not found"
echo "Please install 'nftables'"
echo 7
fi
}

abort_if_interface_not_found() {
if ! ip link show "${INTERFACE}" >/dev/null; then
echo "Device ${INTERFACE} does not exist"
echo 8
fi
}

readonly SOURCED_ENV_VARS_SH=1
28 changes: 28 additions & 0 deletions scripts/vms/ubuntu-14/run-nat-bridge.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

source './env-vars.sh'

echo "Booting machine '${VM_NAME}' with HDD and packages' disk"

abort_if_bios_not_found

abort_if_disk_not_found

qemu-system-x86_64 \
-k pt-br \
-machine "${MACHINE_CFG}" \
-cpu "${CPU_MODEL}" -smp "${CPU_NUMBER}" \
-m "${MACHINE_MEMORY_SIZE}" \
-L "${BIOS_LOCATION}" \
-device virtio-scsi-pci,id=scsi0 \
-drive file="${DISK_LOCATION}",format=qcow2,if=none,media=disk,index=0,id=drive-hd0,readonly=off \
-device scsi-hd,bus=scsi0.0,drive=drive-hd0,id=hd0,bootindex=0 \
-device qemu-xhci \
-boot menu=on \
-netdev bridge,id=net0,br="${BRIDGE}" \
-device virtio-net-pci,netdev=net0,mac="${VM_MAC}" \
-rtc base=localtime,clock=vm \
-device "${DISPLAY_DEVICE}" \
-display "${DISPLAY_BACKEND}" \
-monitor stdio \
-name "${VM_NAME}"
68 changes: 66 additions & 2 deletions scripts/vms/ubuntu-16/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ These scripts need the following packages to be installed on the host's system
|qemu-utils |6.2.0 |
|qemu-system-gui |6.2.0 |
|qemu-block-extra|6.2.0 |
|ovmf |2022.11|
|libguestfs-tools|1.48.6 |
|ovmf |2022.02|
|libguestfs-tools|1.46.2 |
|iproute2 |5.15 |
|nftables |1.0.2 |

The scripts assume that KVM-based accelerated virtualisation is enabled on the
host machine. This requires a compatible processor and it may require a
Expand Down Expand Up @@ -229,3 +231,65 @@ SDK was added to the *worktree*. It is the default toolchain configuration.
- `NAOQI_QIBUILD_CTC_CONFIG`: the name of the configuration in the *worktree*.
It can be used to replace the C++ SDK as the project's toolchain in order to
create a binary that can be transfered to the robot.

### Basic project setup

The following steps will create and build a C++ SDK-based project on the
configured *worktree*:

```bash
cd "${NAO_QIBUILD_WORKSPACE}"
qisrc create my-project
cd my-project
qibuild configure
qibuild make
```

The C++ SDK is configured as the default toolchain. If you wish to set up a
project with an explicit configuration and build setup, you may run:

```bash
cd "${NAO_QIBUILD_WORKSPACE}"
qisrc create my-project
cd my-project
qibuild configure -c "${NAOQI_CPP_QIBUILD_CONFIG}" my-project
qibuild make -c "${NAOQI_CPP_QIBUILD_CONFIG}" my-project
```

Compiling a project that will be run on the robot requires an explicit
configuration to replace the default toolchain by the cross-compilation one
(NAO CTC):

```bash
cd "${NAO_QIBUILD_WORKSPACE}"
qisrc create my-project
cd my-project
qibuild configure -c "${NAOQI_QIBUILD_CTC_CONFIG}"
qibuild make -c "${NAOQI_QIBUILD_CTC_CONFIG}"
```

## Connecting to the Robot

There are three scripts that are used when connecting the Virtual Machine to
your NAO:

1. `enable-nat-bridge-network.sh`: this script must be run with elevated
privileges to set a bridge with a bound DHCP server and a NAT masquerade up
2. `run-nat-bridge.sh`: this script executes the VM with connectivity to the
previously configured bridge. This is achieved by a `tap` device that QEMU will
automatically add to the bridge using `/usr/lib/qemu/qemu-bridge-helper` and
`/etc/qemu/bridge.conf`. It may be executed by a common user.
3. `disable-nat-bridge-network.sh`: this script must be run with elevated
privileges to undo all the modifications made by the NAT enabler script.

### Warning to Docker users

Docker overrides all user firewall configurations. The scripts currently
require a standard firewall configuration, so it will be necessary to remove
all tables and rules created by Docker. It is recommended to stop Docker with
`systemctl stop docker.service docker.socket` to avoid a surprise firewall
reconfiguration event.

You should be able to reset nftables to its standard configuration using the
command: `nft flush ruleset`. This will break the network for the containers
until the machine or the Docker service unit are restarted.
15 changes: 15 additions & 0 deletions scripts/vms/ubuntu-16/disable-nat-bridge-network.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

source './env-vars.sh'

chmod -v 0755 /usr/lib/qemu/qemu-bridge-helper
rm -v /etc/qemu/bridge.conf

sysctl "net.ipv4.conf.${BRIDGE}.forwarding=0"
sysctl "net.ipv6.conf.${BRIDGE}.forwarding=0"

ip link set "${BRIDGE}" down
ip link delete "${BRIDGE}" type bridge

nft delete table inet "${QEMU_NAT_TABLE}"
nft delete table inet "${QEMU_FILTER_TABLE}"
34 changes: 34 additions & 0 deletions scripts/vms/ubuntu-16/enable-nat-bridge-network.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

source './env-vars.sh'

abort_if_iproute2_not_found
abort_if_nftables_not_found
abort_if_interface_not_found

chmod -v 4755 /usr/lib/qemu/qemu-bridge-helper
printf 'allow %s\n' "${BRIDGE}" > /etc/qemu/bridge.conf
chmod -v 0644 /etc/qemu/bridge.conf

ip link add "${BRIDGE}" type bridge
ip link set "${BRIDGE}" up
# Must be in a different network than your current one
ip address add "${BRIDGE_IP}" dev "${BRIDGE}"

sysctl "net.ipv4.conf.${BRIDGE}.forwarding=1"
sysctl "net.ipv6.conf.${BRIDGE}.forwarding=1"

nft add table inet "${QEMU_FILTER_TABLE}"
nft add chain inet "${QEMU_FILTER_TABLE}" input '{ type filter hook input priority filter; }'
nft add chain inet "${QEMU_FILTER_TABLE}" output '{ type filter hook output priority filter; }'
nft add chain inet "${QEMU_FILTER_TABLE}" forward '{ type filter hook forward priority filter; policy drop; }'
nft add rule inet "${QEMU_FILTER_TABLE}" forward iifname "${BRIDGE}" oifname "${INTERFACE}" log accept
nft add rule inet "${QEMU_FILTER_TABLE}" forward ct state related,established log accept

nft add table inet "${QEMU_NAT_TABLE}"
nft add chain inet "${QEMU_NAT_TABLE}" postrouting '{ type nat hook postrouting priority srcnat; policy accept; }'
nft add chain inet "${QEMU_NAT_TABLE}" prerouting '{ type nat hook prerouting priority dstnat; policy accept; }'
nft add chain inet "${QEMU_NAT_TABLE}" output '{ type nat hook output priority -100; policy accept; }'
nft add rule inet "${QEMU_NAT_TABLE}" postrouting oifname "${INTERFACE}" log masquerade

dnsmasq --interface="${BRIDGE}" --bind-interfaces --dhcp-range="${DNSMASQ_IP_START},${DNSMASQ_IP_END},${DNSMASQ_IP_MASK}" --no-daemon
Loading

0 comments on commit 3074edd

Please sign in to comment.