# SOFTWARE DEFINE NETWORK
Software Defined Networking (SDN) adalah sebuah pendekatan arsitektur jaringan yang memisahkan fungsi kontrol jaringan (control plane) dari fungsi pengiriman data (data plane). Fungsi kontrol kemudian dikelola secara terpusat melalui perangkat lunak, memungkinkan operator untuk mengontrol dan mengelola jaringan secara lebih fleksibel dan efisien.
#### konsep Penting Terkait SDN:
- Control Plane:
Fungsi kontrol jaringan yang bertanggung jawab untuk mengambil keputusan tentang bagaimana data dikirimkan dalam jaringan.
- Data Plane:
Fungsi pengiriman data yang bertanggung jawab untuk mengirimkan data sesuai dengan keputusan yang dibuat oleh control plane.
- Controller:
Perangkat lunak atau perangkat keras yang mengontrol control plane dan menerima instruksi dari aplikasi untuk mengelola lalu lintas jaringan.
- API (Application Programming Interface):
Antarmuka yang digunakan oleh aplikasi untuk berkomunikasi dengan controller dan mengelola jaringan.
#### Manfaat dari SDN:
- Fleksibilitas dan Agilitas
- Otomatisasi
- Virtualisasi
- Scalability
- Penghematan Biaya
## Bab 1 : Set Up Tools
### 1. Mininet
Mininet adalah sebuah aplikasi emulasi jarngan berbasis light-weight Linux virtualiation yang memungkinkan kita mmebuat jaringan virtual lengkap dengan switch, router, dan host yang realistis dan berinteraksi dengan real kernel dan program lainnya
gunanya mininet ini adalah untuk meniru atau mensimulasikan jaringan komputer secara virtual, baik jaringan sederhana maupun jaringan kompleks. Ini memungkinkan pengguna untuk membuat, menguji, dan bereksperimen dengan berbagai topologi jaringan, protokol, dan aplikasi tanpa perlu perangkat keras fisik.
:::info
:::spoiler **Mininet**
Langkah - langkah penginstalan
1. Install git
:::success
```
sudo apt update
```
sudo apt ini untuk memperbarui daftar paket yang tersedia di sistem basis VM.
output:

```
sudo apt install git -y
```
untuk menginstall git secara otomatis.
output:

2. Cloning mininet
:::success
```
git clone https://github.com/mininet/mininet.git
```
untuk mengunduh clone seluruh isi repository mininet dari github ke komputer.
output:

3. Install mininet
:::success
```
mininet/util/install.sh -a
```
untuk menginstall semua komponen yang ada di mininet secara lengkap.
Output:

4. Mem-verifikasi mininet
:::success
```
sudo mn
```
untuk menjalankan mininetnya.
output:

:::
## 2. Minikube
Mininet adalah sebuah aplikasi emulasi jaringan berbasis virtualisasi ringan di Linux yang memungkinkan pengguna untuk membuat jaringan virtual yang lengkap dengan host, switch, router, dan lainnya, serta berinteraksi dengan kernel dan program lain. Ini digunakan untuk mensimulasikan kinerja jaringan yang kompleks, seperti Jaringan Terdefinisi Perangkat Lunak (SDN), dengan menggunakan perangkat lunak yang ada pada sistem operasi host.
#### Emulator Jaringan:
Mininet memungkinkan pengguna untuk membuat model jaringan di perangkat lunak, bukan dengan hardware fisik.
#### Virtualisasi Ringan:
Mininet menggunakan teknologi virtualisasi ringan, yang berarti tidak memerlukan mesin virtual penuh yang memakan banyak sumber daya seperti virtualisasi tradisional.
#### Node Logis:
Mininet menciptakan node logis (host, switch, router) yang dapat saling terhubung untuk membentuk topologi jaringan.
#### Interaksi dengan Real Kernel:
Mininet dapat berinteraksi dengan kernel dan program asli di sistem operasi host, sehingga simulasi lebih realistis.
#### SDN dan OpenFlow:
Mininet banyak digunakan dalam riset dan pengembangan Jaringan Terdefinisi Perangkat Lunak (SDN) karena mendukung protokol OpenFlow yang merupakan dasar dari SDN.
#### Simulasi Kinerja:
Mininet dapat digunakan untuk mensimulasikan kinerja jaringan, menguji berbagai topologi, dan mengevaluasi aplikasi jaringan.
#### Open Source:
Mininet adalah perangkat lunak sumber terbuka, sehingga dapat diakses dan digunakan oleh siapa saja.
:::success
:::spoiler **Minikube**
```
sudo apt update && sudo apt upgrade -y
```
untuk memperbarui repository dan mengupdate paket perangkat lunak.
- y nya untuk tidak menanyakan kembali.



> `Docker untuk depedensi untuk deployment.`
untuk mengelola dependensi dan mempermudah deployment aplikasi.

> Containerd sebagai komponen untuk menjalankan dan mengelola container dalam suatu sistem. Containerd ini yang digunakan untuk menjalankan Kubernetes, cenderung lebih cepat dibandingkan Docker dan sebagai standar untuk Kubernetes.

