Connect mininet hosts to root namespace

Hi, How could I do to have a mininet host in root namespace? I’ve read in this link Mininet Walkthrough - Mininet that one can have everything running in root namespace, I do not know how to do it though. I’ve read there is a parameter (innamespace) which can be set to False. However, topology is defined in json files instead of python script. Is there any way to do what I wanna get?
Thanks in advance

Hi,

I think this question is probably better asked in the Mininet mailing list, their Github repository, or in similar forums. Still, we might be able to help with some little comments :slightly_smiling_face:.

I think some time ago I did add a root namespace interface attached to a switch. I did it in a similar way to the way done at this file:

My code was something like this:

for one_switch in switches_to_modify:
            switch = self.net.switches[ int(one_switch[1:2] ) - 1] //this is to select a switch based on trimming part of the name and getting the position from "net.switches". Don't put a lot of attention on this.
            root = Node( 'root', inNamespace=False )
            intf = self.net.addLink( root, switch ).intf1
            ip='10.0.223.2/32' // if you need an ip address 
            root.setIP(ip, intf=intf)

You can see the original version I based my code on from the file I linked before the code. Once the Mininet network is up, you should be able to list the interface and inject packets or listen for packets.

Cheers,

Hi,
Thank you so much for your answer. I asked in this forum because I believe p4 switch may impose some kind of limitations. A link is shown between root-eth0 and s1-eth5. However, when listing mininet networks’ nodes I cannot see any new host. I would like to place one host in root namespace, open its terminal, e.g. xterm h5 and then, as it is in the rootnamespace, would like to test I can ping to my host ip address(outside mininet). My aim is to be capable of accessing to some services running in my host machine from a mininet host. That’s why I believe placing a host in rootnamespace would make it possible. Thank you very much for your help.
Bests,
Sally

Let me tell you that I have not tested my following advice, so the steps I tell you to do might or not work. I believe they do work, but you need to test it. :face_with_monocle:

Thank you so much for your answer. I asked in this forum because I believe p4 switch may impose some kind of limitations.

I think if there are any limitations, it is about Mininet probably. But we can sometimes try to help, of course :slight_smile:

A link is shown between root-eth0 and s1-eth5. However, when listing mininet networks’ nodes I cannot see any new host. I would like to place one host in root namespace, open its terminal, e.g. xterm h5 and then, as it is in the rootnamespace, would like to test I can ping to my host ip address(outside mininet). My aim is to be capable of accessing to some services running in my host machine from a mininet host. That’s why I believe placing a host in rootnamespace would make it possible.

So, you probably do not need any “host” since you already have the actual “host”. I mean why not use the terminal from the “host machine”?. You will need additional “route” commands and ARP rules in the host machine to be able to route packets out of root-eth0 AND rules in the switch to route packets towards root-eth0. Not sure if you understand what I mean. Once you enable forwarding between Mininet and host machine, Mininet hosts should be able to access services running in the host machine.

I made a “kinda” descriptive picture:

Hope it helps Sally.

Cheers,

Hi, I am really grateful for your help, thank you I believe I am understanding it, I may be missing something though. Well, my scenario consists of 3 hosts, each in different networks (h1:10.0.1.1/24, h2: 10.0.2.2/24 and h3:10.0.3.3/24). I’d like to let h3 access to my “host machine”, thus, the Ip assigned to root-eth0 is 10.0.3.4/24. Following your instructions, I’ve done the following:

  • Host machine: #route add -net 10.0.3.0/24 gw 10.0.3.4
    #arp -i root-eth0 's 10.0.3.4 root-eth0_MAC

  • Mininet switch: Before starting mininet network, I’ve configured a table entry as the following:
    {
    "table":"MyIngress.ipv4_lpm",
    "match:{
    "hdr.ipv4.dstAddr":["HostMachine_IPAddr, 32"]
    },
    "action_name": "MyIngress.ipv4_forward",
    "action params":{
    "dstAddr": "HostMachine_MACAddr",
    "port": 4
    }
    I thought I may write as MAC Addr, the address of root-eth0, what happens is that this MAC address is only known after creating the network and table rules should be set before creating it. I’ve also add the following in mininet:
    >s1 route add -net HostMachine_network gw 10.0.3.4
    >s1 arp -i root-eth0 -s 10.0.3.4 root-eth0_MACAddr

