From 2e236afa1d0d3de1299f2ce8a3603ecb8097047c Mon Sep 17 00:00:00 2001 From: Nawasan Wisitsingkhon Date: Sat, 11 May 2024 14:37:26 +0700 Subject: [PATCH] setup and send flow_mod --- src/controller.rs | 43 ++++++++++++++++++- .../events/flow_mod/flow_mod_handler.rs | 15 +++++++ src/openflow/events/flow_mod/match_fields.rs | 16 +++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/controller.rs b/src/controller.rs index 4211ba8..a41e0e9 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -1,10 +1,12 @@ #![allow(unused)] #![allow(unused_variables)] +use crate::openflow::events::flow_mod::{FlowModCommand, MatchFields}; /** * Here is Controller you can modify and write the process or more you need. * In production please remove allow unused. */ -use crate::openflow::events::PacketInEvent; +use crate::openflow::events::{FlowAction, FlowModEvent, PacketInEvent}; +use crate::openflow::PseudoPort; use crate::openflow::{controller_frame::ControllerFrame, traiter::OfpMsgEvent}; use std::{collections::HashMap, net::TcpStream}; @@ -26,5 +28,42 @@ impl ControllerFrame for Controller { /** * Start here for handle packetIn message. */ - fn packet_in_handler(&mut self, xid: u32, packetin: PacketInEvent, stream: &mut TcpStream) {} + fn packet_in_handler(&mut self, xid: u32, packetin: PacketInEvent, stream: &mut TcpStream) { + let mac_dst = packetin.payload.mac_des; + let mac_src = packetin.payload.mac_src; + let out_port = self.mac_to_port.get(&mac_dst); + match out_port { + Some(p) => { + let src_port = packetin.port; + let mut src_dst_match = MatchFields::match_all(); + src_dst_match.mac_dest = Some(mac_dst); + src_dst_match.mac_src = Some(mac_src); + + let mut dst_src_match = MatchFields::match_all(); + dst_src_match.mac_dest = Some(mac_src); + dst_src_match.mac_src = Some(mac_dst); + + let actions = vec![FlowAction::Oputput(PseudoPort::PhysicalPort(*p))]; + self.add_flow(xid, src_dst_match, actions, stream); + + let actions = vec![FlowAction::Oputput(PseudoPort::PhysicalPort(src_port))]; + self.add_flow(xid, dst_src_match, actions, stream); + + // let pkt_out = + } + None => todo!(), + } + } +} + +impl Controller { + fn add_flow( + &self, + xid: u32, + flow: MatchFields, + actions: Vec, + stream: &mut TcpStream, + ) { + self.send_msg(FlowModEvent::add_flow(10, flow, actions), xid, stream) + } } diff --git a/src/openflow/events/flow_mod/flow_mod_handler.rs b/src/openflow/events/flow_mod/flow_mod_handler.rs index 7b7bfaf..f0aa205 100644 --- a/src/openflow/events/flow_mod/flow_mod_handler.rs +++ b/src/openflow/events/flow_mod/flow_mod_handler.rs @@ -43,6 +43,21 @@ pub struct FlowModEvent { } impl FlowModEvent { + pub fn add_flow(priority: u16, match_fileds: MatchFields, actions: Vec) -> Self { + Self { + command: FlowModCommand::Add, + match_fields: match_fileds, + priority, + actions, + cookie: 0, + idle_timeout: Timeout::Permanent, + hard_timeout: Timeout::Permanent, + notify_when_removed: false, + apply_to_packet: None, + out_port: None, + check_overlap: false, + } + } pub fn get_controller_last(&self) -> Vec { let mut not_ctrl: Vec = Vec::new(); let mut is_ctrl: Vec = Vec::new(); diff --git a/src/openflow/events/flow_mod/match_fields.rs b/src/openflow/events/flow_mod/match_fields.rs index da198ff..dfe91f7 100644 --- a/src/openflow/events/flow_mod/match_fields.rs +++ b/src/openflow/events/flow_mod/match_fields.rs @@ -75,6 +75,22 @@ pub struct MatchFields { } impl MatchFields { + pub fn match_all() -> Self { + Self { + ethernet_type: None, + in_port: None, + ip_dest: None, + ip_src: None, + mac_dest: None, + mac_src: None, + protocol: None, + tos: None, + transport_dest: None, + transport_src: None, + vlan_pcp: None, + vlan_vid: None, + } + } pub fn marshal(&self, bytes: &mut Vec) { let mut match_f = 0u32; match_f = set_bit(match_f, 0, self.in_port.is_some());