:::
## 3. Ryu Controller
Ryu Controller adalah Pengendali jaringan berbasis perangkat lunak (SDN) terbuka yang dirancang untuk meningkatkan kelincahan jaringan dengan mempermudah pengelolaan dan penyesuaian penanganan lalu lintas.
#### Open Source:
Ryu adalah perangkat lunak open source yang dikembangkan oleh NTT, artinya kode sumbernya terbuka dan dapat diakses serta dimodifikasi oleh siapa saja.
#### Fungsi:
Ryu berfungsi sebagai controller untuk mengelola dan mengontrol jaringan, termasuk mengatur bagaimana lalu lintas data diproses dan dialirkan melalui jaringan.
#### Protokol yang Didukung:
Ryu mendukung beberapa protokol SDN, termasuk OpenFlow, Netconf, dan OF-config.
#### Keunggulan:
Ryu memiliki komponen yang berguna untuk aplikasi SDN dan juga komponen yang dapat di-upgrade, sehingga dapat digunakan dalam berbagai lingkungan jaringan.
:::info
:::spoiler **Ryu Controller**
```Markdown=
#!/bin/bash
echo "[INFO] Creating ConfigMap, Deployment, and Service for Ryu..."
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: ryu-app
data:
startup.sh: |
#!/bin/sh
echo "[INFO] Installing dependencies..."
apt-get update && apt-get install -y gcc libffi-dev libssl-dev python3-venv
echo "[INFO] Creating Python virtual environment..."
python -m venv /tmp/venv
echo "[INFO] Installing Python packages..."
/tmp/venv/bin/pip install --upgrade pip==20.2.4 setuptools==57.5.0
/tmp/venv/bin/pip install ryu eventlet==0.30.2
echo "[INFO] Starting Ryu controller with built-in simple_switch_13..."
exec /tmp/venv/bin/ryu-manager --observe-links --ofp-tcp-listen-port 6653 ryu.app.simple_switch_13
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ryu-controller
spec:
replicas: 1
selector:
matchLabels:
app: ryu
template:
metadata:
labels:
app: ryu
spec:
containers:
- name: ryu
image: python:3.9-slim
command: ["/bin/sh"]
args: ["-c", "/bin/sh /app/startup.sh"]
volumeMounts:
- name: ryu-app-volume
mountPath: /app
readOnly: true
ports:
- containerPort: 6653
- containerPort: 6633
volumes:
- name: ryu-app-volume
configMap:
name: ryu-app
---
apiVersion: v1
kind: Service
metadata:
name: ryu-service
spec:
selector:
app: ryu
type: NodePort
ports:
- name: of-port
protocol: TCP
port: 6653
targetPort: 6653
nodePort: 30001
- name: legacy-port
protocol: TCP
port: 6633
targetPort: 6633
nodePort: 30002
EOF
echo "[DONE] Deployment complete. You can check the pod logs with:"
echo "kubectl logs -f deploy/ryu-controller"
```
:::success
:::spoiler **Penjelasan**
1. Pembungkus Skrip
```markdown=
#!/bin/bash
echo "[INFO] Creating ConfigMap, Deployment, and Service for Ryu..."
cat <<EOF | kubectl apply -f -
```
- `#!/bin/bash`, menandakan bahwa skrip ini dijalankan menggunakan Bash.
- `echo`, Menampilkan informasi status ke terminal.
- `cat <<EOF | kubectl apply -f -`, meuliskan dokumen YAML ke kubectl apply, artinya Kubernetes langsung membuat resource sesuai definisi YAML dibawahnya.
2. Configmap : Menyimpan File `startup.sh`
```markdown=
apiVersion: v1
kind: ConfigMap
metadata:
name: ryu-app
data:
startup.sh: |
#!/bin/sh
echo "[INFO] Installing dependencies..."
apt-get update && apt-get install -y gcc libffi-dev libssl-dev python3-venv
echo "[INFO] Creating Python virtual environment..."
python -m venv /tmp/venv
echo "[INFO] Installing Python packages..."
/tmp/venv/bin/pip install --upgrade pip==20.2.4 setuptools==57.5.0
/tmp/venv/bin/pip install ryu eventlet==0.30.2
echo "[INFO] Starting Ryu controller with built-in simple_switch_13..."
exec /tmp/venv/bin/ryu-manager --observe-links --ofp-tcp-listen-port 6653 ryu.app.simple_switch_13
```
- `Config ` digunakan untuk menyimpan file konfigurasi/script `startup.sh` yang akan dijalankan dalan container.
- Menginstall beberapa dependansi ang diperlukan untuk Ryu (via `apt`)
- Membuat virtual environment python agar lingkungan tetap bersih.
- Menginstall ryu dan eventlet (Eventlet digunakan untuk aplikasi jaringan seperti controller yang harus melayani banyak koneksi.).
- Menjalankan Ryu Controller menggunakan script `ryu.app.simple_switch_13` di port 6653.
3. Deployment : Menjalankan Container
```markdown=
apiVersion: apps/v1
kind: Deployment
metadata:
name: ryu-controller
spec:
replicas: 1
selector:
matchLabels:
app: ryu
template:
metadata:
labels:
app: ryu
spec:
containers:
- name: ryu
image: python:3.9-slim
command: ["/bin/sh"]
args: ["-c", "/bin/sh /app/startup.sh"]
volumeMounts:
- name: ryu-app-volume
mountPath: /app
readOnly: true
ports:
- containerPort: 6653
- containerPort: 6633
volumes:
- name: ryu-app-volume
configMap:
name: ryu-app
```
- Deployment adalah cara kubernetes menjalankan dan menjadi agar Pod tetap berjalan.
- Menggunakan image dasar python:3.9-slim (mengapa pakai slim karena **python slim** karena ukurannya ringan dibandingkan **python:3.9**, ukurannya sekitar 40-50% ukurannya).
- Script `startup.sh` dijalankan saat container mulai.
4. Service
```markdown=
apiVersion: v1
kind: Service
metadata:
name: ryu-service
spec:
selector:
app: ryu
type: NodePort
ports:
- name: of-port
protocol: TCP
port: 6653
targetPort: 6653
nodePort: 30001
- name: legacy-port
protocol: TCP
port: 6633
targetPort: 6633
nodePort: 30002
```
- Service bertugas menghubungkan lalu lintas dari luar ke Pod.
- `type: Nodeport` membuka port i semua node worker.
- Port yang dibuka
- 6653 --> 30001, port utama OpenFlow.
- 6633 --> 30002, untuk OpenFlow Legacy (Openflow merupakan versi awal-awal dari protokol OpenFlow, terutama Openflow 1.0, yang menggunakan port TCP 6633.).
3. Output
```markdown=
echo "[DONE] Deployment complete. You can check the pod logs with:"
echo "kubectl logs -f deploy/ryu-controller"
```
Memberi tahu user bahwa proses selesai.
:::
## 4. Wireshark
Wireshark adalah perangkat lunak analisis jaringan yang berfungsi untuk merekam dan menganalisis lalu lintas jaringan dalam waktu nyata. Dengan kata lain, Wireshark adalah alat untuk menangkap dan mengamati paket data yang berjalan di jaringan internet atau jaringan lokal. Wireshark digunakan untuk berbagai keperluan seperti pemecahan masalah jaringan, analisis protokol, dan pengujian keamanan.
Lebih detailnya, Wireshark memiliki kemampuan:
#### Menangkap paket data:
Wireshark dapat menangkap semua jenis paket data yang berjalan di jaringan, termasuk paket data dari berbagai protokol seperti HTTP, TCP, UDP, dan banyak lagi.
#### Menganalisis paket data:
Setelah paket data ditangkap, Wireshark memungkinkan pengguna untuk menganalisisnya dengan detail, termasuk melihat header paket, isi paket, dan informasi lainnya.
#### Menampilkan informasi:
Wireshark menampilkan informasi tentang paket data secara visual dan mudah dibaca, termasuk tabel, grafik, dan diagram yang membantu pengguna memahami lalu lintas jaringan.
#### Memecahkan masalah:
Wireshark dapat digunakan untuk memecahkan masalah jaringan seperti masalah koneksi, masalah kinerja, atau masalah keamanan.
#### Menganalisis protokol:
Wireshark dapat digunakan untuk menganalisis protokol jaringan, termasuk protokol yang digunakan untuk komunikasi di jaringan.
#### Pengujian keamanan:
Wireshark dapat digunakan untuk melakukan pengujian keamanan jaringan dan mendeteksi ancaman keamanan.
:::info
:::spoiler **Wireshark**
1. Update dan upgrade `apt`
```markdown=
sudo apt update && sudo apt upgrade
```
untuk mengunduh informasi paket baru dan yang upgrade untuk memperbarui sistem
2. Install wireshark
```markdown=
sudo apt install wireshark -y
```
untuk menginstall wireshark
3. Verifikasi wireshark
```markdown=
wireshark
```
:::warning
Hanya menuliskan **wireshark** pada terminal.
:::
# Bab 2 - Skenario
SDN mempunyai banyak skenario atau use-case yang dapat diimplementasikan. Berikut beberapa kategori dan skenario SDN:
### 1. Traffic Engineering & Path Computation
Menentukan jalur optimal untuk tiap aliran berdasarkan metrik tertentu (delay, bandwidth, utilisasi). Beberapa skenario:
- **Load Balancing**
- **QoS (Quality of Service)**
- MPLS-style path setup (constraint-based routing)
- Dynamic path rerouting saat link gagal (fast failover)
- Segment Routing
### 2. Network Virtualization & Slicing
Membagi infrastruktur fisik menjadi jaringan virtual terisolasi (slice), seperti VLAN tapi lebih fleksibel. Beberapa skenario:
- Membuat beberapa slice jaringan logis di atas infrastruktur fisik yang sama (multi-tenant)
- Virtual Network Functions (VNF) chaining untuk NFV (firewall → DPI → NAT)
### 3. Keamanan & Kontrol Akses
Menggunakan control pusat untuk mengelola kebijakan keamanan dan ACL (Access Control List) pada tiap aliran. Beberapa skenario:
- Firewall terpusat (flow-based ACL)
- Intrusion Detection System (IDS) / Intrusion Prevention System (IPS)
- DDoS mitigation dengan deteksi anomali dan blokir otomatis
### 4. Monitoring, Telemetri & Analytics
Mengumpulkan dan menganalisis data trafik dan perform jaringan secara real-time. Beberapa skenario:
- **Sniffing**
- Flow statistics collection (sFlow, NetFlow over OpenFlow)
- Network traffic visualization dashboard
- Telemetri real-time untuk prediksi atau deteksi anomaly
### 5. Service Chaining & Orchestration
Mengurutkan dan orkestrasi VNF (Virtual Network Functions) supaya paket melewati suatu rangkaian layanan. Beberapa skenario:
- Mengurutkan service (misal: enkripsi → kompresi → inspeksi) secara dinamis
- Integrasi dengan orchestrator (OpenStack Neutron, Kubernetes CNI)
### 6. Mobility & Wireless SDN
Menerapkan prinsip SDN pada jaringan wireless agar handover, channel assignment, dan resourece allocation terpusat. Beberapa skenario:
- Seamless handover management (Wi-Fi atau seluler)
- Dynamic channel assignment di wireless mesh
### 7. Energy-Aware Networking
Menghemat energi dengan mematikan atau menurunkan daya perangkat/switch/link yang idle. Beberapa skenario:
- Mematikan link/switch yang idle untuk menghemat energi
- QoS-aware wake-up berdasarkan beban trafik
### 8. Bandwidth on-Demand & Cloud Interconnect
Menyediakan dan menyesuaikan kapasitas jaringan antar DC atau ke cloud provider dengan API (Application Programming Interface). Beberapa skenario:
- Autoscaling bandwidth antar data center sesuai kebutuhan aplikasi
- API publik untuk request/teardown koneksi
### 9. Edge Computing & IoT
Mengatur trafik dan resource di edge node untuk aplikasi latency-sensitive dan IoT. Beberapa skenario:
- Routing dinamis untuk IoT gateway based on latency
- Pengaturan prioritas trafik sensor vs. actuator
### 10. Programmable WAN/LAN
Menggabungkan berbagai koneksi melalui program dan otomasi jaringan enterprise. Beberapa skenario:
- SD-WAN untuk menggabungkan beberapa koneksi (MPLS, broadband, LTE)
- Automasi deployment VLAN/VXLAN
Dari sekian banyak skenario SDN, kami hanya mengimplementasikan beberapa skenario dasar SDN, yaitu **Load Balancing**, **Sniffing**, dan **QoS**.
</br>
## Skenario 1: Load Balancing
Load balancing merupakan suatu jaringan komputer yang menggunakan metode untuk mendistribusikan beban kerjaan pada dua atau lebih dari suatu koneksi jaringan secara seimbang agar pekerjaan dapat berjalan optimal.
Load Balancing dapat menggunakan dengan beberapa algoritma, antara lain:
- Agen Based
- Flow Based
- Round Robin
### Agen Based
Load Balancing dengan algoritma least connection menggunakan agen yang berfungsi mendistribusikan jumlah koneksi pada server.
### Flow Based
Load Balancing dengan algoritma least connection menggunakan flow yang tersimpan dijadikan sebagai parameter jumlah koneksi pada server.
### Round Robin
Load Balancing dengan algoritma round robin sebagai metode pemilihan server pada load balancing.
#### Multipath Load Balancing
Sebuah metode pengaturan traffic dengan mendistribusi dan membagi muatan secara adil di antara banyak rute dari sumber ke tujuan.
---

