Openflow learning notes

Posted by shmick25 on Thu, 13 Jan 2022 20:06:19 +0100

Tool: Mininet

Topology:

The topology envisaged at the beginning is like this

Purpose of the experiment:

The implementation changes the fowarding route from h1-s1-s2-h2 (default) to h1-s1-s3-h2, and vice versa

It is a simple step to establish this topology using a python script written by the interface provided by mininet

from mininet.topo import Topo

class MyTopo(Topo):

    def build(self):

        #Add hosts and switches
        leftHost = self.addHost('h1')
        rightHost = self.addHost('h2')
        leftSwitch = self.addSwitch('s1')
        rightSwitch1 = self.addSwitch('s2')
        rightSwitch2 = self.addSwitch('s3')

        #Add links
        self.addLink(leftHost, leftSwitch)
        self.addLink(leftSwitch, rightSwitch1)
        self.addLink(leftSwitch, rightSwitch2)
        self.addLink(rightSwitch1, rightHost)
        self.addLink(rightSwitch2, rightHost)


topos = {'mytopo':(lambda:MyTopo() ) }

sudo mn --custom FILE_PATH --topo mytopo --mac

Several practical options for creating topo can be found in mininet walkthrough:

--Custom: follow file_ The custom topology of the script given in the file corresponding to path

--topo mytopo: specifies which topo in the script file to use

--mac: This is very important for simplifying the experiment. In this experiment, it sets the mac addresses of eth0 of H1 and eth0 of H2 to 00:00:00:00:01 and 00:00:00:00:02 respectively (note that eth1 of H2 is not set to 00:00:00:00:02 or 00:00:00:00:03)

--test pingall: you can ping all host nodes to see if the network is connected

At this time, H1 can ping H2, but the path is h1-s1-s2-h2,

Now I'm going to

After the establishment, write the command line manually using OVS vsctl provided by open flow

###icmp

s1: 
1.
#Send the request message of h1 to h2:
sudo ovs-ofctl add-flow s1 priority=65535,icmp,in_port="s1-eth1",vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=10.0.0.1,nw_dst=10.0.0.2,nw_tos=0,icmp_type=8,icmp_code=0,actions=output:"s1-eth3"

2.
#Send the reply message of h2 to h1:
sudo ovs-ofctl add-flow s1 priority=65535,icmp,in_port="s1-eth3",vlan_tci=0x0000,dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01,nw_src=10.0.0.2,nw_dst=10.0.0.1,nw_tos=0,icmp_type=0,icmp_code=0,actions=output:"s1-eth1"


###arp

3.
#Send the arp request of h1 to h2
sudo ovs-ofctl add-flow s1 priority=65535,arp,in_port="s1-eth1",vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,arp_op=1,action=output:"s1-eth3"

4.
#Send the arp reply of h1 to h2
sudo ovs-ofctl add-flow s1 priority=65535,arp,in_port="s1-eth1",vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,arp_op=2,actions=output:"s1-eth3"

5.
#Send the arp request of h2 to h1
sudo ovs-ofctl add-flow s1 priority=65535,arp,in_port="s1-eth3",vlan_tci=0x0000,dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,arp_op=1,actions=output:"s1-eth1"

6.
#Send the arp reply of h2 to h1
sudo ovs-ofctl add-flow s1 priority=65535,arp,in_port="s1-eth3",vlan_tci=0x0000,dl_src=00:00:00:00:00:02,dl_dst=00:00:00:00:00:01,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,arp_op=2,actions=output:"s1-eth1"



s2: Let it not accept the broadcast

sudo ovs-ofctl add-flow s2 priority=65535,arp,in_port="s2-eth1",vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,arp_op=1,actions=DROP

In this step, I made a lot of fancy settings, but h1 ping h2 didn't work

I feel there is no problem with my logic. After capturing packets with wireshark, I find that there is a puzzling problem:

H1 sends a request according to the specified h1-s1-s3-h2 route, but H2 never sends a reply after receiving the packet

h2(10.0.0.2) behaves as if it didn't know the package

The characteristics of the problem are:

(1)

Forward along h1-s1-s2-h2, with both request and reply

(2)

Forward along h1-s1-s3-h2, the request is normal, H2 does not reply, H2 does not report an error, but "don't know" this ICMP request

So what's the problem?

(1)

The forwarding of the switch on the h1-s1-s3-h2 route is normal and open flow. The forwarding of the link layer does not involve changing the destination mac address and source mac address of the packet (it has always been the mac address of H1 and the mac address of H2 in the forwarding process), but just repeating the simple action of sending from one port to another -- > for the time being, it is not considered to be a problem on the switch

