Create basic_l2_switch.py

This is basic(extremely basic switch controller). The controller maintains a macaddr table which is updated by src based learning. whenever a unknown destination packet is received by the switch, it forwards the same to the controller. The controller checks for the dest mac in addr table and frames specific flow table entries which are later used to modify the flow tables on the switch

test output:
running pox controller:
mininet@mininet-vm:~/pox$ pox.py log.level --DEBUG l2_switching
POX 0.2.0 (carp) / Copyright 2011-2013 James McCauley, et al.
in L2switch class
in launch..
DEBUG:core:POX 0.2.0 (carp) going up...
DEBUG:core:Running on CPython (2.7.3/Sep 26 2012 21:51:14)
DEBUG:core:Platform is Linux-3.5.0-17-generic-x86_64-with-Ubuntu-12.10-quantal
INFO:core:POX 0.2.0 (carp) is up.
DEBUG:openflow.of_01:Listening on 0.0.0.0:6633
INFO:openflow.of_01:[None 1] closed
INFO:openflow.of_01:[00-00-00-00-00-01 2] connected
connected to switch
<class 'pox.lib.packet.ethernet.ethernet'>
<class 'pox.lib.packet.ethernet.ethernet'>


simulating a topology:
mininet@mininet-vm:~$ sudo mn --topo single,3 --mac --switch ovsk --controller remote

checking for flow entries using dpctl

mininet> pingall
*** Ping: testing ping reachability
h1 -> h2 h3 
h2 -> h1 h3 
h3 -> h1 h2 
*** Results: 0% dropped (0/6 lost)
mininet> dpctl dump-flows
*** s1 ------------------------------------------------------------------------
in_port(3),eth(src=00:00:00:00:00:03,dst=00:00:00:00:00:01),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions:2,0,1
in_port(2),eth(src=00:00:00:00:00:02,dst=00:00:00:00:00:01),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions:3,0,1
in_port(3),eth(src=00:00:00:00:00:03,dst=00:00:00:00:00:01),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:0, bytes:0, used:never, actions:2,0,1
in_port(3),eth(src=00:00:00:00:00:03,dst=00:00:00:00:00:02),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:0, bytes:0, used:never, actions:2,0,1
in_port(2),eth(src=00:00:00:00:00:02,dst=00:00:00:00:00:03),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions:3,0,1
in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:0, bytes:0, used:never, actions:3,2,0
in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions:3,2,0
in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:03),eth_type(0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:0, bytes:0, used:never, actions:3,2,0
in_port(2),eth(src=00:00:00:00:00:02,dst=00:00:00:00:00:03),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:0, bytes:0, used:never, actions:3,0,1
in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:03),eth_type(0x0800),ipv4(src=10.0.0.1,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions:3,2,0
in_port(2),eth(src=00:00:00:00:00:02,dst=00:00:00:00:00:01),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:0, bytes:0, used:never, actions:3,0,1
in_port(3),eth(src=00:00:00:00:00:03,dst=00:00:00:00:00:02),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:0, bytes:0, used:never, actions:2,0,1
mininet>