I got quite confused with the step of adding ARP rules about root-eth0 in Mininet hosts. I cannot add it as it follows:
>h3 arp -i root-eth0 -s 10.0.3.4 root-eth0_MACAddr since root-eth0 is not directly connected to h3, I just can execute it providing no interface, which means it configures eth0 of h3.

I’m pretty sure I am doing something wrong but do not know exactly what, thanks in advance for your help Eder, eskerrik asko! :slight_smile:

Hi Sally,

No worries. I think most people in the P4 and SDN community, in general, try to help each other as much as they are able to :slight_smile:

I apologize with this extensive email. I warn you that this post is extremely long, be aware of that. Sometimes I cannot find short explanations so I tend to be long.

So let me clarify some points before I write here the long answer (and solution) you are probably waiting for. I warn you that when I explain a concept, there might be corner cases and special cases that might not be true, so be aware of that. I just try to give a general explanation about a few concepts. Let’s start:

Hi, I am really grateful for your help, thank you I believe I am understanding it, I may be missing something though. Well, my scenario consists of 3 hosts, each in different networks (h1:10.0.1.1/24, h2: 10.0.2.2/24 and h3:10.0.3.3/24). I’d like to let h3 access to my “host machine”, thus, the Ip assigned to root-eth0 is 10.0.3.4/24.

That is fine. This is correct to my understanding, I guess you use the triangle-topo from the tutorial. I will use the triangle topo in my example later on in this post, just so you know.

Host machine: #route add -net 10.0.3.0/24 gw 10.0.3.4
#arp -i root-eth0 's 10.0.3.4 root-eth0_MAC

If you tried to run this in the “host machine”, they are not completely correct, or not necessary at the very least. Let me explain why. Since root-eth0's IP and H3’s eth0 IP belong to the same subnet you do not need the route command in this case. This is because once you configure root-eth0 with IP 10.0.3.4 and a /24 subnet, then your host machine automatically adds a route for all IPs belonging to 10.0.3.4/24 (i.e., from 10.0.3.1 to 10.0.3.255). Therefore 10.0.3.3 (H3) and 10.0.3.4 (host machine root-eth0) belong to the same subnet.

Mininet switch: Before starting mininet network, I’ve configured a table entry as the following:

That table entry seems correct, I will use a similar one. It should be an entry for S3 (I guess S3 is H3’s edge switch). and HostMachine_IPAddr = 10.0.3.4. If you kinda understand L2 and L3 forwarding, subnets and so on, you will see that ipv4_forward makes little sense for two hosts in the same subnet. I will explain later why.

I thought I may write as MAC Addr, the address of root-eth0, what happens is that this MAC address is only known after creating the network and table rules should be set before creating it.

This is true, but you can set the MAC too apart from the IP :wink: I have provided an example later on.

I’ve also add the following in mininet:
s1 route add -net HostMachine_network gw 10.0.3.4
s1 arp -i root-eth0 -s 10.0.3.4 root-eth0_MACAddr

I got quite confused with the step of adding ARP rules about root-eth0 in Mininet hosts. I cannot add it as it follows:
h3 arp -i root-eth0 -s 10.0.3.4 root-eth0_MACAddr since root-eth0 is not directly connected to h3, I just can execute it providing no interface, which means it configures eth0 of h3.

Ok this is probably an important point. The first command:

s1 route add -net HostMachine_network gw 10.0.3.4