1. Setup Mininet dan Ryu dengan topologi di atas dengan ketentuan:
- Dalam skenario khusus ini, jika Host1 ingin mengirimkan paket ke Host2, maka akan dilakukan load balancing, **70%** dari traffic S1 akan diarahkan ke port 1 dan sisa **30%** akan diarahkan ke port 2. Begitu juga sebaliknya ketika Host2 ke Host1.
- Lalu jika Host3 ingin mengirimkan paket ke Host4, maka akan dilakukan load balancing juga, **50%** dari traffic Switch3 akan diarahkan ke port 1 dan sisa **50%** akan diarahkan ke port 2. Begi juga sebaliknya ketika Host2 ke Host1.
2. Pembuktian
- Lakukan test iperf **Host1** ke **Host2** untuk melakukan dump paket.
- Lakukan test iperf **Host3** ke **Host4** untuk melakukan dump paket.
- Lakukan cek stats menggunakan **ovs-ofctl**.
:::warning
:::spoiler **Skenario 1 Scripts**
- **Topologi**
:::info
```
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import RemoteController
from mininet.cli import CLI
from mininet.link import TCLink
from mininet.log import setLogLevel
class LoadBalancingTopo(Topo):
def build(self):
# Tambah hosts
h1 = self.addHost('h1', ip='10.0.0.1/24')
h2 = self.addHost('h2', ip='10.0.0.2/24')
h3 = self.addHost('h3', ip='10.0.0.3/24')
h4 = self.addHost('h4', ip='10.0.0.4/24')
# Tambah switches
s1 = self.addSwitch('s1') # Switch untuk H1
s2 = self.addSwitch('s2') # Switch untuk H4
s3 = self.addSwitch('s3') # Switch untuk H3
s4 = self.addSwitch('s4') # Switch untuk H2
# Hubungkan host ke switch sesuai dengan permintaan
self.addLink(h1, s1)
self.addLink(h2, s4)
self.addLink(h3, s3)
self.addLink(h4, s2)
# Inter-switch connections (middle mesh)
self.addLink(s1, s2) # s1 ke s2
self.addLink(s1, s3) # s1 ke s3
self.addLink(s2, s4) # s2 ke s4
self.addLink(s3, s4) # s3 ke s4
def run():
topo = LoadBalancingTopo()
net = Mininet(topo=topo,
controller=lambda name: RemoteController(name, ip='10.0.0.4', port=6653),
link=TCLink)
net.start()
print("Testing connectivity...")
net.pingAll()
CLI(net)
net.stop()
if _name_ == '_main_':
setLogLevel('info')
run()
```
Host-Switch
→ H1 (Host 1) IP Address 10.0.0.1 yang terhubung dengan S1 (Switch 1).</br>
→ H2 (Host 2) IP Address 10.0.0.2 yang terhubung dengan S4 (Switch 4).</br>
→ H3 (Host 3) IP Address 10.0.0.3 yang terhubung dengan S3 (Switch 3).</br>
→ H4 (Host 4) IP Address 10.0.0.4 yang terhubung dengan S2 (Switch 2).</br>
Switch-Switch
→ S1 (Switch 1) yang terhubung dengan S2 (Switch 2) dan S3 (Switch 3).</br>
→ S4 (Switch 4) yang terhubung dengan S2 (Switch 2) dan S3 (Switch 3).
</br>
- **Ryu**
:::info
```
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet, ethernet, ipv4, arp
from ryu.lib import hub
import itertools
class LoadBalancer(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def _init_(self, *args, **kwargs):
super(LoadBalancer, self)._init_(*args, **kwargs)
self.mac_to_port = {}
self.datapaths = {}
self.monitor_thread = hub.spawn(self._monitor)
# Konfigurasi virtual IP dan backends
self.virtual_ip = '10.0.0.100'
self.virtual_mac = 'aa:bb:cc:dd:ee:ff'
self.backends = {
'10.0.0.2': {'mac': '00:00:00:00:00:02', 'port': 2},
'10.0.0.3': {'mac': '00:00:00:00:00:03', 'port': 3},
}
# Round-robin iterator untuk backend
self.backend_iter = itertools.cycle(self.backends.items())
def _monitor(self):
while True:
for dp in self.datapaths.values():
self._request_stats(dp)
hub.sleep(5)
def _request_stats(self, datapath):
parser = datapath.ofproto_parser
req = parser.OFPFlowStatsRequest(datapath)
datapath.send_msg(req)
@set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
def flow_stats_reply_handler(self, ev):
for stat in ev.msg.body:
self.logger.info("Flow stats: %s", stat)
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
datapath = ev.msg.datapath
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
self.logger.info("Switch connected: datapath_id=%s", datapath.id)
# Flow default ke controller
match = parser.OFPMatch()
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
# Flow untuk komunikasi ARP dan IP Traffic antar host
match = parser.OFPMatch(eth_type=0x0806) # ARP untuk IP lokal
actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] # Flood ARP request ke semua port
self.add_flow(datapath, 10, match, actions)
# Flow untuk komunikasi IP antar host (tanpa controller)
match = parser.OFPMatch(eth_type=0x0800) # Semua paket IP
actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] # Flood IP traffic antar host
self.add_flow(datapath, 20, match, actions)
def add_flow(self, datapath, priority, match, actions, idle_timeout=60, hard_timeout=0):
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = parser.OFPFlowMod(datapath=datapath,
priority=priority,
match=match,
instructions=inst,
idle_timeout=idle_timeout,
hard_timeout=hard_timeout)
datapath.send_msg(mod)
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def packet_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocol(ethernet.ethernet)
if eth is None:
return
arp_pkt = pkt.get_protocol(arp.arp)
ip_pkt = pkt.get_protocol(ipv4.ipv4)
# Handle ARP request untuk virtual IP
if arp_pkt and arp_pkt.opcode == arp.ARP_REQUEST and arp_pkt.dst_ip == self.virtual_ip:
self.logger.info("Received ARP request for virtual IP")
self.reply_arp(datapath, arp_pkt, in_port)
return
# Handle trafik yang ditujukan ke virtual IP
if ip_pkt and ip_pkt.dst == self.virtual_ip:
# Pilih backend berdasarkan round-robin
selected_ip, backend = next(self.backend_iter)
self.logger.info("Routing traffic to backend: %s", selected_ip)
match = parser.OFPMatch(
in_port=in_port,
eth_type=0x0800,
ipv4_dst=self.virtual_ip,
ipv4_src=ip_pkt.src
)
actions = [
parser.OFPActionSetField(ipv4_dst=selected_ip),
parser.OFPActionSetField(eth_dst=backend['mac']),
parser.OFPActionOutput(backend['port'])
]
self.add_flow(datapath, 10, match, actions, idle_timeout=30)
out = parser.OFPPacketOut(
datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=in_port,
actions=actions,
data=msg.data
)
datapath.send_msg(out)
def reply_arp(self, datapath, arp_request, port):
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
ether = ethernet.ethernet(
dst=arp_request.src_mac,
src=self.virtual_mac,
ethertype=0x0806
)
arp_reply = arp.arp(
opcode=arp.ARP_REPLY,
src_mac=self.virtual_mac,
src_ip=self.virtual_ip,
dst_mac=arp_request.src_mac,
dst_ip=arp_request.src_ip
)
pkt = packet.Packet()
pkt.add_protocol(ether)
pkt.add_protocol(arp_reply)
pkt.serialize()
out = parser.OFPPacketOut(
datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=ofproto.OFPP_CONTROLLER,
actions=[parser.OFPActionOutput(port)],
data=pkt.data
)
datapath.send_msg(out)
```
Script Ryu ini adalah load balancer SDN berbasis OpenFlow 1.3 yang menggunakan virtual IP (10.0.0.100) untuk mendistribusikan trafik ke dua backend server (10.0.0.2 dan 10.0.0.3) secara round-robin. Ia menangani permintaan ARP ke VIP dan mengganti tujuan IP/MAC ke backend saat menerima trafik ke VIP, lalu meneruskannya ke server yang dipilih.
:::
:::warning
:::spoiler **Skenario 1 Outputs**

