adde source_routing exercise

This commit is contained in:
Antonin Bas 2015-09-30 12:35:20 -07:00
parent 8d05aae343
commit 82bde33ec7
11 changed files with 367 additions and 0 deletions

13
SIGCOMM_2015/.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Python byte code
*.pyc
# Emacs
*~
# Compiled JSON
*.json
*.pcap
# Extracted solutions
solution/

8
SIGCOMM_2015/env.sh Normal file
View File

@ -0,0 +1,8 @@
THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
# ---------------- EDIT THIS ------------------
BMV2_PATH=$THIS_DIR/../../bmv2
# e.g. BMV2_PATH=$THIS_DIR/../bmv2
P4C_BM_PATH=$THIS_DIR/../../p4c-bm
# e.g P4C_BM_PATH=$THIS_DIR/../p4c-bm
# ---------------- END ------------------

View File

@ -0,0 +1,2 @@
sudo killall simple_switch
redis-cli FLUSHDB

View File

View File

@ -0,0 +1,28 @@
/*
Copyright 2013-present Barefoot Networks, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
parser start {
// TODO
return ingress;
}
control ingress {
// TODO
}
control egress {
// leave empty
}

View File

@ -0,0 +1,42 @@
#!/usr/bin/python
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from scapy.all import sniff, sendp
from scapy.all import Packet
from scapy.all import ShortField, IntField, LongField, BitField
import sys
import struct
def handle_pkt(pkt):
pkt = str(pkt)
if len(pkt) < 12: return
preamble = pkt[:8]
preamble_exp = "\x00" * 8
if preamble != preamble_exp: return
num_valid = struct.unpack("<L", pkt[8:12])[0]
if num_valid != 0:
print "received incorrect packet"
msg = pkt[12:]
print msg
sys.stdout.flush()
def main():
sniff(iface = "eth0",
prn = lambda x: handle_pkt(x))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,31 @@
#!/bin/bash
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source $THIS_DIR/../env.sh
P4C_BM_SCRIPT=$P4C_BM_PATH/p4c_bm/__main__.py
SWITCH_PATH=$BMV2_PATH/targets/simple_switch/simple_switch
CLI_PATH=$BMV2_PATH/tools/runtime_CLI.py
$P4C_BM_SCRIPT p4src/source_routing.p4 --json source_routing.json
sudo PYTHONPATH=$PYTHONPATH:$BMV2_PATH/mininet/ python topo.py \
--behavioral-exe $BMV2_PATH/targets/simple_switch/simple_switch \
--json source_routing.json \
--cli $CLI_PATH

View File

@ -0,0 +1,106 @@
#!/usr/bin/python
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from scapy.all import sniff, sendp
from scapy.all import Packet
from scapy.all import ShortField, IntField, LongField, BitField
import networkx as nx
import sys
class SrcRoute(Packet):
name = "SrcRoute"
fields_desc = [
LongField("preamble", 0),
IntField("num_valid", 0)
]
def read_topo():
nb_hosts = 0
nb_switches = 0
links = []
with open("topo.txt", "r") as f:
line = f.readline()[:-1]
w, nb_switches = line.split()
assert(w == "switches")
line = f.readline()[:-1]
w, nb_hosts = line.split()
assert(w == "hosts")
for line in f:
if not f: break
a, b = line.split()
links.append( (a, b) )
return int(nb_hosts), int(nb_switches), links
def main():
if len(sys.argv) != 3:
print "Usage: send.py [this_host] [target_host]"
print "For example: send.py h1 h2"
sys.exit(1)
src, dst = sys.argv[1:]
nb_hosts, nb_switches, links = read_topo()
port_map = {}
for a, b in links:
if a not in port_map:
port_map[a] = {}
if b not in port_map:
port_map[b] = {}
assert(b not in port_map[a])
assert(a not in port_map[b])
port_map[a][b] = len(port_map[a]) + 1
port_map[b][a] = len(port_map[b]) + 1
G = nx.Graph()
for a, b in links:
G.add_edge(a, b)
shortest_paths = nx.shortest_path(G)
shortest_path = shortest_paths[src][dst]
print "path is:", shortest_path
port_list = []
first = shortest_path[1]
for h in shortest_path[2:]:
port_list.append(port_map[first][h])
first = h
print "port list is:", port_list
port_str = ""
for p in port_list:
port_str += chr(p)
while(1):
msg = raw_input("What do you want to send: ")
# finding the route
first = None
p = SrcRoute(num_valid = len(port_list)) / port_str / msg
print p.show()
sendp(p, iface = "eth0")
# print msg
if __name__ == '__main__':
main()

Binary file not shown.

View File

@ -0,0 +1,129 @@
#!/usr/bin/python
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.log import setLogLevel, info
from mininet.cli import CLI
from mininet.link import TCLink
from p4_mininet import P4Switch, P4Host
import argparse
from time import sleep
import os
import subprocess
_THIS_DIR = os.path.dirname(os.path.realpath(__file__))
_THRIFT_BASE_PORT = 22222
parser = argparse.ArgumentParser(description='Mininet demo')
parser.add_argument('--behavioral-exe', help='Path to behavioral executable',
type=str, action="store", required=True)
parser.add_argument('--json', help='Path to JSON config file',
type=str, action="store", required=True)
parser.add_argument('--cli', help='Path to BM CLI',
type=str, action="store", required=True)
args = parser.parse_args()
class MyTopo(Topo):
def __init__(self, sw_path, json_path, nb_hosts, nb_switches, links, **opts):
# Initialize topology and default options
Topo.__init__(self, **opts)
for i in xrange(nb_switches):
switch = self.addSwitch('s%d' % (i + 1),
sw_path = sw_path,
json_path = json_path,
thrift_port = _THRIFT_BASE_PORT + i,
pcap_dump = True,
device_id = i)
for h in xrange(nb_hosts):
host = self.addHost('h%d' % (h + 1))
for a, b in links:
self.addLink(a, b)
def read_topo():
nb_hosts = 0
nb_switches = 0
links = []
with open("topo.txt", "r") as f:
line = f.readline()[:-1]
w, nb_switches = line.split()
assert(w == "switches")
line = f.readline()[:-1]
w, nb_hosts = line.split()
assert(w == "hosts")
for line in f:
if not f: break
a, b = line.split()
links.append( (a, b) )
return int(nb_hosts), int(nb_switches), links
def main():
nb_hosts, nb_switches, links = read_topo()
topo = MyTopo(args.behavioral_exe,
args.json,
nb_hosts, nb_switches, links)
net = Mininet(topo = topo,
host = P4Host,
switch = P4Switch,
controller = None )
net.start()
for n in xrange(nb_hosts):
h = net.get('h%d' % (n + 1))
for off in ["rx", "tx", "sg"]:
cmd = "/sbin/ethtool --offload eth0 %s off" % off
print cmd
h.cmd(cmd)
print "disable ipv6"
h.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
h.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
h.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1")
h.cmd("sysctl -w net.ipv4.tcp_congestion_control=reno")
h.cmd("iptables -I OUTPUT -p icmp --icmp-type destination-unreachable -j DROP")
sleep(1)
for i in xrange(nb_switches):
cmd = [args.cli, "--json", args.json,
"--thrift-port", str(_THRIFT_BASE_PORT + i)]
with open("commands.txt", "r") as f:
print " ".join(cmd)
try:
output = subprocess.check_output(cmd, stdin = f)
print output
except subprocess.CalledProcessError as e:
print e
print e.output
sleep(1)
print "Ready !"
CLI( net )
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
main()

View File

@ -0,0 +1,8 @@
switches 3
hosts 3
h1 s1
h2 s2
h3 s3
s1 s2
s1 s3
s2 s3