POX Python Codes

29
Custom.py #!/usr/bin/python # Mininet Example Copyright 2012 William Yu # [email protected] from mininet.net import Mininet from mininet.cli import CLI net = Mininet() # Creating nodes in the network. c0 = net.addController() h0 = net.addHost('h0') s0 = net.addSwitch('s0') h1 = net.addHost('h1') # Creating links between nodes in network net.addLink(h0, s0) net.addLink(h1, s0) # Configuration of IP addresses in interfaces h0.setIP('192.168.1.1', 24) h1.setIP('192.168.1.2', 24) net.start() net.pingAll() CLI(net) net.stop()

description

Mininet examples

Transcript of POX Python Codes

  • Custom.py #!/usr/bin/python # Mininet Example Copyright 2012 William Yu # [email protected] from mininet.net import Mininet from mininet.cli import CLI net = Mininet() # Creating nodes in the network. c0 = net.addController() h0 = net.addHost('h0') s0 = net.addSwitch('s0') h1 = net.addHost('h1') # Creating links between nodes in network net.addLink(h0, s0) net.addLink(h1, s0) # Configuration of IP addresses in interfaces h0.setIP('192.168.1.1', 24) h1.setIP('192.168.1.2', 24) net.start() net.pingAll() CLI(net) net.stop()

  • Fanout.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    #!/usr/bin/python # Mininet Example Copyright 2012 William Yu # [email protected]

    from mininet.net import Mininet from mininet.topolib import TreeTopo Tree22 = TreeTopo(depth=2, fanout=2) net = Mininet(topo=Tree22)

    net.start() net.pingAll() net.stop()

  • Linear.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    #!/usr/bin/python

    # Mininet Example Copyright 2012 William Yu # [email protected]

    from mininet.net import Mininet from mininet.topo import LinearTopo Linear4 = LinearTopo(k=4) net = Mininet(topo=Linear4) net.start()

    net.pingAll() net.stop()

  • Perf.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    #!/usr/bin/python # Mininet Example Copyright 2012 William Yu

    # [email protected]

    from mininet.net import Mininet from mininet.node import CPULimitedHost from mininet.link import TCLink from mininet.cli import CLI

    net = Mininet(host=CPULimitedHost, link=TCLink)

    c0 = net.addController()

    s0 = net.addSwitch('s0') h0 = net.addHost('h0', cpu=0.5) h1 = net.addHost('h1') h2 = net.addHost('h2')

    net.addLink(h0, s0, bw=10, delay='5ms', max_queue_size=1000, loss=10, use_htb=True) net.addLink(h1, s0)

    net.addLink(h2, s0)

    net.start() net.pingAll() CLI(net) net.stop()

  • Single.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    #!/usr/bin/python # Mininet Example Copyright 2012 William Yu # [email protected]

    from mininet.net import Mininet from mininet.topo import SingleSwitchTopo Single3 = SingleSwitchTopo(k=3) net = Mininet(topo=Single3)

    net.start() net.pingAll() net.stop()

  • Flowstats.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    #!/usr/bin/python # Copyright 2012 William Yu # [email protected] # # This file is part of POX. # # POX is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # POX is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of

    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with POX. If not, see . #

    """ This is a demonstration file created to show how to obtain flow and port statistics from OpenFlow 1.0-enabled switches. The flow statistics handler contains a summary of web-only traffic. """

    # standard includes from pox.core import core from pox.lib.util import dpidToStr import pox.openflow.libopenflow_01 as of

    # include as part of the betta branch from pox.openflow.of_json import *

    log = core.getLogger()

    # handler for timer function that sends the requests to all the # switches connected to the controller. def _timer_func (): for connection in core.openflow._connections.values(): connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) connection.send(of.ofp_stats_request(body=of.ofp_port_stats_request())) log.debug("Sent %i flow/port stats request(s)", len(core.openflow._connections))

    # handler to display flow statistics received in JSON format

    # structure of event.stats is defined by ofp_flow_stats() def _handle_flowstats_received (event): stats = flow_stats_to_list(event.stats) log.debug("FlowStatsReceived from %s: %s", dpidToStr(event.connection.dpid), stats)

    # Get number of bytes/packets in flows for web traffic only web_bytes = 0 web_flows = 0 web_packet = 0 for f in event.stats: if f.match.tp_dst == 80 or f.match.tp_src == 80: web_bytes += f.byte_count web_packet += f.packet_count web_flows += 1 log.info("Web traffic from %s: %s bytes (%s packets) over %s flows", dpidToStr(event.connection.dpid), web_bytes, web_packet, web_flows)

  • 64

    65

    66

    67

    68

    69

    70

    # handler to display port statistics received in JSON format def _handle_portstats_received (event): stats = flow_stats_to_list(event.stats) log.debug("PortStatsReceived from %s: %s", dpidToStr(event.connection.dpid), stats)

    # main functiont to launch the module def launch (): from pox.lib.recoco import Timer

    # attach handsers to listners core.openflow.addListenerByName("FlowStatsReceived", _handle_flowstats_received) core.openflow.addListenerByName("PortStatsReceived", _handle_portstats_received)

    # timer set to execute every five seconds

    Timer(5, _timer_func, recurring=True)

  • Of_double_controller.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    #!/usr/bin/python # Copyright 2012 William Yu # [email protected] # from mininet.net import Mininet from mininet.node import Controller, OVSKernelSwitch, RemoteController from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.util import createLink

    def createDoubleControllerNetwork(): info( '*** Creating network for Double Controller Example\n' )

    # Create an empty network. net = Mininet(switch=OVSKernelSwitch) c0 = net.addController('c0', controller=RemoteController, defaultIP="127.0.0.1", port=6633) c1 = net.addController('c1', controller=RemoteController, defaultIP="127.0.0.1", port=6644)

    # Creating nodes in the network. h0 = net.addHost('h0') h1 = net.addHost('h1') s0 = net.addSwitch('s0') h2 = net.addHost('h2') h3 = net.addHost('h3') s1 = net.addSwitch('s1')

    # Creating links between nodes in network. h0int, s0int = createLink(h0, s0) h1int, s0int = createLink(h1, s0) h2int, s1int = createLink(h2, s1) h3int, s1int = createLink(h3, s1) s0int, s1int = createLink(s0, s1)

    # Configuration of IP addresses in interfaces h0.setIP(h0int, '192.168.1.2', 26) h1.setIP(h1int, '192.168.1.3', 26) h2.setIP(h2int, '192.168.1.66', 26) h3.setIP(h3int, '192.168.1.67', 26)

    # Start network net.build()

    # Attaching Controllers to Switches s0.start([c0]) s1.start([c1])

    # Setting interface only routes and not default routes h0.cmd("route del -net 0.0.0.0") h1.cmd("route del -net 0.0.0.0") h2.cmd("route del -net 0.0.0.0") h3.cmd("route del -net 0.0.0.0") h0.cmd("route add -net 192.168.1.0 netmask 255.255.255.192 " + h0int) h1.cmd("route add -net 192.168.1.0 netmask 255.255.255.192 " + h1int)

    #!/usr/bin/python # Copyright 2012 William Yu # [email protected] # from mininet.net import Mininet from mininet.node import Controller, OVSKernelSwitch, RemoteController from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.util import createLink

    def createDoubleControllerNetwork(): info( '*** Creating network for

    Double Controller Example\n' )

    # Create an empty network. net = Mininet(switch=OVSKernelSwitch) c0 = net.addController('c0', controller=RemoteController, defaultIP="127.0.0.1",

    port=6633) c1 = net.addController('c1', controller=RemoteController, defaultIP="127.0.0.1",

    port=6644)

    # Creating nodes in the

    network. h0 = net.addHost('h0') h1 = net.addHost('h1') s0 = net.addSwitch('s0') h2 = net.addHost('h2') h3 = net.addHost('h3') s1 = net.addSwitch('s1')

    # Creating links between nodes

    in network. h0int, s0int = createLink(h0, s0) h1int, s0int = createLink(h1, s0) h2int, s1int = createLink(h2, s1) h3int, s1int = createLink(h3, s1) s0int, s1int = createLink(s0, s1)

    # Configuration of IP addresses

    in interfaces h0.setIP(h0int, '192.168.1.2',

    26)

  • 48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    h2.cmd("route add -net 192.168.1.64 netmask 255.255.255.192 " + h2int) h3.cmd("route add -net 192.168.1.64 netmask 255.255.255.192 " + h3int)

    # dump stuff on the screen info( '*** Network state:\n' ) for node in c0, c1, s0, s1, h0, h1, h2, h3: info( str( node ) + '\n' )

    # Start command line CLI(net)

    # Stop network net.stop()

    if __name__ == '__main__': setLogLevel( 'info' ) createDoubleControllerNetwork()

    h1.setIP(h1int, '192.168.1.3',

    26) h2.setIP(h2int, '192.168.1.66',

    26) h3.setIP(h3int, '192.168.1.67',

    26)

    # Start network net.build()

    # Attaching Controllers to

    Switches s0.start([c0]) s1.start([c1])

    # Setting interface only routes

    and not default routes h0.cmd("route del -net

    0.0.0.0") h1.cmd("route del -net

    0.0.0.0") h2.cmd("route del -net

    0.0.0.0") h3.cmd("route del -net

    0.0.0.0") h0.cmd("route add -net

    192.168.1.0 netmask 255.255.255.192

    " + h0int) h1.cmd("route add -net

    192.168.1.0 netmask 255.255.255.192

    " + h1int) h2.cmd("route add -net

    192.168.1.64 netmask

    255.255.255.192 " + h2int) h3.cmd("route add -net

    192.168.1.64 netmask

    255.255.255.192 " + h3int)

    # dump stuff on the screen info( '*** Network state:\n' ) for node in c0, c1, s0, s1, h0, h1, h2, h3: info( str( node ) + '\n' )

    # Start command line CLI(net)

    # Stop network net.stop()

    if __name__ == '__main__': setLogLevel( 'info' ) createDoubleControllerNetwork()

  • Of_firewall.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    #!/usr/bin/python

    # Copyright 2012 William Yu

    # [email protected]

    #

    # This file is part of POX.

    #

    # POX is free software: you can redistribute it and/or modify

    # it under the terms of the GNU General Public License as published by

    # the Free Software Foundation, either version 3 of the License, or

    # (at your option) any later version.

    #

    # POX is distributed in the hope that it will be useful,

    # but WITHOUT ANY WARRANTY; without even the implied warranty of

    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

    # GNU General Public License for more details.

    #

    # You should have received a copy of the GNU General Public License

    # along with POX. If not, see .

    #

    # NOISY FIREWALL. This is a simple firewall implementation for demonstration

    # purposes. This firewall is bad because only flows for valid packets are

    # installed. Non-matches always trigger a PacketIn().

    #

    # This is a demonstration file aims to build a firewall. In this demo,

    # firewall rules are applied to specific ports in the switch using the

    # following commands:

    # AddRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL)

    # DeleteRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL):

    # ShowRule ()

    #

    # Mininet Command Line: sudo mn --topo single,3 --mac --switch ovsk --controller remote

    # Command Line: ./pox.py py log.level --DEBUG samples.of_firewall

    #

    # THIS VERSION SUPPORT resend() functionality in the betta branch POX.

    #

    # These next two imports are common POX convention

    from pox.core import core

    from pox.lib.util import dpidToStr

    import pox.openflow.libopenflow_01 as of

    from pox.lib.packet.ethernet import ethernet

    # Even a simple usage of the logger is much nicer than print!

    log = core.getLogger()

    # This table maps (switch,MAC-addr) pairs to the port on 'switch' at

    # which we last saw a packet *from* 'MAC-addr'.

    # (In this case, we use a Connection object for the switch.)

    table = {}

    # This table contains the firewall rules:

    # firewall[(switch, dl_type, nw_proto, port, src_port)] = TRUE/FALSE

    #

    # Our firewall only supports inbound rule enforcement per port only.

    # By default, this is empty.

    # Sample dl_type(s): IP (0x800)

    # Sample nw_proto(s): ICMP (1), TCP (6), UDP (17)

    #

    firewall = {}

    # function that allows adding firewall rules into the firewall table

    def AddRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL):

    firewall[(event.connection,dl_type,nw_proto,port,src_port)]=True

    log.debug("Adding firewall rule to %s: %s %s %s %s" %

    dpidToStr(event.connection.dpid), dl_type, nw_proto, port, src_port)

    # function that allows deleting firewall rules from the firewall table

    def DeleteRule (event, dl_type=0x800, nw_proto=1, port=0, src_port=of.OFPP_ALL):

    try:

    del firewall[(event.connection,dl_type,nw_proto,port,src_port)]

    log.debug("Deleting firewall rule in %s: %s %s %s %s" %

    dpidToStr(event.connection.dpid), dl_type, nw_proto, port, src_port)

    except KeyError:

    log.error("Cannot find in %s: %s %s %s %s" %

    dpidToStr(event.connection.dpid), dl_type, nw_proto, port, src_port)

    # function to display firewall rules

    def ShowRules ():

    for key in firewall:

    log.info("Rule %s defined" % key)

    # function to handle all housekeeping items when firewall starts

  • 82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    def _handle_StartFirewall (event):

    log.info("Firewall Tutorial is running.")

    # function to handle all PacketIns from switch/router

    def _handle_PacketIn (event):

    packet = event.parsed

    # only process Ethernet packets

    if packet.type != ethernet.IP_TYPE:

    return

    # check if packet is compliant to rules before proceeding

    if (firewall[(event.connection, packet.dl_type, packet.nw_proto, packet.tp_src, event.port)] == True):

    log.debug("Rule (%s %s %s %s) FOUND in %s" %

    dpidToStr(event.connection.dpid), packet.dl_type, packet.nw_proto, packet.tp_src, event.port)

    else:

    log.debug("Rule (%s %s %s %s) NOT FOUND in %s" %

    dpidToStr(event.connection.dpid), packet.dl_type, packet.nw_proto, packet.tp_src, event.port)

    return

    # Learn the source and fill up routing table

    table[(event.connection,packet.src)] = event.port

    dst_port = table.get((event.connection,packet.dst))

    if dst_port is None:

    # We don't know where the destination is yet. So, we'll just

    # send the packet out all ports (except the one it came in on!)

    msg = of.ofp_packet_out(resend = event.ofp)

    msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))

    msg.send(event.connection)

    log.debug("Broadcasting %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    else:

    # Since we know the switch ports for both the source and dest

    # MACs, we can install rules for both directions.

    msg = of.ofp_flow_mod()

    msg.match.dl_type = packet.dl_type

    msg.match.nw_proto = packet.nw_proto

    if (nw_proto != 1):

    msg.match.tp_src = packet.tp_src

    msg.match.dl_dst = packet.src

    msg.match.dl_src = packet.dst

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.actions.append(of.ofp_action_output(port = event.port))

    msg.send(event.connection)

    # This is the packet that just came in -- we want to

    # install the rule and also resend the packet.

    msg = of.ofp_flow_mod()

    msg.match.dl_type = packet.dl_type

    msg.match.nw_proto = packet.nw_proto

    if (nw_proto != 1):

    msg.match.tp_src = packet.tp_src

    msg.match.dl_src = packet.src

    msg.match.dl_dst = packet.dst

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.actions.append(of.ofp_action_output(port = dst_port))

    msg.send(event.connection, resend = event.ofp)

    log.debug("Installing %s.%i -> %s.%i AND %s.%i -> %s.%i" %

    (packet.dst, dst_port, packet.src, event.ofp.in_port,

    packet.src, event.ofp.in_port, packet.dst, dst_port))

    # main function to start module

    def launch ():

    core.openflow.addListenerByName("ConnectionUp", _handle_StartFirewall)

    core.openflow.addListenerByName("PacketIn", _handle_PacketIn)

  • Of_router_topo.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    #!/usr/bin/python # Copyright 2012 William Yu # [email protected] # # Sample network for creating an OpenFlow Static Router. # # This is a demonstration file aims to build a simple static router. # Network A (192.168.1.0/26) # Router A (192.168.1.1, 192.168.1.129) # Router B (192.168.1.65, 192.168.1.130) # Network B (192.168.1.64/26) #

    from mininet.net import Mininet from mininet.node import Controller, OVSKernelSwitch, RemoteController from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.util import createLink

    def createStaticRouterNetwork(): info( '*** Creating network for Static Router Example\n' )

    # Create an empty network. net = Mininet(controller=RemoteController, switch=OVSKernelSwitch) net.addController('c0')

    # Creating nodes in the network. h0 = net.addHost('h0') s0 = net.addSwitch('s0') h1 = net.addHost('h1') s1 = net.addSwitch('s1')

    # Creating links between nodes in network. h0int, s0int = createLink(h0, s0) h1int, s1int = createLink(h1, s1) s0pint, s1pint = createLink(s0, s1)

    # Configuration of IP addresses in interfaces s0.setIP(s0int, '192.168.1.1', 26) h0.setIP(h0int, '192.168.1.2', 26) s1.setIP(s1int, '192.168.1.65', 26) h1.setIP(h1int, '192.168.1.66', 26) s0.setIP(s0pint, '192.168.1.129', 26) s1.setIP(s1pint, '192.168.1.130', 26)

    info( '*** Network state:\n' ) for node in s0, s1, h0, h1: info( str( node ) + '\n' )

    # Start command line

  • 51

    52

    53

    54

    55

    56

    57

    58

    net.start() CLI(net) net.stop()

    if __name__ == '__main__': setLogLevel( 'info' ) createStaticRouterNetwork()

  • Of_simple_switch.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    #!/usr/bin/python # Copyright 2012 William Yu # [email protected] # # Sample network for creating an OpenFlow Static Router. # # This is a demonstration file aims to build a simple static router. # Network A (192.168.1.0/26) # Switch # Network B (192.168.1.64/26) #

    from mininet.net import Mininet from mininet.node import Controller, OVSKernelSwitch, RemoteController from mininet.cli import CLI from mininet.log import setLogLevel, info from mininet.util import createLink

    def createStaticRouterNetwork(): info( '*** Creating network for Static Router Example\n' )

    # Create an empty network. net = Mininet(controller=RemoteController, switch=OVSKernelSwitch) net.addController('c0')

    # Creating nodes in the network. h0 = net.addHost('h0') s0 = net.addSwitch('s0') h1 = net.addHost('h1')

    # Creating links between nodes in network. h0int, s0int = createLink(h0, s0) h1int, s0int = createLink(h1, s0)

    # Configuration of IP addresses in interfaces h0.setIP(h0int, '192.168.1.2', 26) h1.setIP(h1int, '192.168.1.66', 26)

    info( '*** Network state:\n' ) for node in s0, h0, h1: info( str( node ) + '\n' )

    # Start command line net.start() CLI(net) net.stop()

    if __name__ == '__main__': setLogLevel( 'info' ) createStaticRouterNetwork()

  • 46

    Of_switch_flow.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    # Copyright 2012 James McCauley # # This file is part of POX. # # POX is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # POX is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with POX. If not, see .

    """ This component is for use with the OpenFlow tutorial.

    It acts as a simple hub, but can be modified to act like an L2 learning switch.

    It's quite similar to the one for NOX. Credit where credit due. :) """

    from pox.core import core import pox.openflow.libopenflow_01 as of

    log = core.getLogger()

    class Tutorial (object): """ A Tutorial object is created for each switch that connects. A Connection object for that switch is passed to the __init__ function. """ def __init__ (self, connection): # Keep track of the connection to the switch so that we can # send it messages! self.connection = connection

    # This binds our PacketIn event listener connection.addListeners(self)

    # Use this table to keep track of which ethernet address is on # which switch port (keys are MACs, values are ports). self.mac_to_port = {}

    def send_packet (self, buffer_id, raw_data, out_port, in_port): """ Sends a packet out of the specified switch port.

  • 47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    If buffer_id is a valid buffer on the switch, use that. Otherwise, send the raw data in raw_data. The "in_port" is the port number that packet arrived on. Use OFPP_NONE if you're generating this packet. """ msg = of.ofp_packet_out() msg.in_port = in_port if buffer_id != -1 and buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = buffer_id else: # No buffer ID from switch -- we got the raw data if raw_data is None: # No raw_data specified -- nothing to send! return msg.data = raw_data

    # Add an action to send to the specified port action = of.ofp_action_output(port = out_port) msg.actions.append(action)

    # Send message to switch self.connection.send(msg)

    def act_like_hub (self, packet, packet_in): """ Implement hub-like behavior -- send all packets to all ports besides the input port. """

    # We want to output to all ports -- we do that using the special # OFPP_FLOOD port as the output port. (We could have also used # OFPP_ALL.) #self.send_packet(packet_in.buffer_id, packet_in.data, # of.OFPP_FLOOD, packet_in.in_port)

    log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, packet_in.in_port, packet.dst, of.OFPP_FLOOD))

    msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) msg.buffer_id = packet_in.buffer_id self.connection.send(msg)

    # Note that if we didn't get a valid buffer_id, a slightly better # implementation would check that we got the full data before # sending it (len(packet_in.data) should be == packet_in.total_len)).

    def act_like_switch (self, packet, packet_in): """ Implement switch-like behavior. """

  • 97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    # Here's some psuedocode to start you off implementing a learning # switch. You'll need to rewrite it as real Python code.

    # Learn the port for the source MAC self.mac_to_port[str(packet.src)] = packet_in.in_port

    if str(packet.dst) in self.mac_to_port: # Send packet out the associated port #self.send_packet(packet_in.buffer_id, packet_in.data, # self.mac_to_port[str(packet.dst)], packet_in.in_port)

    # Once you have the above working, try pushing a flow entry # instead of resending the packet (comment out the above and # uncomment and complete the below.)

    #log.debug("Installing flow: from " + str(packet_in.in_port)) # Maybe the log statement should have source/destination/port? port = self.mac_to_port[str(packet.dst)] log.debug("installing flow for %s.%i -> %s.%i" % (packet.src, packet_in.in_port, packet.dst, port))

    """ # create new flow with match record set to match entire record # what is wrong with this? msg = of.ofp_flow_mod() msg.match = of.ofp_match.from_packet(packet) msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.buffer_id = packet_in.buffer_id self.connection.send(msg) """ """ # create new flow with match record set to only match destination # what is wrong with this? msg = of.ofp_flow_mod() msg.match.dl_dst = packet.dst msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.buffer_id = packet_in.buffer_id self.connection.send(msg) """

    # create new flow with match record set to only match destination # what is wrong with this? msg = of.ofp_flow_mod() msg.match.dl_dst = packet.dst msg.match.dl_src = packet.src msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = port)) msg.buffer_id = packet_in.buffer_id self.connection.send(msg)

    #msg = of.ofp_flow_mod() # ## Set fields to match received packet #msg.match = of.ofp_match.from_packet(packet)

  • 147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    169

    170

    171

    172

    173

    174

    175

    176

    177

    178

    179

    180

    181

    182

    183

    184

    185

    186

    187

    188

    189

    190

    191

    192

    193

    194

    195

    196

    # #< Set other fields of flow_mod (timeouts? buffer_id?) > # #< Add an output action, and send -- similar to send_packet() > #msg.in_port = packet_in.in_port #if packet_in.buffer_id != -1 and packet_in.buffer_id is not None: # We got a buffer ID from the switch; use that # msg.buffer_id = packet_in.buffer_id #else: # No buffer ID from switch -- we got the raw data # if packet_in.data is None: # No raw_data specified -- nothing to send! # return # msg.data = packet_in.data

    # Add an action to send to the specified port #action = of.ofp_action_output(port = self.mac_to_port[str(packet.dst)]) #msg.actions.append(action)

    else: # Flood the packet out everything but the input port # This part looks familiar, right? self.send_packet(packet_in.buffer_id, packet_in.data, of.OFPP_FLOOD, packet_in.in_port)

    def _handle_PortStatus (self, event): """ Returns on change of port status """ if event.added: log.debug("HW Address %s to port %d added (%d).", event.ofp.desc.hw_addr, event.port, event.dpid) elif event.deleted: log.debug("Port %d deleted (%d).", event.port, event.dpid)

    def _handle_PacketIn (self, event): """ Handles packet in messages from the switch. """

    packet = event.parsed # This is the parsed packet data. if not packet.parsed: log.warning("Ignoring incomplete packet") return

    packet_in = event.ofp # The actual ofp_packet_in message.

    # Comment out the following line and uncomment the one after # when starting the exercise. #self.act_like_hub(packet, packet_in) self.act_like_switch(packet, packet_in)

    def launch (): """ Starts the component """

  • 197

    198

    199

    200

    def start_switch (event): log.debug("Controlling %s" % (event.connection,)) Tutorial(event.connection) core.openflow.addListenerByName("ConnectionUp", start_switch)

    Of_switch_tutorial1.py

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    #!/usr/bin/python # Copyright 2012 James McCauley, William Yu # [email protected] # # This file is part of POX. # # POX is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # POX is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with POX. If not, see . # """ This is a demonstration file that has various switch implementations. The first example is a basic "all match" switch followed by a destination match, pair match then finally a more ideal pair match switch.

    Mininet: sudo mn --topo single,3 --mac --switch ovsk --controller remote Command Line: ./pox.py log.level --DEBUG samples.of_sw_tutorial """

    # These next two imports are common POX convention from pox.core import core import pox.openflow.libopenflow_01 as of

    # Even a simple usage of the logger is much nicer than print! log = core.getLogger()

    # This table maps (switch,MAC-addr) pairs to the port on 'switch' at # which we last saw a packet *from* 'MAC-addr'. # (In this case, we use a Connection object for the switch.) table = {}

    # Method for just sending a packet to any port (broadcast by default)

  • 36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    def send_packet (event, dst_port = of.OFPP_ALL): msg = of.ofp_packet_out(in_port=event.ofp.in_port) if event.ofp.buffer_id != -1 and event.ofp.buffer_id is not None: # We got a buffer ID from the switch; use that msg.buffer_id = event.ofp.buffer_id else: # No buffer ID from switch -- we got the raw data if event.ofp.data: # No raw_data specified -- nothing to send! return msg.data = event.ofp.data msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg)

    # DUMB HUB Implementation # This is an implementation of a broadcast hub but all packets go # to the controller since no flows are installed. def _handle_dumbhub_packetin (event): # Just send an instruction to the switch to send packet to all ports packet = event.parsed send_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    # PAIR-WISE MATCHING HUB Implementation # This is an implementation of a broadcast hub with flows installed. def _handle_pairhub_packetin (event): packet = event.parsed

    # Create flow that simply broadcasts any packet received msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    # LAZY HUB Implementation (How hubs typically are) # This is an implementation of a broadcast hub with flows installed. def _handle_lazyhub_packetin (event): packet = event.parsed

    # Create flow that simply broadcasts any packet received msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL)) event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" % ("ff:ff:ff:ff:ff:ff", event.ofp.in_port, "ff:ff:ff:ff:ff:ff", of.OFPP_ALL))

    # BAD SWITCH Implementation

  • 86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    # This is an obvious but problematic implementation of switch that # routes based on destination MAC addresses. def _handle_badswitch_packetin (event): packet = event.parsed

    # Learn the source and fill up routing table table[(event.connection,packet.src)] = event.port

    # install appropriate flow rule when learned msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.match.dl_dst = packet.src msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg)

    # determine if appropriate destination route is available dst_port = table.get((event.connection,packet.dst))

    log.debug("Installing %s.%i -> %s.%i" % ("ff:ff:ff:ff:ff:ff", event.ofp.in_port, packet.src, event.port))

    if dst_port is None: # We don't know where the destination is yet. So, we'll just # send the packet out all ports (except the one it came in on!) # and hope the destination is out there somewhere. :) # To send out all ports, we can use either of the special ports # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD, # but it's not clear if all switches support this. :( send_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL)) else: # This is the packet that just came in -- we want send the packet # if we know the destination. send_packet(event, dst_port)

    log.debug("Sending %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, dst_port))

    # PAIR-WISE MATCH SWITCH Implementation # This is an implementation of an pair match switch. This only matches # source and destination MAC addresses. Whenever a new source # destination MAC address is detected it then add a new flow # identifying the source destination pair. The routing table is updated # using the detected destination MAC address to the destination port. def _handle_pairswitch_packetin (event): packet = event.parsed

    # Learn the source and fill up routing table table[(event.connection,packet.src)] = event.port dst_port = table.get((event.connection,packet.dst))

    if dst_port is None: # We don't know where the destination is yet. So, we'll just # send the packet out all ports (except the one it came in on!) # and hope the destination is out there somewhere. :) # To send out all ports, we can use either of the special ports

  • 136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    169

    170

    171

    172

    173

    174

    175

    176

    177

    178

    179

    180

    181

    182

    183

    184

    185

    # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD, # but it's not clear if all switches support this. :( send_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL)) else: # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, dst_port))

    # SMARTER PAIR-WISE MATCH SWITCH Implementation # This is an implementation of an ideal pair switch. This optimizes the # previous example by adding both direction in one entry. def _handle_idealpairswitch_packetin (event): packet = event.parsed

    # Learn the source and fill up routing table table[(event.connection,packet.src)] = event.port dst_port = table.get((event.connection,packet.dst))

    if dst_port is None: # We don't know where the destination is yet. So, we'll just # send the packet out all ports (except the one it came in on!) # and hope the destination is out there somewhere. :) # To send out all ports, we can use either of the special ports # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD, # but it's not clear if all switches support this. :( send_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" % (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL)) else: # Since we know the switch ports for both the source and dest # MACs, we can install rules for both directions. msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.match.dl_dst = packet.src msg.match.dl_src = packet.dst msg.actions.append(of.ofp_action_output(port = event.port)) event.connection.send(msg)

    # This is the packet that just came in -- we want to # install the rule and also resend the packet. msg = of.ofp_flow_mod() msg.idle_timeout = 10 msg.hard_timeout = 30 msg.match.dl_src = packet.src msg.match.dl_dst = packet.dst

  • 186

    187

    188

    189

    190

    191

    192

    193

    194

    195

    196

    197

    198

    199

    200

    201

    202

    203

    Switch_tu

    msg.actions.append(of.ofp_action_output(port = dst_port)) event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i AND %s.%i -> %s.%i" % (packet.dst, dst_port, packet.src, event.ofp.in_port, packet.src, event.ofp.in_port, packet.dst, dst_port))

    # function that is invoked upon load to ensure that listeners are # registered appropriately. Uncomment the hub/switch you would like # to test. Only one at a time please. def launch (): #core.openflow.addListenerByName("PacketIn", _handle_dumbhub_packetin) #core.openflow.addListenerByName("PacketIn", _handle_pairhub_packetin) #core.openflow.addListenerByName("PacketIn", _handle_lazyhub_packetin) #core.openflow.addListenerByName("PacketIn", _handle_badswitch_packetin) #core.openflow.addListenerByName("PacketIn", _handle_pairswitch_packetin) core.openflow.addListenerByName("PacketIn", _handle_idealpairswitch_packetin)

    log.info("Switch Tutorial is running.")

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    #!/usr/bin/python

    # Copyright 2012 James McCauley, William Yu

    # [email protected]

    #

    # This file is part of POX.

    #

    # POX is free software: you can redistribute it and/or modify

    # it under the terms of the GNU General Public License as published by

    # the Free Software Foundation, either version 3 of the License, or

    # (at your option) any later version.

    #

    # POX is distributed in the hope that it will be useful,

    # but WITHOUT ANY WARRANTY; without even the implied warranty of

    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

    # GNU General Public License for more details.

  • 13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    #

    # You should have received a copy of the GNU General Public License

    # along with POX. If not, see .

    """

    This is a demonstration file that has various switch implementations.

    The first example is a basic "all match" switch followed by a

    destination match, pair match then finally a more ideal pair match

    switch.

    Mininet Command: sudo mn --topo single,3 --mac

    --switch ovsk

    --controller remote

    Command Line: ./pox.py py --completion

    log.level --DEBUG

    samples.of_sw_tutorial_oo

    THIS VERSION SUPPORT resend() functionality in the betta branch POX.

    Object-oriented version that allows user to switch switches via the

    command line interface.

    """

    # These next two imports are common POX convention

    from pox.core import core

    import pox.openflow.libopenflow_01 as of

    from pox.lib.util import dpidToStr

    # Even a simple usage of the logger is much nicer than print!

    log = core.getLogger()

    # Create the class to hold the switch tutorial implementations

    class SwitchTutorial (object):

    # This table maps (switch,MAC-addr) pairs to the port on 'switch' at

    # which we last saw a packet *from* 'MAC-addr'.

    # (In this case, we use a Connection object for the switch.)

    table = {}

    # Holds the object with the default switch

    handlerName = 'SW_IDEALPAIRSWITCH'

    # Holds the current active PacketIn listener object

    listeners = None

    # Constructor and sets default handler to Ideal Pair Switch

    def __init__(self, handlerName = 'SW_IDEALPAIRSWITCH'):

    log.debug("Initializing switch %s." % handlerName)

    # Method for just sending a packet to any port (broadcast by default)

    def send_packet(self, event, dst_port = of.OFPP_ALL):

    msg = of.ofp_packet_out(in_port=event.ofp.in_port)

    if event.ofp.buffer_id != -1 and event.ofp.buffer_id is not None:

    msg.buffer_id = event.ofp.buffer_id

    else:

    if event.ofp.data:

    return

    msg.data = event.ofp.data

    msg.actions.append(of.ofp_action_output(port = dst_port))

    event.connection.send(msg)

    # Optimal method for resending a packet

  • 63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    def resend_packet(self, event, dst_port = of.OFPP_ALL):

    msg = of.ofp_packet_out(data = event.ofp)

    msg.actions.append(of.ofp_action_output(port = dst_port))

    event.connection.send(msg)

    # DUMB HUB Implementation

    # This is an implementation of a broadcast hub but all packets go

    # to the controller since no flows are installed.

    def _handle_dumbhub_packetin(self, event):

    # Just send an instruction to the switch to send packet to all ports

    packet = event.parsed

    self.resend_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    # PAIR-WISE MATCHING HUB Implementation

    # This is an implementation of a broadcast hub with flows installed.

    def _handle_pairhub_packetin(self, event):

    packet = event.parsed

    # Create flow that simply broadcasts any packet received

    msg = of.ofp_flow_mod()

    msg.data = event.ofp

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.match.dl_src = packet.src

    msg.match.dl_dst = packet.dst

    msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))

    event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    # LAZY HUB Implementation (How hubs typically are)

    # This is an implementation of a broadcast hub with flows installed.

    def _handle_lazyhub_packetin(self, event):

    packet = event.parsed

    # Create flow that simply broadcasts any packet received

    msg = of.ofp_flow_mod()

    msg.data = event.ofp

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))

    event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" %

    ("ff:ff:ff:ff:ff:ff", event.ofp.in_port, "ff:ff:ff:ff:ff:ff",

    of.OFPP_ALL))

    # BAD SWITCH Implementation

    # This is an obvious but problematic implementation of switch that

    # routes based on destination MAC addresses.

    def _handle_badswitch_packetin(self, event):

    packet = event.parsed

    # Learn the source and fill up routing table

    self.table[(event.connection,packet.src)] = event.port

    # install appropriate flow rule when learned

  • 113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    msg = of.ofp_flow_mod()

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.match.dl_dst = packet.src

    msg.actions.append(of.ofp_action_output(port = event.port))

    event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" %

    ("ff:ff:ff:ff:ff:ff", event.ofp.in_port, packet.src, event.port))

    # determine if appropriate destination route is available

    dst_port = self.table.get((event.connection,packet.dst))

    if dst_port is None:

    # We don't know where the destination is yet. So, we'll just

    # send the packet out all ports (except the one it came in on!)

    # and hope the destination is out there somewhere. :)

    # To send out all ports, we can use either of the special ports

    # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD,

    # but it's not clear if all switches support this. :(

    self.resend_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    else:

    # This is the packet that just came in -- we want send the packet

    # if we know the destination.

    self.resend_packet(event, dst_port)

    log.debug("Sending %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, dst_port))

    # PAIR-WISE MATCH SWITCH Implementation

    # This is an implementation of an pair match switch. This only matches

    # source and destination MAC addresses. Whenever a new source

    # destination MAC address is detected it then add a new flow

    # identifying the source destination pair. The routing table is updated

    # using the detected destination MAC address to the destination port.

    def _handle_pairswitch_packetin (self, event):

    packet = event.parsed

    # Learn the source and fill up routing table

    self.table[(event.connection,packet.src)] = event.port

    dst_port = self.table.get((event.connection,packet.dst))

    if dst_port is None:

    # We don't know where the destination is yet. So, we'll just

    # send the packet out all ports (except the one it came in on!)

    # and hope the destination is out there somewhere. :)

    # To send out all ports, we can use either of the special ports

    # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD,

    # but it's not clear if all switches support this. :(

    self.resend_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    else:

    # This is the packet that just came in -- we want to

    # install the rule and also resend the packet.

    msg = of.ofp_flow_mod()

    msg.data = event.ofp

  • 163

    164

    165

    166

    167

    168

    169

    170

    171

    172

    173

    174

    175

    176

    177

    178

    179

    180

    181

    182

    183

    184

    185

    186

    187

    188

    189

    190

    191

    192

    193

    194

    195

    196

    197

    198

    199

    200

    201

    202

    203

    204

    205

    206

    207

    208

    209

    210

    211

    212

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.match.dl_src = packet.src

    msg.match.dl_dst = packet.dst

    msg.actions.append(of.ofp_action_output(port = dst_port))

    event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, dst_port))

    # SMARTER PAIR-WISE MATCH SWITCH Implementation

    # This is an implementation of an ideal pair switch. This optimizes the

    # previous example by adding both direction in one entry.

    def _handle_idealpairswitch_packetin(self, event):

    packet = event.parsed

    # Learn the source and fill up routing table

    self.table[(event.connection,packet.src)] = event.port

    dst_port = self.table.get((event.connection,packet.dst))

    if dst_port is None:

    # We don't know where the destination is yet. So, we'll just

    # send the packet out all ports (except the one it came in on!)

    # and hope the destination is out there somewhere. :)

    # To send out all ports, we can use either of the special ports

    # OFPP_FLOOD or OFPP_ALL. We'd like to just use OFPP_FLOOD,

    # but it's not clear if all switches support this. :(

    self.resend_packet(event, of.OFPP_ALL)

    log.debug("Broadcasting %s.%i -> %s.%i" %

    (packet.src, event.ofp.in_port, packet.dst, of.OFPP_ALL))

    else:

    # Since we know the switch ports for both the source and dest

    # MACs, we can install rules for both directions.

    msg = of.ofp_flow_mod()

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.match.dl_dst = packet.src

    msg.match.dl_src = packet.dst

    msg.actions.append(of.ofp_action_output(port = event.port))

    event.connection.send(msg)

    # This is the packet that just came in -- we want to

    # install the rule and also resend the packet.

    msg = of.ofp_flow_mod()

    msg.data = event.ofp

    msg.idle_timeout = 10

    msg.hard_timeout = 30

    msg.match.dl_src = packet.src

    msg.match.dl_dst = packet.dst

    msg.actions.append(of.ofp_action_output(port = dst_port))

    event.connection.send(msg)

    log.debug("Installing %s.%i -> %s.%i AND %s.%i -> %s.%i" %

    (packet.dst, dst_port, packet.src, event.ofp.in_port,

    packet.src, event.ofp.in_port, packet.dst, dst_port))

    # Define the proper handler

    def _set_handler_name (self, handlerName = 'SW_IDEALPAIRSWITCH'):

    self.handlerName = handlerName

  • 213

    214

    215

    216

    217

    218

    219

    220

    221

    222

    223

    224

    225

    226

    227

    228

    229

    230

    231

    232

    233

    234

    235

    236

    237

    238

    239

    240

    241

    242

    243

    244

    245

    246

    247

    248

    249

    250

    251

    252

    253

    254

    255

    256

    257

    258

    259

    260

    261

    262

    # Function to grab the appropriate handler

    def _get_handler (self, event):

    return self.swMap[self.handlerName](self, event)

    """ Here are functions that are meant to be called directly """

    # Here is a function to list all possible switches

    def list_available_listeners(self):

    for key in self.swMap.iterkeys():

    log.info("%s" % key)

    # Here is a function to displaying possible methods

    def help(self):

    log.info("Methods available: %s %s %s %s %s" %

    ('list_available_listeners()',

    'attach_packetin_listener(handlerName = \'SW_IDEALPAIRSWITCH\'',

    'detach_packetin_listener()',

    'clear_all_flows()',

    'clear_flows(connection)'))

    # Here is a function to attach the listener give the default handerName

    def attach_packetin_listener (self, handlerName = 'SW_IDEALPAIRSWITCH'):

    self._set_handler_name(handlerName)

    self.listeners = core.openflow.addListenerByName("PacketIn",

    self._get_handler)

    log.debug("Attach switch %s." % handlerName)

    # Here is a function to remove the listener

    def detach_packetin_listener (self):

    core.openflow.removeListener(self.listeners)

    log.debug("Detaching switch %s." % self.handlerName)

    # Function to clear all flows from a specified switch given

    # a connection object

    def clear_flows (self, connection):

    msg = of.ofp_flow_mod(match=of.ofp_match(),command=of.OFPFC_DELETE)

    connection.send(msg)

    log.debug("Clearing all flows from %s." %

    dpidToStr(connection.dpid))

    # Function to clear all flows from all switches

    def clear_all_flows (self):

    msg = of.ofp_flow_mod(match=of.ofp_match(),command=of.OFPFC_DELETE)

    for connection in core.openflow._connections.values():

    connection.send(msg)

    log.debug("Clearing all flows from %s." %

    dpidToStr(connection.dpid))

    # Define various switch handlers

    swMap = {

    'SW_DUMBHUB' : _handle_dumbhub_packetin,

    'SW_PAIRHUB' : _handle_pairhub_packetin,

    'SW_LAZYHUB' : _handle_lazyhub_packetin,

    'SW_BADSWITCH' : _handle_badswitch_packetin,

    'SW_PAIRSWITCH' : _handle_pairswitch_packetin,

    'SW_IDEALPAIRSWITCH' : _handle_idealpairswitch_packetin,

    }

    # function that is invoked upon load to ensure that listeners are

    # registered appropriately. Uncomment the hub/switch you would like

    # to test. Only one at a time please.

  • 263

    264

    265

    266

    267

    268

    269

    270

    271

    def launch ():

    # create new tutorial class object using the IDEAL PAIR SWITCH as default

    MySwitch = SwitchTutorial('SW_IDEALPAIRSWITCH')

    # add this class into core.Interactive.variables to ensure we can access

    # it in the CLI.

    core.Interactive.variables['MySwitch'] = MySwitch

    # attach the corresponding default listener

    MySwitch.attach_packetin_listener()

    Refference:

    http://nullege.com/codes/show/src@p@o@poxstuff-HEAD@of_sw_tutorial_oo.py