Host → Switch:
h1 → s1
h2 → s4
h3 → s3
h4 → s2
Antar Switch (mesh):
s1 ↔ s2
s1 ↔ s3
s2 ↔ s4
s3 ↔ s4

iperf digunakan untuk mengukur bandwidth antara dua host dalam jaringan.
Command iperf dijalankan dua kali dari host yang berbeda:
h1 ke h2 → melalui IP 10.0.0.2
h3 ke h4 → melalui IP 10.0.0.4

sudo ovs-ofctl dump-flows s1
yang digunakan untuk melihat semua flow entries (aturan pemrosesan paket) yang telah diinstal pada switch Open vSwitch (dalam hal ini s1) oleh controller Ryu Anda.

Host: Menambahkan 4 host virtual (h1–h4).
Switch: Menambahkan 4 switch virtual (s1–s4).
Link: Menghubungkan host dan switch serta antar-switch.
Contohnya:
h1 <-> s1 artinya host h1 dihubungkan ke switch s1.
s1 <-> s2 artinya switch s1 dihubungkan ke s2
:::
</br>
## Skenario 2: Sniffing
Sniffing adalah metode penyadapan lalu lintas data pada suatu jaringan komputer. Aktivitas ini biasanya disalahgunakan oleh orang-orang yang tidak bertanggung jawab, seperti Hacker.
---