So you don’t add it to a switch. The switch does not process any route commands, that’s normally your host (mininet host or host machine). When you program a switch and add rules, you are making a similar thing to what a “route” command is doing (roughly). The action of forwarding a packet to one port or another, changing MACs and so on is what you with P4 and rules. A route command is used in host to, for instance, define which IP ranges/subnets should be forwarded to a specific interface, define the gateway for the host and many more things. If you check topology.json, you can see a few examples of that that the tutorial does automatically. You need those (topology.json) route commands (also the arp ones) in the exercise to define a gateway for your hosts and make this basic exercise become a simple L3 forwarding exercise.

A similar thing happens with this command:

s1 arp -i root-eth0 -s 10.0.3.4 root-eth0_MACAddr

If you needed to put these commands in any machine, it would not be in S1, it would be in the host machine and H3 (with different values, of course).

I got quite confused with the step of adding ARP rules about root-eth0 in Mininet hosts. I cannot add it as it follows:

The ARP rule that you need is only for H3. However, you could ignore it because the P4 switch is actually replacing the destination MAC.

h3 arp -i root-eth0 -s 10.0.3.4 root-eth0_MACAddr since root-eth0 is not directly connected to h3, I just can execute it providing no interface, which means it configures eth0 of h3.

Ok so the problem here is that root-eth0 is never connected to H3 directly. If you meant that they are not connected to the same switch they actually, are… via S3. Also, the command is wrong, it could be my fault when giving you a link about ARP commands (this link is better). You should follow this command at H3:

arp -s IP.host.machine Mac:host:machine
#10.0.3.4 and the MAC you define

I finished all my comments at this point. I will put the steps I followed in my use case since I never documented it. I will do it in another reply to prevent a single answer from becoming too long.

Hi again,

After my previous dissertation let me list here the steps I followed. It might help you because I could ping between H3 and host machine.

I have used the tutorial from Github. Not sure if my version was too old (I think it was a VM from January) but it should work for you.

My case:

  1. Makefile at root folder of the exercise, like basic (not at utils folder)
    TOPO = triangle-topo/topology.json

  2. At triangle-topo/topology.json, at h3 > commands list:

(...)
            "arp -i eth0 -s 10.0.3.30 08:00:00:00:03:00",
            add the following line and previous comma <- do not copy this line 
            "arp -s 10.0.3.4 00:11:00:22:00:33"
            ]}


(...)

And also in the same file (assuming port 4 is correct):

"links": [
        ["h1", "s1-p1"], ["s1-p2", "s2-p2"], ["s1-p3", "s3-p2"], 
        ["s3-p3", "s2-p3"], ["h2", "s2-p1"], ["h3", "s3-p1"]
    ], 
Add line below  and previous comma <- do not copy this line
"switch_outport" : {
        "s3" : {
          "port" : 4
        }
    }
}
  1. At run_exercise.py (at ~/tutorials/tools/), add the following import

from mininet.node import Node

  1. At run_exercise.py, within __init__ function, around line 174
(...)
        self.links = self.parse_links(topo['links'])
        # Add line below
        self.outport = topo['switch_outport']
(...)
  1. At run_exercise.py, in create_network function, around line 261 (attention to setMAC).
                 (...)
                  switch = defaultSwitchClass,
                  controller = None)
        #Add the complete for loop
        for switch_name in self.outport.iterkeys():
            switch = self.net.switches[int(switch_name[1:2])-1]
            root = Node( 'root', inNamespace=False )
            intf = self.net.addLink( root, switch ).intf1
            mac='00:11:00:22:00:33' # here you define the MAC
            ip='10.0.3.4/24'
            root.setMAC(mac, intf=intf)
            root.setIP(ip, intf=intf)
  1. Also a rule like the one you posted. This one is for S3:
},
    ,
    {
      "table": "MyIngress.ipv4_lpm",
      "match": {
        "hdr.ipv4.dstAddr": ["10.0.3.4", 32]
      },
      "action_name": "MyIngress.ipv4_forward",
      "action_params": {
        "dstAddr": "00:11:00:22:00:33",
        "port": 4
      }
    }
  1. Add an ARP command for host machine so that it knows H3’s MAC address, which associates 10.0.3.3 with the one topology.json defined. You can verify with mininet: h3 ifconfig which mac address H3’s eth0 holds.

