# Programmable Network Switches
## Lab1 - Using the OpenFlow Protocol with Ryu Controller to Implement the Learning Switch Protocol
### Overview
In this lab, you will utilize the OpenFlow protocol and the Ryu controller to implement the learning switch protocol.
### Environment
Right click on the link and click on `Save link as`.
* VM Image (tested on VirtualBox): http://140.113.216.90:8000/openflow_vm.ova
* Sample Code: http://140.113.216.90:8000/openflow.zip
### Setup
1. Import the .ova file into VirtualBox and start the VM.
* Username: sdn
* Password: nslab
2. Download the sample code archive.
```shell
wget http://140.113.216.90:8000/openflow.zip
```
3. Unzip the sample code into the VM. Place it in any location you prefer.
The folder contains the following files:
* `controller.py`
* `dataplane.py`
* `disable_ipv6.sh`
* `Makefile`
* `set_arp.sh`
### Topology
In this lab, you will construct a hierarchical tree topology as illustrated below:

The IP and MAC addresses of each host are listed as follows:
* h1: 10.0.0.1, 08:00:00:00:01:11
* h2: 10.0.0.2, 08:00:00:00:02:22
* h3: 10.0.0.3, 08:00:00:00:03:33
* h4: 10.0.0.4, 08:00:00:00:04:44
### Test
After setting up your VM, open two consoles and navigate to the location where you placed the sample code. Run the following commands:
```shell
# First shell
make controller
```
```shell
# Second shell
make test
```
Once you see the hint `*** Starting CLI: mininet>` in the second shell, you can run:
```shell
mininet> pingall
```
This command tests ping reachability between all hosts, equivalent to individual pings between hosts (e.g., h1 ping h2, h1 ping h3, ...).
You will see the result in the second shell:
```
*** Starting CLI:
mininet> pingall
*** Ping: testing ping reachability
*** Warning: No packets sent
```
You can use `ctrl+c` to terminate the ping, and `exit` to stop the mininet.
Additionally, some messages should appear in the first console (controller):
```
loading app ./controller.py
loading app ryu.controller.ofp_handler
instantiating app ./controller.py of LearningSwitch
instantiating app ryu.controller.ofp_handler of OFPHandler
```
This is because there are currently no hosts and switches in the topology, and thus the controller is not performing any actions. Later on, you need to build the topology as depicted in the provided picture.
Your task is to construct the topology and enable the switch to learn the destination MAC address for each port and forward packets accordingly.
The overall logic for the learning switch implementation involves the following steps:
1. **When receiving a packet:**
- Save the (source MAC address -> incoming port) mapping.
2. **If the destination MAC address is in the mapping:**
- Retrieve the corresponding port from the mapping.
- Install a forwarding rule based on both of the destination MAC address and the source MAC address.
3. **If the destination MAC address is not in the mapping:**
- Perform flooding to ensure that the packet is forwarded out of all ports, except the incoming port.
4. **Forward the packet:**
- Use the obtained port (either from the mapping or through flooding) to forward the packet out.
### Implementation Steps
* In `dataplane.py`, follow the TODO section to create the correct topology.
* In `controller.py`, follow the TODO section to ensure that the controller can remember the port and install rules if needed.
### Tips
* **Important!! The match field should use both of the source and destination MAC addresses; otherwise, the experiment will fail.**
* Remember to disable IPv6 on each host and switch. Also, set ARP in each host using the provided scripts (`disable_ipv6.sh` and `set_arp.sh`).
* Assign IP and MAC addresses to each host as specified.
* Use `self.add_flow` to install flow. The `actions` parameter is created by
```python
actions = [ofp_parser.OFPActionOutput(out_port)]
```
* If you encounter issues with Mininet not opening, execute the command `make clean`.
### Submission
* `{student_id}_lab1.zip`
* `controller.py`
* `dataplane.py`