1. Setup Mininet dan Ryu dengan topologi di atas dengan ketentuan:
- Dalam skenario kali ini, jika Host2 ingin mengirimkan paket ke Host1, ketika paket sampai Switch2, Switch2 akan menduplikasi paket tersebut dan melakukan forwarding ke port 3 (Hacker3).
- Lalu jika Host1 ingin mengirim paket ke Host2, ketika paket sampai di Switch1, Switch1 akan menduplikasi paket tersebut dan melakukan forwarding ke port 3 (Hacker1) dan port 4 (Hacker2).
2. Pembuktian
- Lakukan tes **iperf Host1 ke Host2** untuk melakukan dump paket.
- Lakukan cek stat menggunakan **ovs-ofctl**.
:::warning
:::spoiler **Skenario 2 Scripts**
- **Topologi**
:::info
```markdown=
from mininet.topo import Topo
class SniffTopo(Topo):
def build(self):
# Tambah switch
s1 = self.addSwitch('s1')
s2 = self.addSwitch('s2')
# Tambah host
h1 = self.addHost('h1') # host1
h2 = self.addHost('h2') # host2
h3 = self.addHost('h3') # hacker1
h4 = self.addHost('h4') # hacker2
h5 = self.addHost('h5') # hacker3
# Urutan link memengaruhi penomoran port
# Switch s2
self.addLink(s2, s1, port1=1, port2=1) # s2-eth1
self.addLink(s2, h1, port1=2, port2=1) # s2-eth2
self.addLink(s2, h5, port1=3, port2=1) # s2-eth3
# Switch s1
self.addLink(s1, h2, port1=2, port2=1) # s1-eth2
self.addLink(s1, h3, port1=3, port2=1) # s1-eth3
self.addLink(s1, h4, port1=4, port2=1) # s1-eth4
topos = {'snifftopo': (lambda: SniffTopo())}
```
→ H1 (Host 1) port 1 terhubung dengan S2 (Switch 2) port 2.
→ H2 (Host 2) port 1 terhubung dengan S1 (Switch 1) port 2.
→ H3 (Host 3 / hacker1) port 1 dengan S1 (Switch 1) port 3.
→ H4 (Host 4 / hacker2) port 1 dengan S1 (Switch 1) port 4.
→ H5 (Host 5 / hacker3) port 1 dengan S2 (Switch 2) port 3.
→ S2 (Switch 2) port 1 terhubung dengan S1 (Switch 1) port 1.
</br>
- **Ryu**
:::info
```markdown=
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 SniffingController(app_manager.RyuApp):
# Menentukan versi OpenFlow yang digunakan oleh controller ini
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def _init_(self, *args, **kwargs):
# Konstruktor untuk inisialisasi controller
super(SniffingController, self)._init_(*args, **kwargs)
# Menyimpan mapping MAC address ke port switch
self.mac_to_port = {}
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
# Menangani event ketika switch baru terhubung
datapath = ev.msg.datapath
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
# Install table-miss flow entry yang mengarah ke controller
match = parser.OFPMatch()
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
def add_flow(self, datapath, priority, match, actions):
# Fungsi untuk menambahkan flow entry ke switch
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
# Instruksi untuk menerapkan aksi yang ditentukan pada flow
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
match=match, instructions=inst)
datapath.send_msg(mod)
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
# Menangani event ketika ada paket yang masuk ke controller
msg = ev.msg
datapath = msg.datapath
dpid = datapath.id
parser = datapath.ofproto_parser
ofproto = datapath.ofproto
# Mengambil informasi Ethernet dari paket yang diterima
pkt = packet.Packet(msg.data)
eth = pkt.get_protocol(ethernet.ethernet)
# Mendapatkan alamat tujuan dan sumber
dst = eth.dst
src = eth.src
in_port = msg.match['in_port']
# Menyimpan MAC address ke port
self.mac_to_port.setdefault(dpid, {})
self.mac_to_port[dpid][src] = in_port
# Menentukan port keluar berdasarkan MAC address tujuan
out_port = self.mac_to_port[dpid].get(dst, ofproto.OFPP_FLOOD)
actions = []
# Jika alamat tujuan ditemukan (tidak di flood), paket akan keluar melalui port tersebut
if out_port != ofproto.OFPP_FLOOD:
actions.append(parser.OFPActionOutput(out_port))
# Logika sniffing berdasarkan dpid (ID switch):
if dpid == 1:
# Jika switch adalah S1, kita duplikasi paket yang menuju Host2 ke Hacker1 (port 3) dan Hacker2 (port 4)
if out_port != 3:
actions.append(parser.OFPActionOutput(3)) # Menyalin ke Hacker1
if out_port != 4:
actions.append(parser.OFPActionOutput(4)) # Menyalin ke Hacker2
elif dpid == 2:
# Jika switch adalah S2, kita duplikasi paket yang menuju Host1 ke Hacker3 (port 3)
if out_port != 3:
actions.append(parser.OFPActionOutput(3)) # Menyalin ke Hacker3
# Membuat pesan PacketOut untuk mengirimkan paket yang telah dimodifikasi
out = parser.OFPPacketOut(datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=in_port,
actions=actions,
data=msg.data)
datapath.send_msg(out)
```
sturktur penjelasan mengenai ryu script
- app_manager: Mengatur siklus hidup aplikasi Ryu.
- ofp_event: Event-event OpenFlow (misalnya saat switch connect atau ada paket masuk).
- set_ev_cls: Dekorator untuk mendaftarkan handler berdasarkan jenis event.
- ofproto_v1_3: Mendukung protokol OpenFlow versi 1.3. packet,
- ethernet: Untuk parsing isi paket Ethernet.
:::
:::warning
:::spoiler **Skenario 2 Outputs**
Dalam skenario kali ini, jika Host2 ingin mengirimkan paket ke Host1, ketika paket sampai Switch2, Switch2 akan menduplikasi paket tersebut dan melakukan forwarding ke port 3 (Hacker3).