sudo arp -s 10.0.3.3 08:00:00:00:03:33

I think I listed all the steps I followed in my own use case. With all that I was able to ping between H3 and host machine. Now keep in mind that this should not give you access to the internet to H3 or any other host. I remember Mininet used to handle that with the addNat() option or the --nat argument but I never tried that with a P4 switch-based topology.

I hope it helps.

thanks in advance for your help Eder, eskerrik asko! :slight_smile:

Ez horregatik (You are welcome)

Cheers,

Hi Eder,

Wow, thank you so much. It works, my topology is not the triangle one, it consists of just one switch and 3 hosts connected to its ports, but no matter, pings work correctly, there’s connectivity.

I do not know whether this other problem belongs to this forum, if this is not the case, tell me, no worries.
I would like to access to a mysql database service which is listening on all interfaces, I can access to it from my host machine typing the following.
#mysql -u USER -h 10.0.3.4 -p
or from another VM specifying the ip which belongs to the same private network of the other VM.
However, when trying to access to it from h3, it is not possible, connection timed out.
I can access to it in this way:
#mysql -u USER (-h localhost) -p
Do you know what could it be due to?
It happens the same with another application I would like to run (EJBCA) I can both access to it from my host machine and from another, but not from mininet.My ufw firewall is disabled.
I thought it has something to do with mininet as when accessing to the service from another VM it works. But doing the same in mininet leads to that problem.
Thank you so much for all your time and help Eder! :grin:

Wow, thank you so much. It works, my topology is not the triangle one, it consists of just one switch and 3 hosts connected to its ports, but no matter, pings work correctly, there’s connectivity.
I do not know whether this other problem belongs to this forum, if this is not the case, tell me, no worries.
I would like to access to a mysql database service which is listening on all interfaces, I can access to it from my host machine typing the following.
mysql -u USER -h 10.0.3.4 -p
or from another VM specifying the ip which belongs to the same private network of the other VM.

I see. You can also use localhost when you run it in the host machine. It makes sense that it works when using the IP used in the NAT network (or similar type) of interfaces in your VM. Nothing strange so far.

However, when trying to access to it from h3, it is not possible, connection timed out.
I can access to it in this way:
mysql -u USER (-h localhost) -p
Do you know what could it be due to?

The reasons could be multiple :thinking:, I cannot imagine just one particular reason right now. Since you have connectivity, I am not sure what is wrong. To start, you can try to use Wireshark at root-eth0 and see if any packet is missing or something makes no sense (see end of post).

It happens the same with another application I would like to run (EJBCA) I can both access to it from my host machine and from another, but not from mininet.My ufw firewall is disabled.
I thought it has something to do with mininet as when accessing to the service from another VM it works. But doing the same in mininet leads to that problem.

Checking the ufw is a smart thing, it was a good idea. I solve most of my issues with Wireshark when it comes to problems like this. Check next paragraph :slight_smile:

EDIT:
Oh I might have found the error. I’ll give you some steps to find the solution. But I will let you discover it on your own. Try to run a netcat session, a TCP one like this.

Run this on host machine:
nc -l 11111 #sorry wrong port before
Run this on H3:
nc 10.0.3.4 11111

If the connection is successful (i.e., TCP session is OK, but it won’t be the first time you do this command from H3), then whatever you write in H3’s console will appear at host machine’s console. If you open Wireshark listening at root-eth0, it will tell you there is an error with packet’s coming back from host machine to H3. Read the error and the suggestion it gives you about the checksum. Let’s see if you can solve that on your own, else send another message and I will help you further right away.

Cheers,

Hi!
I solved it, the problem was related to “checksum offloading”, then, I fixed it running the following command:

sudo ethtool --offload root-eth0 rx off tx off

Thank you so much for your help! :grin: