ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Limit ROS traffic to specific network interface

asked 2022-08-30 12:30:12 -0600

Barty gravatar image

updated 2022-08-30 15:57:46 -0600

I have a computer that is acting as a ROS master that has 5 network interfaces, 1 WiFi and 4 ethernet ports. I'd like to limit ROS traffic to just one of the ethernet ports so that I can leave the wifi on for SSH, but not have to set ROS_LOCALHOST_ONLY=1, that way I am able to e.g. run RVIZ on another computer over ethernet without touching the wifi. Is this possible?

I'm running ROS2 Humble on Ubuntu 22.04 and using Cyclone DDS, though I may also need to use FastRTPS instead/as well.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
2

answered 2022-08-31 03:56:56 -0600

Both CycloneDDS and FastRTPS have ways to restrict the comms to a given network interface.

https://dds-demonstrators.readthedocs... https://fast-dds.docs.eprosima.com/en...

On Ubuntu I use a small bash function to hide this:

# restrict fastrtps / Cyclone DDS to this network interface
ros_restrict()
{
    if [[ $# -eq 0 ]]; then
        echo "ros_restrict: give a network interface"
        return
    fi

    # auto-detect if basic name
    local interface=$1
    if [[ $1 == "WIFI" ]]; then
        local interface=$(for dev in /sys/class/net/*; do [ -e "$dev"/wireless ] && echo ${dev##*/}; done)
    fi
    if [[ $1 == "ETH" ]]; then
        local interface=$(ip link | awk -F: '$0 !~ "lo|vir|wl|^[^0-9]"{print $2;getline}')
        local interface=$(for dev in $interface; do [ ! -e /sys/class/net/"$dev"/wireless ] && echo ${dev##*/}; done)
    fi
    if [[ $1 == "lo" ]]; then
        export ROS_LOCALHOST_ONLY=1
        unset ROS_DOMAIN_ID
        unset FASTRTPS_DEFAULT_PROFILES_FILE
        # https://answers.ros.org/question/365051/using-ros2-offline-ros_localhost_only1/
        export CYCLONEDDS_URI='<General>
            <NetworkInterfaceAddress>lo</NetworkInterfaceAddress>
            <AllowMulticast>false</AllowMulticast>
        </General>
        <Discovery>
            <ParticipantIndex>auto</ParticipantIndex>
            <MaxAutoParticipantIndex>100</MaxAutoParticipantIndex>
            <Peers>
                <Peer address="localhost"/>
            </Peers>
        </Discovery>'
        return
    fi

    # Fast-DDS https://fast-dds.docs.eprosima.com/en/latest/fastdds/transport/whitelist.html
    # needs actual ip for this interface
    ipinet="$(ip a s $interface | egrep -o 'inet [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')"
    echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
    <profiles xmlns=\"http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles\">
        <transport_descriptors>
            <transport_descriptor>
                <transport_id>CustomUDPTransport</transport_id>
                <type>UDPv4</type>
                <interfaceWhiteList>
                    <address>${ipinet##inet }</address>
                </interfaceWhiteList>
            </transport_descriptor>

            <transport_descriptor>
                <transport_id>CustomTcpTransport</transport_id>
                <type>TCPv4</type>
                <interfaceWhiteList>
                    <address>${ipinet##inet }</address>
                </interfaceWhiteList>
            </transport_descriptor>

        </transport_descriptors>

        <participant profile_name=\"CustomUDPTransportParticipant\">
            <rtps>
                <userTransports>
                    <transport_id>CustomUDPTransport</transport_id>
                </userTransports>
            </rtps>
        </participant>

        <participant profile_name=\"CustomTcpTransportParticipant\">
            <rtps>
                <userTransports>
                    <transport_id>CustomTcpTransport</transport_id>
                </userTransports>
            </rtps>
        </participant>
    </profiles>" > /tmp/fastrtps_interface_restriction.xml
    # tell where to look
    export FASTRTPS_DEFAULT_PROFILES_FILE=/tmp/fastrtps_interface_restriction.xml

    # Cyclone DDS https://dds-demonstrators.readthedocs.io/en/latest/Teams/1.Hurricane/setupCycloneDDS.html
    export CYCLONEDDS_URI="<General><NetworkInterfaceAddress>$interface"

    # we probably do not want to limit to localhost
    unset ROS_LOCALHOST_ONLY  
}
edit flag offensive delete link more
0

answered 2022-08-30 16:23:37 -0600

johnjamesmiller gravatar image

I believe you can use iptables to block the udp ports

example of using port blocking. You will probably want to block both in and out. https://bobcares.com/blog/iptables-bl...

you will want to include the -i flag to block only on the interfaces you do not want the ros2 traffic to go on https://serverfault.com/questions/286...

the specific ports you will want to block will be in the ros domain id documentation https://docs.ros.org/en/galactic/Conc...

assuming your domain id is 0 try something like:

iptables -I INPUT -p udp -i eth0:1 --dport 7400:7649 -j REJECT
iptables -A OUTPUT -p udp -i eth0:1 --dport 7400:7649 -j DROP

these rules will probably disappear on reboot by default so you will probably need to do something to save them off https://askubuntu.com/questions/11939...

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2022-08-30 12:30:12 -0600

Seen: 1,830 times

Last updated: Aug 31 '22