(2)

Mininet is used by many people, but no major bug s are found in mininet. This is a very simple forwarding path experiment -- > for the time being, it is not a virtual machine problem.

(3)

After learning the icmp Protocol, I found nothing that seems to be related to this problem -- > the pit should not be on icmp

(4)

After looking at a similar problem on the Internet, there is a problem with checksum. Here, wireshark seems to have no such problem -- > requests are forwarded normally all the way to h2

(5)

I suspect that it may be the problem of spaning tree (maybe according to spaning tree, the request packet can only be sent to eth0 port of h2) - > elder martial brother told me that there is no spaning tree conflict because two network cards of h2 are connected to the network

I see here that the reason why icmp does not reply is that the destination mac address is 00:00:00:00:02, which is the mac of h2-eth0. Therefore, when the packet is sent to h2-eth1, H2 will not respond to the icmp request

Here, I think of two ways to solve this problem

(1)

Add mod to the action in the s1 forwarding flow table_ dl_ DST = "mac address of h2-eth1". This has not been tried yet. It will be updated later

(2)

Change the topology, add a s4 to s2-h2 and s3-h2, and the topology is changed as follows:

At this time, there was a problem. h1 ping h2 failed. I immediately checked whether the topo file was wrong. Staring at these short lines of code, I couldn't see any problem. I restarted the network and added the parameter test pingall. I found that ping really failed,

Do not write -- test pingall, just set up mininet network, open wireshark, and find that h1 and h2 have been broadcasting icmpv6 and mdns messages to each other. At the same time, all ports of all devices are filled with the same icmpv6 and mdns messages. Under normal circumstances, if you only open the network without any operation, all ports of all devices should receive almost no messages. Now it seems that all nodes have been discussing something without reaching an agreed result.

Why is this? Why is it normal when s4 is not added (topo above), and this problem will occur after s4 is added?

The explanation is that there is a loop in the new topology. When the flow table is not written, mininet cannot determine the forwarding path between nodes if there is a loop.

The above 3switch network seems to have a loop. In fact, because the two ports of h2 are used, it is a tree structure, so there is no problem of forming a loop.

So next, we set the flow table of switches:

#topo:


          s2     
        /    \
h1 - s1        s4 - h2
        \    /
          s3 

#Open wireshark method: xterm h1/xterm s1 open the shell of host or switch
#Run wireshark -n

#(1) All messages are forwarded from s3:

sudo ovs-ofctl add-flow s1 in_port='s1-eth1',actions=output:'s1-eth3'
sudo ovs-ofctl add-flow s3 in_port='s3-eth1',actions=output:'s3-eth2'
sudo ovs-ofctl add-flow s4 in_port='s4-eth2',actions=output:'s4-eth3'
sudo ovs-ofctl add-flow s2 in_port='s2-eth1',actions=DROP
sudo ovs-ofctl add-flow s1 in_port='s1-eth2',actions=output:'s1-eth1'
sudo ovs-ofctl add-flow s3 in_port='s3-eth2',actions=output:'s3-eth1'
sudo ovs-ofctl add-flow s4 in_port='s4-eth3',actions=output:'s4-eth1'
sudo ovs-ofctl add-flow s2 in_port='s2-eth2',actions=DROP

#When you open wireshark, you can see that both icmp request and icmp reply are forwarded from s3

#(2) The message of h1-h2 is forwarded from s3, and the message of h2-h1 is forwarded from s2:



sudo ovs-ofctl add-flow s1 in_port='s1-eth1',actions=output:'s1-eth3'
sudo ovs-ofctl add-flow s3 in_port='s3-eth1',actions=output:'s3-eth2'
sudo ovs-ofctl add-flow s4 in_port='s4-eth2',actions=output:'s4-eth3'
sudo ovs-ofctl add-flow s2 in_port='s2-eth1',actions=DROP
sudo ovs-ofctl add-flow s1 in_port='s1-eth2',actions=output:'s1-eth1'
sudo ovs-ofctl add-flow s2 in_port='s2-eth2',actions=output:'s2-eth1'
sudo ovs-ofctl add-flow s4 in_port='s4-eth3',actions=output:'s4-eth1'
sudo ovs-ofctl add-flow s3 in_port='s3-eth2',actions=DROP

#Open wireshark and you can see that the route of request is h1-s1-s3-s4-h2 and the route of reply is h2-s4-s2-s1-h1

So far, a simple experiment of controlling forwarding by adding a flow table through the ofctl command has been completed. Later, the experiment of controlling forwarding by issuing a flow table through the ryu controller file will be updated.

Topics: Python network mininet