- Masukkan perintah
```markdown=
sudo mn --custom sniff_toppology.py --topo snifftopo -controller=remote, ip=10.0.0.4,port=30001 --switch=ovsk
```
- `--custom niff_topology.py` adalah script topologi yang akan dijalanakan.
- `--topo snifftopo` adalah nama topo itu sendiri.
- `--controller=remote, ip=10.0.0.4, port=30001` adalah me-remote dari vm ryu, dengan `ip vm ryu 10.0.0.4`, dam `port 30001`.
- `--switch=ovsk`, menginstruksikan Mininet untuk menggunakan Open vSwitch (OVS) sebagai switch virtual
- Masukkan perintah dalam CLI mininet
`mininet> h2 iperf -s &`
- `-s` digunakan untuk menjalankan dalam mode server.
- `simbol &` digunakan untuk menjalankan dibackground.
- Masukkan printah dalam CLI mininet
`mininet> h1 iperf -c h2`
- `-c`, h1 (mode client) mengirimkan data ke h2
:::success
- `-c` mode client;
- `-s`, mode server;
- `-t`, waktu yang dibutuhkan;

- Lakukan cek stat menggunakan `ovs-ofctl`.

:::
## Skenario 3: QoS (Quality of Sevice)
Quality of Service (QoS) di Kubernetes adalah sistem yang mengelola dan memprioritaskan alokasi sumber daya (CPU dan memori) di antara Pod, memastikan bahwa aplikasi penting mendapatkan sumber daya yang dibutuhkan dan sistem tetap stabil. Kubernetes membagi Pod menjadi tiga kelas QoS: Guaranteed (Dijamin), Burstable (Dapat Dilanggar), dan Best Effort (Upaya Terbaik).
### Definisi
QoS di Kubernetes adalah mekanisme untuk menentukan bagaimana Pod mendapatkan sumber daya, terutama CPU dan memori, dalam kondisi persaingan.
### Kelas QoS
- Guaranteed: Pod ini memiliki permintaan dan batas sumber daya yang sama. Jika permintaan dan batas sama, Kubernetes menjamin bahwa Pod selalu mendapatkan jumlah sumber daya yang dibutuhkan.
- Burstable: Pod ini memiliki permintaan sumber daya yang lebih rendah daripada batasnya. Pod dapat menggunakan lebih banyak sumber daya jika tersedia, tetapi terbatas pada batas yang telah ditetapkan.
- Best Effort: Pod ini tidak memiliki permintaan atau batas sumber daya. Pod dapat menggunakan sumber daya yang tersedia, tetapi tidak memiliki jaminan untuk mendapatkan sumber daya yang dibutuhkan.
### Manfaat QoS
Jaminan Sumber Daya: QoS memastikan bahwa aplikasi penting selalu mendapatkan sumber daya yang diperlukan, bahkan dalam kondisi beban yang berat.
Pengendalian Sumber Daya: QoS membantu mengelola sumber daya secara efektif dan mencegah satu Pod menghabiskan terlalu banyak sumber daya yang dibutuhkan oleh Pod lain.
Penjadwalan dan Penghapusan: QoS memengaruhi bagaimana Pod dijadwalkan dan dihapus jika sistem kekurangan sumber daya. Pod dengan QoS yang lebih tinggi (seperti Guaranteed) memiliki prioritas yang lebih tinggi dalam penjadwalan dan akan dipertahankan lebih lama jika sumber daya terbatas.
### Penggunaan
QoS digunakan untuk menjamin kinerja aplikasi, mengelola sumber daya secara efisien, dan memastikan stabilitas sistem.
### Pentingnya QoS
Dalam lingkungan Kubernetes yang kompleks dengan banyak Pod dan beban kerja, QoS sangat penting untuk memastikan bahwa aplikasi dapat berjalan dengan baik dan sistem tetap stabil.
---

