OpenVswitch Flow 建立
GOAL
h1 Ping h2 (ICMP)
request 跟 reply 會走不同path

## ARP Header

ARP request opcode=1
ARP reply opcode=2
SPA record src IP
TPA record dst IP
e.g.
H1(10.0.0.1) ping H2(10.0.0.2)
H1:SPA = 10.0.0.1
H1:TPA = 10.0.0.2
- ARP 如果switch 有loop話 會有 ARP storm
- ICMP
## Default controller (觀察 ICMP&ARP FLOW 怎麼下放)
Topology
```
root@ubuntu:/home/user/Desktop# mn --topo single,2
root@ubuntu:/home/user/Desktop# h1 ping h2
```
```
root@ubuntu:/home/user/Desktop# ovs-ofctl dump-flows s1
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=5.097s, table=0, n_packets=6, n_bytes=588, idle_timeout=60, idle_age=0, priority=65535,icmp,in_port=2,vlan_tci=0x0000,dl_src=26:34:ef:a9:41:b4,dl_dst=ce:ce:b8:90:65:1e,nw_src=10.0.0.2,nw_dst=10.0.0.1,nw_tos=0,icmp_type=0,icmp_code=0 actions=output:1
cookie=0x0, duration=4.096s, table=0, n_packets=6, n_bytes=588, idle_timeout=60, idle_age=0, priority=65535,icmp,in_port=1,vlan_tci=0x0000,dl_src=ce:ce:b8:90:65:1e,dl_dst=26:34:ef:a9:41:b4,nw_src=10.0.0.1,nw_dst=10.0.0.2,nw_tos=0,icmp_type=8,icmp_code=0 actions=output:2
cookie=0x0, duration=0.082s, table=0, n_packets=1, n_bytes=42, idle_timeout=60, idle_age=0, priority=65535,arp,in_port=2,vlan_tci=0x0000,dl_src=26:34:ef:a9:41:b4,dl_dst=ce:ce:b8:90:65:1e,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,arp_op=1 actions=output:1
cookie=0x0, duration=0.079s, table=0, n_packets=1, n_bytes=42, idle_timeout=60, idle_age=0, priority=65535,arp,in_port=1,vlan_tci=0x0000,dl_src=ce:ce:b8:90:65:1e,dl_dst=26:34:ef:a9:41:b4,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,arp_op=2 actions=output:2
```
h1 icmp type = 8(request)
h2 icmp type =0 (reply
<!-- ouput:<interface> : Forward 到哪個PORT -->
## 查看interface port number
way1
看python script
先連的會先有
way 2
net Command 可以查看
```
net
```
## Topology Script

# ovs Switch Flow
## S1
### ARP (request 問H2)
opcode =1
```
root@ubuntu:/home/user/Desktop/Meowhecker/ovsScript# ovs-ofctl add-flow s1 arp,arp_op=1,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:2
```
spa(src)
tpa(dst)
nw -> Network 簡寫
action:
port 2 (forwarding)
ARP (request 問H1)
```
root@ubuntu:/home/user/Desktop/Meowhecker/ovsScript# ovs-ofctl add-flow s1 arp,arp_op=1,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
```
action:
port 1 forwarding
### ARP reply
opcode =2
```
root@ubuntu:/home/user/Desktop/Meowhecker/ovsScript# ovs-ofctl add-flow s1 arp,arp_op=2,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:2
```
spa (sender address )
```
ovs-ofctl add-flow s1 arp,arp_op=2,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
```
### ICMP request
```
root@ubuntu:/home/user/Desktop/Meowhecker/ovsScript# ovs-ofctl add-flow s1 icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2,icmp_type=8,icmp_code=0,actions=output:2
```
### ICMP reply
```
ovs-ofctl add-flow s1 icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1,icmp_type=0,icmp_code=0,actions=output:1
```
## s2 flows
s2 flow 跟 s1 差不多
```
ovs-ofctl add-flow s2 arp,arp_op=1,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:3
ovs-ofctl add-flow s2 arp,arp_op=1,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
ovs-ofctl add-flow s2 arp,arp_op=2,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:3
ovs-ofctl add-flow s2 arp,arp_op=2,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
ovs-ofctl add-flow s2 icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2,icmp_type=8,icmp_code=0,actions=output:3
ovs-ofctl add-flow s2 icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1,icmp_type=0,icmp_code=0,actions=output:2
```
s3 flow
for ICMP reply(繞路)
```
ovs-ofctl add-flow s3 icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1,icmp_type=0,icmp_code=0,actions=output:1
```
# Test h1 ping h2
switch eth-1
```
containernet> h1 ping h2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.467 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.075 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.089 ms
```

Script
```python
from mininet.cli import CLI
from mininet.net import Mininet
from mininet.link import Link,TCLink,Intf
from mininet.node import Controller,RemoteController
net = Mininet(link=TCLink)
h1 = net.addHost('h1')
h2 = net.addHost('h2')
s1 = net.addSwitch('s1')
s2 = net.addSwitch('s2')
s3 = net.addSwitch('s3')
# switch won't connect to RemoteController !
c0 = net.addController('c0', controller=RemoteController)
#Establish LINK
net.addLink(h1, s1)
net.addLink(s1, s2)
net.addLink(s1, s3)
net.addLink(s3, s2)
net.addLink(s2, h2)
net.build()
net.start
s1.start([c0])
s2.start([c0])
s3.start([c0])
#ovs-ofctl openVswitch Flows
# rules for s1
# ovs-ofctl add-flow s1 arp,arp_op=1,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:2
# ovs-ofctl add-flow s1 arp,arp_op=1,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
# ovs-ofctl add-flow s1 arp,arp_op=2,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:2
# ovs-ofctl add-flow s1 arp,arp_op=2,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
# ovs-ofctl add-flow s1 icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2,icmp_type=8,icmp_code=0,actions=output:2
# ovs-ofctl add-flow s1 icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1,icmp_type=0,icmp_code=0,actions=output:1
# rules for s2
# ovs-ofctl add-flow s2 arp,arp_op=1,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:3
# ovs-ofctl add-flow s2 arp,arp_op=1,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
# ovs-ofctl add-flow s2 arp,arp_op=2,arp_spa=10.0.0.1,arp_tpa=10.0.0.2,actions=output:3
# ovs-ofctl add-flow s2 arp,arp_op=2,arp_spa=10.0.0.2,arp_tpa=10.0.0.1,actions=output:1
# ovs-ofctl add-flow s2 icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2,icmp_type=8,icmp_code=0,actions=output:3
# ovs-ofctl add-flow s2 icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1,icmp_type=0,icmp_code=0,actions=output:2
# rules for s3
# ovs-ofctl add-flow s3 icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1,icmp_type=0,icmp_code=0,actions=output:1
CLI(net)
net.stop()
```