Introduction
Build a software-defined network using OpenFlow protocol, Mininet emulator, and ONOS controller with custom packet routing policies. This comprehensive guide covers everything from design through implementation, testing, and deployment.
Build a software-defined network using OpenFlow protocol, Mininet emulator, and ONOS controller with custom packet routing policies.
Build a software-defined network using OpenFlow protocol, Mininet emulator, and ONOS controller with custom packet routing policies. This comprehensive guide covers everything from design through implementation, testing, and deployment.
Traditional networking: control plane (routing decisions) and data plane (packet forwarding) embedded in each device — distributed intelligence. SDN: decouple control from forwarding. Centralized Controller programs all switches via OpenFlow protocol. Data plane: 'dumb' switches forward packets based on flow tables programmed by controller. Advantages: global network view enables better optimization, programmatic control (deploy new routing policies via code instantly), hardware independence (commodity switches with OpenFlow). Disadvantages: controller is single point of failure (redundancy needed), higher latency for first packet of new flow.
10 components required for this project.
| # | Component | Purpose | Qty |
|---|---|---|---|
| 1 | Mininet network emulator | Virtual SDN network simulation | x1 |
| 2 | ONOS SDN Controller | Centralized network controller | x1 |
| 3 | OpenFlow 1.3 switches (virtual) | Programmatic packet forwarding | x1 |
| 4 | Python (Ryu framework) | Custom SDN application development | x1 |
| 5 | Wireshark with OpenFlow dissector | OpenFlow message analysis | x1 |
| 6 | Ubuntu 20.04 (Mininet compatible) | Host OS | x1 |
| 7 | iperf3 | Network performance measurement | x1 |
| 8 | ONOS REST API | Network policy programming | x1 |
| 9 | OpenVSwitch (OVS) | OpenFlow-capable virtual switch | x1 |
| 10 | GNS3 (alternative) | Network simulation with real router images | x1 |
Follow these 3 steps carefully.
Traditional networking: control plane (routing decisions) and data plane (packet forwarding) embedded in each device — distributed intelligence. SDN: decouple control from forwarding. Centralized Controller programs all switches via OpenFlow protocol. Data plane: 'dumb' switches forward packets based on flow tables programmed by controller. Advantages: global network view enables better optimization, programmatic control (deploy new routing policies via code instantly), hardware independence (commodity switches with OpenFlow). Disadvantages: controller is single point of failure (redundancy needed), higher latency for first packet of new flow.
Mininet creates a virtual network with real kernel networking stack. mn --topo tree,depth=3,fanout=3 creates a tree topology with 27 hosts and 13 switches. Custom topology in Python: class MyTopo(Topo): define hosts and switches, add links with bandwidth/delay parameters. Connect to Ryu controller: mn --controller=remote,ip=127.0.0.1,port=6653. Test connectivity: mininet> pingall. Measure throughput: mininet> iperf h1 h27. Mininet runs all hosts/switches on one Linux machine using network namespaces.
Ryu is a Python-based SDN framework. OpenFlow application inherits from RyuApp. Event handlers: @set_ev_cls(ofp_event.EventOFPSwitchFeatures): called when switch connects, install initial flow rules. @set_ev_cls(ofp_event.EventOFPPacketIn): called when switch receives packet not matching any flow table entry. Handler: learn source MAC, look up destination MAC, if known install flow rule (avoiding future PacketIn events for this flow), otherwise flood.
Core code for sdn_controller.py:
from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER, set_ev_cls from ryu.ofproto import ofproto_v1_3 from ryu.lib.packet import packet, ethernet class L2Switch(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.mac_to_port = {} # {dpid: {mac: port}} @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_connected(self, ev): """Install table-miss flow: send all unknown packets to controller""" dp = ev.msg.datapath ofp = dp.ofproto; parser = dp.ofproto_parser # Match: all packets. Action: send to controller match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofp.OFPP_CONTROLLER)] inst = [parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] dp.send_msg(parser.OFPFlowMod(dp, priority=0, match=match, instructions=inst)) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in(self, ev): msg = ev.msg; dp = msg.datapath ofp = dp.ofproto; parser = dp.ofproto_parser pkt = packet.Packet(msg.data) eth = pkt.get_protocol(ethernet.ethernet) dpid = dp.id; in_port = msg.match['in_port'] # Learn source MAC self.mac_to_port.setdefault(dpid, {}) self.mac_to_port[dpid][eth.src] = in_port # Forward or flood out_port = self.mac_to_port[dpid].get(eth.dst, ofp.OFPP_FLOOD) # Install flow rule if destination known (avoid future PacketIn) if out_port != ofp.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=eth.dst) actions = [parser.OFPActionOutput(out_port)] inst = [parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] dp.send_msg(parser.OFPFlowMod(dp, priority=1, match=match, instructions=inst)) # Forward this packet dp.send_msg(parser.OFPPacketOut(dp, msg.buffer_id, in_port, [parser.OFPActionOutput(out_port)], msg.data))
Test Software-Defined Networking with OpenFlow by verifying each subsystem individually before full integration.
Verify power voltages, check ground connections, use serial monitor for debug.
An interactive simulator will be available here — simulate circuits and run code in-browser without hardware.