Skip to content
This repository was archived by the owner on Mar 24, 2026. It is now read-only.

Commit 99326dd

Browse files
author
test
committed
Merge commit with modified feature/qklink.
2 parents 9ab7394 + ccebd0b commit 99326dd

18 files changed

Lines changed: 756 additions & 7 deletions

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,34 @@ Testing:
6565
./bcmn_test.py [host_type]
6666
```
6767

68+
69+
**Test with quantum links:**
70+
```bash
71+
mn --custom=bal/QKCustom.py --link=qk --topo=tree,depth=2,fanout=3
72+
```
73+
74+
**Test with ryu:**
75+
76+
```bash
77+
sudo mn --custom bal/topo_2sw-2host.py --topo mytopo --mac --controller remote --switch ovs
78+
```
79+
80+
Go to 'bal' directory and start ryu-manager:
81+
82+
```bash
83+
cd bal
84+
sudo ryu-manager rest_forward.py
85+
```
86+
87+
You can switch channels with RestAPI:
88+
For raw channel:
89+
```bash
90+
curl -X GET http://localhost:8080/channel/1/1
91+
```
92+
For quantum channel:
93+
```bash
94+
curl -X GET http://localhost:8080/channel/1/2
95+
```
96+
6897
## More information
6998
you may find in the project's [Wiki](https://github.com/BAlchemyLab/bal/wiki).

bal/QKCustom.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
from mininet.link import (Link, TCLink, TCULink, OVSLink)
2+
from mininet import util
3+
import time
4+
import subprocess
5+
import os
6+
import atexit
7+
8+
class QKLink(Link):
9+
@classmethod
10+
def makeIntfPair(cls, intfname1, intfname2, addr1=None, addr2=None,
11+
node1=None, node2=None, deleteIntfs=True):
12+
"""Create pair of interfaces
13+
intfname1: name for interface 1
14+
intfname2: name for interface 2
15+
addr1: MAC address for interface 1 (optional)
16+
addr2: MAC address for interface 2 (optional)
17+
node1: home node for interface 1 (optional)
18+
node2: home node for interface 2 (optional)
19+
(override this method [and possibly delete()]
20+
to change link type)"""
21+
# Leave this as a class method for now
22+
assert cls
23+
return makeIntfPair(intfname1, intfname2, addr1, addr2, node1, node2,
24+
deleteIntfs)
25+
26+
def stop(self):
27+
for p in QKLink.processes:
28+
p.kill()
29+
self.delete()
30+
31+
32+
QKLink.processes = []
33+
34+
35+
def makeIntfPair(intf1, intf2, addr1=None, addr2=None, node1=None, node2=None,
36+
deleteIntfs=True, runCmd=None):
37+
"""Make a veth pair connnecting new interfaces intf1 and intf2
38+
intf1: name for interface 1
39+
intf2: name for interface 2
40+
addr1: MAC address for interface 1 (optional)
41+
addr2: MAC address for interface 2 (optional)
42+
node1: home node for interface 1 (optional)
43+
node2: home node for interface 2 (optional)
44+
deleteIntfs: delete intfs before creating them
45+
runCmd: function to run shell commands (quietRun)
46+
raises Exception on failure"""
47+
if not runCmd:
48+
runCmd = util.quietRun if not node1 else node1.cmd
49+
runCmd2 = util.quietRun if not node2 else node2.cmd
50+
if deleteIntfs:
51+
# Delete any old interfaces with the same names
52+
runCmd('ip link del ' + intf1)
53+
runCmd2('ip link del ' + intf2)
54+
"""cmdOutput = util.run('ip tuntap add %s mode tap' %
55+
(intf1))
56+
if cmdOutput:
57+
raise Exception("Error creating interface pair (%s,%s): %s " %
58+
(intf1, intf2, cmdOutput))
59+
cmdOutput = util.run('ip tuntap add %s mode tap' %
60+
(intf2))
61+
if cmdOutput:
62+
raise Exception("Error creating interface pair (%s,%s): %s " %
63+
(intf1, intf2, cmdOutput))"""
64+
# Create new pair
65+
netns = 1 if not node2 else node2.pid
66+
print('\nctapudp -s 0.0.0.0 -p %i -t 127.0.0.1 -k %i -i %s -a 1 -q 127.0.0.1 -r 55554 -e 100\n' % (
67+
makeIntfPair.portscount, makeIntfPair.portscount + 1, intf1))
68+
print('\nctapudp -s 0.0.0.0 -p %i -t 127.0.0.1 -k %i -i %s -a 1 -q 127.0.0.1 -r 55554 -e 100\n' % (
69+
makeIntfPair.portscount + 1, makeIntfPair.portscount, intf2))
70+
process = subprocess.Popen(
71+
['ctapudp', '-s', '127.0.0.1', '-p', str(makeIntfPair.portscount), '-t', '127.0.0.1', '-k',
72+
str(makeIntfPair.portscount + 1), '-i', intf1, '-a', '1', '-q', '127.0.0.1', '-r', '55554', '-e',
73+
'100'""", '-d', '1'"""], preexec_fn=os.setpgrp)
74+
QKLink.processes.append(process)
75+
process = subprocess.Popen(
76+
['ctapudp', '-s', '127.0.0.1', '-p', str(makeIntfPair.portscount + 1), '-t', '127.0.0.1', '-k',
77+
str(makeIntfPair.portscount), '-i', intf2, '-a', '1', '-q', '127.0.0.1', '-r', '55554', '-e',
78+
'100'""", '-d', '1'"""], preexec_fn=os.setpgrp)
79+
QKLink.processes.append(process)
80+
time.sleep(0.5)
81+
makeIntfPair.portscount = makeIntfPair.portscount + 2
82+
if addr1 is None:
83+
cmdOutput = util.run('ip link set %s '
84+
'netns %s' %
85+
(intf1, node1.pid))
86+
else:
87+
cmdOutput = util.run('ip link set %s address %s '
88+
'netns %s' %
89+
(intf1, addr1, node1.pid))
90+
91+
if cmdOutput:
92+
for p in QKLink.processes:
93+
p.kill()
94+
raise Exception("Error creating interface pair (%s,%s): %s " %
95+
(intf1, intf2, cmdOutput))
96+
if addr2 is None:
97+
cmdOutput = util.run('ip link set %s '
98+
'netns %s' %
99+
(intf2, netns))
100+
else:
101+
cmdOutput = util.run('ip link set %s address %s '
102+
'netns %s' %
103+
(intf2, addr2, netns))
104+
105+
if cmdOutput:
106+
for p in QKLink.processes:
107+
p.kill()
108+
raise Exception("Error creating interface pair (%s,%s): %s " %
109+
(intf1, intf2, cmdOutput))
110+
111+
112+
makeIntfPair.portscount = 3333
113+
114+
LINKS = {'default': Link, # Note: overridden below
115+
'tc': TCLink,
116+
'tcu': TCULink,
117+
'ovs': OVSLink,
118+
'qk': QKLink}
119+
120+
print('/root/qnet/keyworker/keyworker -n db1')
121+
process = subprocess.Popen(
122+
['keyworker', '-n', '/opt/bal/var/db1','-w','2'""", '-d', '1'"""], preexec_fn=os.setpgrp)
123+
124+
125+
def exit_handler():
126+
process.kill()
127+
128+
atexit.register(exit_handler)

bal/QTopo.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
from mininet.topo import Topo
2+
from mininet.link import Link
3+
from mininet import util
4+
from mininet.node import OVSSwitch
5+
import time
6+
import subprocess
7+
import os
8+
import atexit
9+
10+
11+
class QKLink(Link):
12+
@classmethod
13+
def makeIntfPair(cls, intfname1, intfname2, addr1=None, addr2=None,
14+
node1=None, node2=None, deleteIntfs=True):
15+
"""Create pair of interfaces
16+
intfname1: name for interface 1
17+
intfname2: name for interface 2
18+
addr1: MAC address for interface 1 (optional)
19+
addr2: MAC address for interface 2 (optional)
20+
node1: home node for interface 1 (optional)
21+
node2: home node for interface 2 (optional)
22+
(override this method [and possibly delete()]
23+
to change link type)"""
24+
# Leave this as a class method for now
25+
assert cls
26+
return makeIntfPair(intfname1, intfname2, addr1, addr2, node1, node2,
27+
deleteIntfs)
28+
29+
def stop(self):
30+
for p in QKLink.processes:
31+
p.kill()
32+
self.delete()
33+
34+
35+
QKLink.processes = []
36+
37+
38+
def makeIntfPair(intf1, intf2, addr1=None, addr2=None, node1=None, node2=None,
39+
deleteIntfs=True, runCmd=None):
40+
"""Make a veth pair connnecting new interfaces intf1 and intf2
41+
intf1: name for interface 1
42+
intf2: name for interface 2
43+
addr1: MAC address for interface 1 (optional)
44+
addr2: MAC address for interface 2 (optional)
45+
node1: home node for interface 1 (optional)
46+
node2: home node for interface 2 (optional)
47+
deleteIntfs: delete intfs before creating them
48+
runCmd: function to run shell commands (quietRun)
49+
raises Exception on failure"""
50+
if not runCmd:
51+
runCmd = util.quietRun if not node1 else node1.cmd
52+
runCmd2 = util.quietRun if not node2 else node2.cmd
53+
if deleteIntfs:
54+
# Delete any old interfaces with the same names
55+
runCmd('ip link del ' + intf1)
56+
runCmd2('ip link del ' + intf2)
57+
"""cmdOutput = util.run('ip tuntap add %s mode tap' %
58+
(intf1))
59+
if cmdOutput:
60+
raise Exception("Error creating interface pair (%s,%s): %s " %
61+
(intf1, intf2, cmdOutput))
62+
cmdOutput = util.run('ip tuntap add %s mode tap' %
63+
(intf2))
64+
if cmdOutput:
65+
raise Exception("Error creating interface pair (%s,%s): %s " %
66+
(intf1, intf2, cmdOutput))"""
67+
# Create new pair
68+
netns = 1 if not node2 else node2.pid
69+
print(
70+
'\nctapudp -s 0.0.0.0 -p %i -t 127.0.0.1 -k %i -i %s -a 1 -q 127.0.0.1 -r 55554 -e 100\n' % (
71+
makeIntfPair.portscount, makeIntfPair.portscount + 1, intf1))
72+
print(
73+
'\nctapudp -s 0.0.0.0 -p %i -t 127.0.0.1 -k %i -i %s -a 1 -q 127.0.0.1 -r 55554 -e 100\n' % (
74+
makeIntfPair.portscount + 1, makeIntfPair.portscount, intf2))
75+
process = subprocess.Popen(
76+
['ctapudp', '-s', '127.0.0.1', '-p', str(makeIntfPair.portscount), '-t', '127.0.0.1',
77+
'-k',
78+
str(makeIntfPair.portscount + 1), '-i', intf1, '-a', '1', '-q', '127.0.0.1', '-r', '55554', '-e',
79+
'100'""", '-d', '1'"""], preexec_fn=os.setpgrp)
80+
QKLink.processes.append(process)
81+
process = subprocess.Popen(
82+
['ctapudp', '-s', '127.0.0.1', '-p', str(makeIntfPair.portscount + 1), '-t', '127.0.0.1',
83+
'-k',
84+
str(makeIntfPair.portscount), '-i', intf2, '-a', '1', '-q', '127.0.0.1', '-r', '55554', '-e',
85+
'100'""", '-d', '1'"""], preexec_fn=os.setpgrp)
86+
QKLink.processes.append(process)
87+
time.sleep(0.5)
88+
makeIntfPair.portscount = makeIntfPair.portscount + 2
89+
if addr1 is None:
90+
cmdOutput = util.run('ip link set %s '
91+
'netns %s' %
92+
(intf1, node1.pid))
93+
else:
94+
cmdOutput = util.run('ip link set %s address %s '
95+
'netns %s' %
96+
(intf1, addr1, node1.pid))
97+
98+
if cmdOutput:
99+
for p in QKLink.processes:
100+
p.kill()
101+
raise Exception("Error creating interface pair (%s,%s): %s " %
102+
(intf1, intf2, cmdOutput))
103+
if addr2 is None:
104+
cmdOutput = util.run('ip link set %s '
105+
'netns %s' %
106+
(intf2, netns))
107+
else:
108+
cmdOutput = util.run('ip link set %s address %s '
109+
'netns %s' %
110+
(intf2, addr2, netns))
111+
112+
if cmdOutput:
113+
for p in QKLink.processes:
114+
p.kill()
115+
raise Exception("Error creating interface pair (%s,%s): %s " %
116+
(intf1, intf2, cmdOutput))
117+
118+
119+
makeIntfPair.portscount = 3333
120+
121+
122+
class QTopo(Topo):
123+
"2 switch 2 host connetcted by QKLink custom topology"
124+
125+
def __init__(self):
126+
"Create custom topo."
127+
128+
# Initialize topology
129+
Topo.__init__(self)
130+
131+
# Add hosts and switches
132+
leftHost = self.addHost('h1')
133+
rightHost = self.addHost('h2')
134+
leftSwitch = self.addSwitch('s1', cls = OVSSwitch, protocols='OpenFlow13', dpid='000016ccbbe0d642')
135+
rightSwitch = self.addSwitch('s2', cls = OVSSwitch, protocols='OpenFlow13', dpid='00001ad87e868d45')
136+
137+
# Add links
138+
self.addLink(leftHost, leftSwitch, cls=QKLink)
139+
self.addLink(rightHost, rightSwitch, cls=QKLink)
140+
self.addLink(leftSwitch, rightSwitch)
141+
self.addLink(leftSwitch, rightSwitch, cls=QKLink)
142+
143+
144+
process = subprocess.Popen(
145+
['keyworker', '-n', '/opt/bal/var/db1', '-w', '2'""", '-d', '1'"""],
146+
preexec_fn=os.setpgrp)
147+
148+
149+
def exit_handler():
150+
process.kill()
151+
152+
153+
atexit.register(exit_handler)
154+
topos = {'qtopo': (lambda: QTopo())}

bal/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+

bal/__version__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
VERSION = (1, 0, 1)
2+
3+
__version__ = '.'.join(map(str, VERSION))
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
from mininet.node import ( Host, CPULimitedHost )
2-
from bal.bcnode import ( EthNode, BtcNode, POWNode, QNode )
32
from mininet.util import specialClass
3+
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
4+
from mininet.topolib import TreeTopo
5+
from bal.bcnode import ( EthNode, BtcNode, POWNode, QNode )
6+
from bal.QTopo import QTopo
7+
48

59
HOSTDEF = 'proc'
610
HOSTS = { 'proc': Host,
@@ -10,3 +14,13 @@
1014
'pow': POWNode,
1115
'btc': BtcNode,
1216
'eth': EthNode}
17+
18+
TOPODEF = 'none'
19+
TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ),
20+
'linear': LinearTopo,
21+
'reversed': SingleSwitchReversedTopo,
22+
'single': SingleSwitchTopo,
23+
'none': None,
24+
'tree': TreeTopo,
25+
'qtopo': QTopo }
26+

0 commit comments

Comments
 (0)