<div dir="ltr"><div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">It sounds like you're on to a solution, but here are some other thoughts...</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"><br></div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">1) Depending on what kind of switch you're using and exactly how your controllers are supposed to work... it may be possible to just have the switch connect to multiple controllers (and have the controllers behave differently) rather than have one controller connect to another.</div></div><div><br></div><div>2) You're having the first controller send the redirected packet-in to the second controller's normal OpenFlow-listening-port. Which, as you found, is problematic. Because the second controller is expecting a switch to connect which does some handshaking which you're not doing. Why not just have the second controller like... open a socket and listen on it? Why have it go through the normal OpenFlow processing stuff at all? You could use POX's messenger component for this (though it's not ideal for this use case). Or you should be able to use the ioworker stuff to open a socket and listen easily. Or you could just write it by hand. Or you could just send the packet-in data between controller using some Python RPC library (RPyC would probably work).</div><div><br></div><div>3) Again, this doesn't seem necessary, but you could have controller 1 act like a proper OpenFlow switch which just happens to only send packet-in messages. The datapaths.switch.SoftwareSwitchBase class will maintain a connection to a controller. Create a subclass of it in controller 1 (you actually may not even need to subclass it!) and have it send the packet-ins to controller 2 using its .send() method. This is probably overkill, even. You could probably just hardcode enough of the handshake into controller 1. (But using SoftwareSwitchBase seems like it'd be really easy with no particular downside?)</div><div><br></div><div>As a sidenote, carp is like 5 years out of date. eel has updates like six months ago. fangtooth (in my fork) has updates last month.</div><div><br></div><div>Good luck.</div><div><br></div><div>-- Murphy</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 13, 2018 at 8:22 AM, 夏瑞 <span dir="ltr"><<a href="mailto:xiarui0428@163.com" target="_blank">xiarui0428@163.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="line-height:1.7;color:#000000;font-size:14px;font-family:Arial"><div>I'm trying to modify the source code of POX to realize my idea.</div><div><br></div><div>I find that the "ofnexus" is the key module for processing an event, like "Packet_In". This is the code snippet in "pox/openflow/of_01.py"</div><div>##############################<wbr>##############################<wbr>#######</div><div><div>def handle_PACKET_IN (con, msg): #A</div><div> e = con.ofnexus.<wbr>raiseEventNoErrors(PacketIn, con, msg)</div><div> if e is None or e.halt != True:</div><div> con.raiseEventNoErrors(<wbr>PacketIn, con, msg)</div></div><div>##############################<wbr>##############################<wbr>#######</div><div><br></div><div>"con.ofnexus" will trigger my customized "_handle_packet_in". However, this value is "_dummyOFNexus" by default, which is set in "__init__()" function of class "Connection".</div><div>##############################<wbr>##############################<wbr>#######</div><div><div>class DummyOFNexus (object):</div><div> def raiseEventNoErrors (self, event, *args, **kw):</div><div> log.warning("%s raised on dummy OpenFlow nexus" % event)</div><div> def raiseEvent (self, event, *args, **kw):</div><div> log.warning("%s raised on dummy OpenFlow nexus" % event)</div><div> def _disconnect (self, dpid):</div><div> log.warning("%s disconnected on dummy OpenFlow nexus",</div><div> pox.lib.util.dpidToStr(dpid))</div><div><br></div><div>_dummyOFNexus = DummyOFNexus()</div></div><div>##############################<wbr>##############################<wbr>#######</div><div><br></div><div>The value of "con.ofnexus" is formally set in "handle_request_reply" function:</div><div>##############################<wbr>##############################<wbr>#######</div><div><div> nexus = core.<wbr>OpenFlowConnectionArbiter.<wbr>getNexus(con)</div><div> if nexus is None:</div><div> # Cancel connection</div><div> <a href="http://con.info" target="_blank">con.info</a>("No OpenFlow nexus for " +</div><div> pox.lib.util.dpidToStr(msg.<wbr>datapath_id))</div><div> con.disconnect()</div><div> return</div><div> con.ofnexus = nexus</div><div> con.ofnexus._connect(con)</div></div><div>##############################<wbr>##############################<wbr>#######</div><div><br></div><div>So I come up with an idea, I manually set the value of "con.ofnexus". In this way, customized "_handle_packet_in" will be triggered:</div><div>##############################<wbr>##############################<wbr>#######</div><div><div>def handle_PACKET_IN (con, msg): #A</div><div> if con.ofnexus is _dummyOFNexus:</div><div> con.ofnexus = core.<wbr>OpenFlowConnectionArbiter.<wbr>getNexus(con)</div><div> e = con.ofnexus.<wbr>raiseEventNoErrors(PacketIn, con, msg)</div><div> if e is None or e.halt != True:</div><div> con.raiseEventNoErrors(<wbr>PacketIn, con, msg)</div></div><div>##############################<wbr>##############################<wbr>####### </div><div><br></div><div>I was wondering if there are some underlying bugs in my modification. Any comments or suggestions are welcomed. Thank you for sharing.</div><div><br></div><div>Best wishes.</div><div>Xia</div><div><div class="h5"><br><div style="zoom:1"></div><div id="m_4687532118790117124divNeteaseMailCard"></div><br>At 2018-06-13 13:30:35, "夏瑞" <<a href="mailto:xiarui0428@163.com" target="_blank">xiarui0428@163.com</a>> wrote:<br> <blockquote id="m_4687532118790117124isReplyContent" style="PADDING-LEFT:1ex;MARGIN:0px 0px 0px 0.8ex;BORDER-LEFT:#ccc 1px solid"><div style="line-height:1.7;color:#000000;font-size:14px;font-family:Arial"><div style="line-height:1.7"><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">Hello, </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">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`**.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">I am trying to implement my idea by POX, but I got some mistakes.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">This is the code of `c1`, only `_handle_packet_in` is shown:</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">##############################<wbr>##############################<wbr>######</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> def _handle_PacketIn(self, event):</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> log.debug("Switch %s has a PacketIn: [port: %d, ...]", event.dpid, event.port)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> self._redirect_packet(event)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> def _redirect_packet(self, event):</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> log.debug("Send packet to 6634!")</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> TCP_IP = '10.0.2.15'</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> TCP_PORT = 6634</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> BUFFER_SIZE = 1024</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> packet = event.ofp</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # I attach all the payload of OpenFlow Packet_In to the new packet</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> MESSAGE = packet.pack() </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # MESSAGE = MESSAGE + 'Hello world'</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s.connect((TCP_IP, TCP_PORT))</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s.send(MESSAGE)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # s.close()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">##############################<wbr>##############################<wbr>#####</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">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)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">##############################<wbr>##############################<wbr>#####</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> from <a href="http://mininet.net" target="_blank">mininet.net</a> import Mininet</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> from mininet.node import Controller, OVSSwitch</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> from mininet.cli import CLI</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> from mininet.log import setLogLevel</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> from mininet.node import RemoteController</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> def multiControllerNet():</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> "Create a network from semi-scratch with multiple controllers."</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> net = Mininet( controller=Controller, switch=OVSSwitch, autoSetMacs=True )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Creating (reference) controllers"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # c1 = net.addController( 'c1', port=6633 )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # c2 = net.addController( 'c2', port=6634 )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> c1 = net.addController('c1', controller=RemoteController, ip='10.0.2.15', port=6633)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> c2 = net.addController('c2', controller=RemoteController, ip='10.0.2.15', port=6634)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Creating switches"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s1 = net.addSwitch( 's1' )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s2 = net.addSwitch( 's2' )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Creating hosts"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> hosts1 = [ net.addHost( 'h%d' % n ) for n in 3, 4 ]</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> hosts2 = [ net.addHost( 'h%d' % n ) for n in 5, 6 ]</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Creating links"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> for h in hosts1:</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> net.addLink( s1, h )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> for h in hosts2:</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> net.addLink( s2, h )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> net.addLink( s1, s2 )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Starting network"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> net.build()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # c1.start()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> c2.start()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s1.start( [ c1 ] )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # s1.start([c2])</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> s2.start( [ c2 ] )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # s2.start([c2])</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # print "*** Testing network"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> # net.pingAll()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Running CLI"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> CLI( net )</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> print "*** Stopping network"</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> net.stop()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> </div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> if __name__ == '__main__':</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> setLogLevel( 'info' ) # for CLI output</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"> multiControllerNet()</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">##############################<wbr>##############################<wbr>#####</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">Then, I start two controllers at my host with different ports, `6633, 6634`. Open `c1`:</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">```</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">../pox.py openflow.of_01 --port=6633 --address=10.0.2.15 openflow_test log.level --DEBUG</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">```</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">and, open `c2`</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">```</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">../pox.py openflow.of_01 --port=6634 --address=10.0.2.15 openflow_test_2 log.level --DEBUG</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">```</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">`c1` has only the `_handle_packet_in` handler which is shown above. `c2` has no function.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">I try to `ping` between `h3` (controlled by `c1`) to `h5` (controller by `c2`), in order to trigger `_handle_packet_in` handler.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">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).</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">However, `c2` doesn't accept this packet, and warn that this is dummy OpenFlowNexus. This is the error:</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">##############################<wbr>#####################</div><div><div>WARNING:openflow.of_01:<class 'pox.openflow.PacketIn'> raised on dummy OpenFlow nexus</div><div>INFO:openflow.of_01:[None 8] closed</div></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">##############################<wbr>#####################</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">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**.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">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`.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">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.</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">I am using POX 0.2.0 (carp)</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px"><br></div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">Best wishes,</div><div style="color:rgb(0,0,0);font-family:Arial;font-size:14px">Xia</div></div><br><br><span title="neteasefooter"><p> </p></span></div><br><br><span title="neteasefooter"><p> </p></span></blockquote></div></div></div><br><br><span title="neteasefooter"><div id="m_4687532118790117124netease_mail_footer"><div style="border-top:#ccc 1px solid;padding:10px 5px;font-size:16px;color:#777;line-height:22px"><a href="http://you.163.com/item/detail?id=1092001&from=web_gg_mail_jiaobiao_7" style="color:#3366ff;text-decoration:none" target="_blank">【网易自营|30天无忧退货】爱上书写:<wbr>施华洛世奇制造商星空原色水晶笔,限时仅29元>></a>
</div></div></span></blockquote></div><br></div>