1. Setup Mininet dan Ryu dengan topologi di atas dengan ketentuan:
- Trafik dari Host1 ke Host3 (**VoIP**) → Diprioritaskan dengan queue berkecepatan tinggi.
- Trafik dari Host2 ke Host4 (**HTTP**) → Diproses dengan queue berkecepatan lebih rendah.
- Terapkan QoS dengan OVS Queue untuk memastikan VoIP mendapatkan bandwidth lebih besar dibanding HTTP.
2. Pembuktian QoS berjalan dengan benar
- Gunakan **iperf** untuk melakukan uji trafik dan tunjukkan bahwa trafik prioritas tinggi mendapatkan bandwidth lebih besar dibanding trafik prioritas rendah.
- Gunakan **Wireshark** untuk melihat bagaimana paket **diprioritaskan**.
- **Bandingkan hasil pengujian dengan dan tanpa QoS.**
:::warning
:::spoiler **Skenario 3 Scripts**
- Topologi
:::info
```markdown=
from mininet.topo import Topo
class QoSTopo(Topo):
def __init__(self):
Topo.__init__(self)
# Add switches
s1 = self.addSwitch('s1', protocols='OpenFlow13')
s2 = self.addSwitch('s2', protocols='OpenFlow13')
# Add hosts with MAC and IP
h1 = self.addHost('h1', mac='00:00:00:00:00:01', ip='10.0.0.1/24') # V>
h2 = self.addHost('h2', mac='00:00:00:00:00:02', ip='10.0.0.2/24') # H>
h3 = self.addHost('h3', mac='00:00:00:00:00:03', ip='10.0.0.3/24') # V>
h4 = self.addHost('h4', mac='00:00:00:00:00:04', ip='10.0.0.4/24') # H>
# Add links
self.addLink(h1, s1, port1=1, port2=1) # h1 --> port 1 s1
self.addLink(h2, s1, port1=1, port2=2) # h2 --> port 2 s1
self.addLink(s1, s2, port1=3, port2=1) # s1 port3 --> s2 port 2
self.addLink(h3, s2, port1=1, port2=2) # h3 --> port 2 s2
self.addLink(h4, s2, port1=1, port2=3) # h4 --> port 3 s2
topos = {'QoS_topo': (lambda: QoSTopo())}
```
- H1 (Host 1) port 1 dengan IP Address 10.0.0.1 dan MAC Address 00:00:00:00:00:01 yang terhubung dengan S1 (Switch 1) port 1.</br>
- H2 (Host 2) port 1 dengan IP Address 10.0.0.2 dan MAC Address 00:00:00:00:00:02 yang terhubung dengan S1 (Switch 1) port 2.</br>
- S1 (Switch 1) port 3 terhubung dengan S2 (Switch 2) port 1 dimana keduanya sama-sama menggunakan protokol **OpenFlow13**.</br>
- H3 (Host 3) port 1 dengan IP Address 10.0.0.3 dan MAC Address 00:00:00:00:00:03 yang terhubung dengan S2 (Switch 2) port 2.</br>
- H4 (Host 4) port 1 dengan IP Address 10.0.0.4 dan MAC Address 00:00:00:00:00:04 yang terhubung dengan S2 (Switch 2) port 3.
</br>
- Ryu
:::info
```markdown=
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet, ethernet, ipv4, tcp, udp
class QoSController(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def __init__(self, *args, **kwargs):
super(QoSController, self).__init__(*args, **kwargs)
self.mac_to_port = {}
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
datapath = ev.msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
# Table-miss flow entry
match = parser.OFPMatch()
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)]
self.add_flow(datapath, 0, match, actions)
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
in_port = msg.match['in_port']
pkt = packet.Packet(msg.data)
eth = pkt.get_protocol(ethernet.ethernet)
if eth.ethertype == 0x88cc:
return # Ignore LLDP
dpid = datapath.id
self.mac_to_port.setdefault(dpid, {})
self.mac_to_port[dpid][eth.src] = in_port
out_port = self.mac_to_port[dpid].get(eth.dst, ofproto.OFPP_FLOOD)
actions = []
ip_pkt = pkt.get_protocol(ipv4.ipv4)
if ip_pkt:
if ip_pkt.proto == 17: # UDP (VoIP)
actions.append(parser.OFPActionSetQueue(0))
elif ip_pkt.proto == 6: # TCP (HTTP)
actions.append(parser.OFPActionSetQueue(1))
actions.append(parser.OFPActionOutput(out_port))
if out_port != ofproto.OFPP_FLOOD:
match = parser.OFPMatch(
in_port=in_port,
eth_type=0x0800,
ipv4_src=ip_pkt.src,
ipv4_dst=ip_pkt.dst,
ip_proto=ip_pkt.proto
)
self.add_flow(datapath, 1, match, actions)
out = parser.OFPPacketOut(
datapath=datapath,
buffer_id=msg.buffer_id,
in_port=in_port,
actions=actions,
data=msg.data if msg.buffer_id == ofproto.OFP_NO_BUFFER else None
)
datapath.send_msg(out)
def add_flow(self, datapath, priority, match, actions):
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = parser.OFPFlowMod(
datapath=datapath,
priority=priority,
match=match,
instructions=inst
)
datapath.send_msg(mod)
```
Script Ryu ini mengimplementasikan tentang QoS (Quality of Service) sederhana yang memprioritaskan lalu lintas jaringan berbasis OpenFlow v1.3. Controller ini membagi bandwidth menjadi dua antrian prioritas: antrian 0 (80% bandwidth) untuk lalu lintas UDP/VoIP (prioritas tinggi) dan antrian 1 (20% bandwidth) untuk lalu lintas TCP/HTTP (prioritas rendah).
:::
:::warning
:::spoiler **Skenario 3 Outputs**
- Tanpa QoS
:::danger
:::spoiler **Tanpa QoS**
- VoIP (UDP - High Priority)
→ Verifikasi
```markdown=
mininet@vm-mininet:~$ sudo mn --custom qos_topology.py --topo QoS_topo --controller=remote,ip=10.0.0.4,port=30001
/usr/local/bin/mn:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
__import__('pkg_resources').run_script('mininet==2.3.1b4', 'mn')
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 h4
*** Adding switches:
s1 s2
*** Adding links:
(h1, s1) (h2, s1) (h3, s2) (h4, s2) (s1, s2)
*** Configuring hosts
h1 h2 h3 h4
*** Starting controller
c0
*** Starting 2 switches
s1 s2 ...
*** Starting CLI:
mininet> h3 iperf -s -u &
mininet> h1 iperf -c h3 -u -b 10M
------------------------------------------------------------
Client connecting to 10.0.0.3, UDP port 5001
Sending 1470 byte datagrams, IPG target: 1121.52 us (kalman adjust)
UDP buffer size: 208 KByte (default)
------------------------------------------------------------
[ 1] local 10.0.0.1 port 33022 connected with 10.0.0.3 port 5001
[ ID] Interval Transfer Bandwidth
[ 1] 0.0000-10.0018 sec 12.5 MBytes 10.5 Mbits/sec
[ 1] Sent 8921 datagrams
[ 1] Server Report:
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
[ 1] 0.0000-9.9913 sec 12.5 MBytes 10.5 Mbits/sec 0.006 ms 0/8920 (0%)
[ 1] 0.0000-9.9913 sec 5 datagrams received out-of-order
mininet> exit
*** Stopping 1 controllers
c0
*** Stopping 5 links
.....
*** Stopping 2 switches
s1 s2
*** Stopping 4 hosts
h1 h2 h3 h4
*** Done
completed in 830.451 seconds
```
→ Hasil Dari simulasi menggunakan mininet dengan menggunakan topologi khusus yang telah dirancang yang menghubungkan 4 host (h1-h4) dan 2 switch (s1-s2).
Setelah jaringan di jalankan, maka dilakukan pengujian bandwidth antara h1 (client) dan h3 (server) menggunakan iperf dengan protokol UDP dengan kecepatan 10Mbps.


