Reputation: 335
I am trying to redirect ofp_packet_in
packet among multiple controllers. For example, suppose there are two controllers c1,c2
and one switch s1
. s1
is assigned to c1
. Now, c1
receives a Packet_In
from switch s1
. Generally, s1
should dispose of this Packet_In
. What I am trying to do is to send this Packet_In
to c2
and let c2
process this Packet_In
.
I am trying to implement my idea by POX, but I got some mistakes.
This is the code of c1
, only _handle_packet_in
is shown:
def _handle_PacketIn(self, event):
log.debug("Switch %s has a PacketIn: [port: %d, ...]", event.dpid, event.port)
self._redirect_packet(event)
def _redirect_packet(self, event):
log.debug("Send packet to 6634!")
TCP_IP = '10.0.2.15'
TCP_PORT = 6634
BUFFER_SIZE = 1024
packet = event.ofp
# I attach all the payload of OpenFlow Packet_In to the new packet
MESSAGE = packet.pack()
# MESSAGE = MESSAGE + 'Hello world'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
# s.close()
Then I start Mininet and build the topology. (Here the topology has little difference with the formal description, however, it is clear and modified from Mininet example controllers2.py)
from mininet.net import Mininet
from mininet.node import Controller, OVSSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel
from mininet.node import RemoteController
def multiControllerNet():
"Create a network from semi-scratch with multiple controllers."
net = Mininet( controller=Controller, switch=OVSSwitch, autoSetMacs=True )
print "*** Creating (reference) controllers"
# c1 = net.addController( 'c1', port=6633 )
# c2 = net.addController( 'c2', port=6634 )
c1 = net.addController('c1', controller=RemoteController, ip='10.0.2.15', port=6633)
c2 = net.addController('c2', controller=RemoteController, ip='10.0.2.15', port=6634)
print "*** Creating switches"
s1 = net.addSwitch( 's1' )
s2 = net.addSwitch( 's2' )
print "*** Creating hosts"
hosts1 = [ net.addHost( 'h%d' % n ) for n in 3, 4 ]
hosts2 = [ net.addHost( 'h%d' % n ) for n in 5, 6 ]
print "*** Creating links"
for h in hosts1:
net.addLink( s1, h )
for h in hosts2:
net.addLink( s2, h )
net.addLink( s1, s2 )
print "*** Starting network"
net.build()
# c1.start()
c2.start()
s1.start( [ c1 ] )
# s1.start([c2])
s2.start( [ c2 ] )
# s2.start([c2])
# print "*** Testing network"
# net.pingAll()
print "*** Running CLI"
CLI( net )
print "*** Stopping network"
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' ) # for CLI output
multiControllerNet()
Then, I start two controllers at my host with different ports, 6633, 6634
. Open c1
:
../pox.py openflow.of_01 --port=6633 --address=10.0.2.15 openflow_test log.level --DEBUG
and, open c2
../pox.py openflow.of_01 --port=6634 --address=10.0.2.15 openflow_test_2 log.level --DEBUG
c1
has only the _handle_packet_in
handler which is shown above. c2
has no function.
I try to ping
between h3
(controlled by c1
) to h5
(controller by c2
), in order to trigger _handle_packet_in
handler.
I use wireshark to capture the of_packet_in
packet, and the new redirect packet
It is clear that they have the same payload (OpenFlow packet).
However, c2
doesn't accept this packet, and warn that this is dummy OpenFlowNexus. This is the error:
I guess, even if c1
sends a legal OpenFlow of_packet_in
to c2
, c2
has no idea about "who is c1
", for c1
has not registered to c1
using OpenFlow of_hello
, of_features_request
,.... Therefore, c2
discard the OpenFlow of_packet_in
sent by c1
, and say dummy.
I only want to let c2
process the Packet_In
redirected by c1
. In this way, c2
can calculate and install table entries for table-miss
event happened in s1
.
Maybe I can use other controllers, like floodlight, ONOS..., to solve this problem. Maybe this problem cannot be solved. Thank you for sharing your idea, best wishes.
I am using POX 0.2.0 (carp)
Upvotes: 0
Views: 798
Reputation: 440
You connect c1 to c2 as if c1 is a switch and you expect c2 to treat c1 like that. However, c1 did no represent itself like this. In fact, c1 did not introduce itself to c2 in no way. Each switch that connects to a controller follows a certain identification protocol and you can see that happen in ConnectionUp handler. c1 does not trigger this handler at c2.
c1 can identify itself as a switch to c2 and then redirect packets to it. However, to my mind, this is too cumbersome. I would recommend that c1 connect to c2 out-of-band and communicate with c2 in their own protocol(rules). For example, c2 waits for a connection on a different port. When c1 connects, c2 waits for redirected packets. c1 redirects a packet with the required context to c2, and c2 decides on action upon receiving the packet and the required context.
Upvotes: 0