Networking - Macvlan

In some companies the IT department sets up specific rules for restricting device behavior on the network. This can include which IP ranges are allowed and where they are allowed to connect and communicate together. The issue for a URCap developer is in that case that the application could be limited and not able to connect to external sensors e.g. cameras.

Macvlan is a networking virtualization mechanism that allows you to create virtual network interfaces (sub-interfaces) with their own MAC addresses on a physical network interface. It is a way to partition a single physical network interface into multiple virtual interfaces, each with its own unique MAC address and associated configuration.

Creating a virtual network interface that shares a subnet IP address is a viable solution to ensure connectivity between a URCap and a sensor, especially when the application requires connection to the sensor located at a specific IP address.

Adding macvlan to URCap

There is a sample in the SDK called macvlan. The following section from the manifest.yaml describes setting up the network interface.

containers:
  - id: macvlan
    image: macvlan:latest
    networks:
      - id: "eth1"
        type: macvlan
        description: "Sample network"

The networks.id is the name of the network interface that will be created. From inside the URCap container it will be possible to see that it has been created with the command ip addr show. Initially, the interface is denoted as eth1 with its state marked as DOWN.

17: eth1@if2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether be:64:ce:83:19:bd brd ff:ff:ff:ff:ff:ff link-netnsid 0

The sample includes a Flask server which has a /set_interface REST endpoint. The functionality of the endpoint is to check if the network interface exists and if it does then set a specific IP address and ensure the interface is up. You can test that functionality with the cURL command

curl <ROBOT_IP>/universal-robots/macvlan/macvlan/rest-api/set_interface

When verified that the network interface exists the IP address is set using ip addr add 192.168.1.10/22 dev eth1.

17: eth1@if2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether be:64:ce:83:19:bd brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.10/22 scope global eth1
valid_lft forever preferred_lft forever

Subsequently, it is checked if the interface is active, and if not it is activated with ip link set dev eth1 up.

17: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether be:64:ce:83:19:bd brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.10/22 scope global eth1
valid_lft forever preferred_lft forever

Notice that the state has changed to UP at which point the network interface is ready to be used.