→ Diatas merupakan data yang diambil di Wiresharknya.
</br>
- HTTP (TCP - Low Priority)
→ Verifikasi
```markdown=
mininet@vm-mininet:~$ sudo mn --custom qos_topology.py --topo QoS_topo --control ler=remote,ip=10.0.0.4,port=30001
/usr/local/bin/mn:4: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
__import__('pkg_resources').run_script('mininet==2.3.1b4', 'mn')
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3 h4
*** Adding switches:
s1 s2
*** Adding links:
(h1, s1) (h2, s1) (h3, s2) (h4, s2) (s1, s2)
*** Configuring hosts
h1 h2 h3 h4
*** Starting controller
c0
*** Starting 2 switches
s1 s2 ...
*** Starting CLI:
mininet> h4 iperf -s &
mininet> h2 iperf -c h4
------------------------------------------------------------
Client connecting to 10.0.0.4, TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[ 1] local 10.0.0.2 port 35400 connected with 10.0.0.4 port 5001 (icwnd/mss/irt t=14/1448/6124)
[ ID] Interval Transfer Bandwidth
[ 1] 0.0000-10.0156 sec 35.8 GBytes 30.7 Gbits/sec
mininet> exit
*** Stopping 1 controllers
c0
*** Stopping 5 links
.....
*** Stopping 2 switches
s1 s2
*** Stopping 4 hosts
h1 h2 h3 h4
*** Done
completed in 1993.962 seconds
```
→ Hasil Dari simulasi menggunakan mininet dengan menggunakan topologi khusus yang telah dirancang yang menghubungkan 4 host (h1-h4) dan 2 switch (s1-s2).
Setelah jaringan aktif, maka dilakukan pengujian bandwidth antara h2 (client) dan h4 (server) menggunakan iperf dengan protokol TCP.


→ Diatas merupakan data yang diambil di Wiresharknya.
- Qos
:::success
:::spoiler **QoS**
**1. H1 ke H3**

→ Menjalankan perintah iperf, perintah yang pertama mininets h3 iperf -s -u & memulai server UDP pada host h3, lalu perintah yang kedua mininets h1 iperf -c h3 -u -b 10M mengirim traffic UDP dari host h1 ke h3 dengan bandwidth 10Mbps.

→ Diatas merupakan Hasil ujicoba yang diambil pada Wireshark dari H1 ke H3.
**2. H2 ke H4**

→ Menjalankan perintah iperf, perintah yang pertama h4 iperf -s -p 5002 & mengaktifkan server iperf pada host h4. Lalu perintah yang kedua h2 iperf -c h4 -p 5002 -b 2M -t 60 & mengirim traffic UDP dari host h2 ke h4 dengan bandwidth 2 Mbps selama 60 detik.


→ Diatas merupakan Hasil ujicoba yang diambil pada Wireshark dari H2 ke H4.
3. Gunakan Wireshark untuk melihat bagaimana paket diprioritaskan.
4. HTTP


→ Diatas merupakan data yang diambil di Wiresharknya.
:::