2

I have a computer (running Linux) with two ethernet interfaces. I want to test them without involving another PC.

The setup:

  (192.168.1.5) eth1-------.
Linux PC/device            | loopback cable
  (192.168.1.6) eth2-------'

I run

ping -I eth1 192.168.1.6

but no reply comes.

I don't understand what the problem is. Why does Linux prevent this action? How can I solve this problem?

Dogan Ugurlu
  • 23
  • 1
  • 3

1 Answers1

4

Why?

I cannot fully explain.


How can I solve this problem?

Usually Linux reaches locally assigned IP addresses internally and it just works. It seems the problem appears when one really needs packets to travel to the outside (e.g. via a cable) and back – like in your case.

You can make it work by using network namespaces. I adjusted this other answer of mine to your needs.

Notes:

  • I tested on Debian 10.
  • Where the command is ip … you will probably need sudo ip …. For readability I omit sudo. Work in an elevated shell or (temporarily) define alias ip='sudo ip' to be able to copy-paste conveniently.
  • I assume no automation interferes, i.e. there is no daemon that would try to configure the relevant interfaces in its own way.
  • To run a command in a non-default network namespace I use ip netns exec …. It's possible to run a shell this way; then everything you run from the shell will use the network namespace. This answer uses ip netns exec … every time we need to run something in a non-default network namespace.

Proceed like this:

  1. Define useful variables. Here ns1 is an arbitrary name for a namespace; eth1 and eth2 are the devices you want to use.

    netns=ns1
    dev1=eth1
    dev2=eth2
    
  2. Create a new network namespace.

    ip netns add "$netns"
    
  3. Bring the devices down in the default namespace.

    ip link set dev "$dev1" down
    ip link set dev "$dev2" down
    
  4. Add one of the devices to the new namespace (it will disappear from the default namespace). Here I choose to move $dev2 to the new namespace.

    ip link set dev "$dev2" netns "$netns"
    
  5. Assign IP addresses.

                           ip address add 192.168.1.5/24 dev "$dev1"
    ip netns exec "$netns" ip address add 192.168.1.6/24 dev "$dev2"
    
  6. Confirm the two devices are where they should be, with the right IP addresses.

                           ip address show
    ip netns exec "$netns" ip address show
    # examine output
    
  7. Physically connect the two interfaces with a cable, if not yet done.

  8. Bring the interfaces up. The namespace contains its own loopback device lo. I bring it up just in case, because in general programs may want to rely on it.

                           ip link set dev "$dev1" up
    ip netns exec "$netns" ip link set dev "$dev2" up
    ip netns exec "$netns" ip link set dev      lo up
    
  9. Check routes. In my Debian 10 sane routes appear automatically. This command

    ip route show
    

    prints (among other lines)

    192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5
    

    and this command

    ip netns exec "$netns" ip route show
    

    prints

    192.168.1.0/24 dev eth2 proto kernel scope link src 192.168.1.6
    
  10. Ping one way or the other.

                           ping 192.168.1.6
    ip netns exec "$netns" ping 192.168.1.5
    

    You can use -I but it's not necessary. The address 192.168.1.6 is not assigned to any interface in the default network namespace; and 192.168.1.5 is not assigned in the non-default namespace.

And this is it. It should work. My tests indicate these pings really use the cable. I can tell because:

  • disconnecting the cable makes them stop flowing; for comparison: "internal" pings (from a wired interface to its own IP address) flow even without a cable;
  • iptraf-ng monitoring the pinged interface shows ICMP echo requests and ICMP echo replies; for comparison: the tool doesn't show "internal" pings for a wired interface.

Basic cleanup: delete the network namespace.

ip netns del "$netns"

This will move the second device back to the default network namespace.

None of the commands we used implements a permanent change, so in case of any trouble just reboot.