Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
T
Tenjin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nawasan Wisitsingkhon
Tenjin
Commits
282cba84
Commit
282cba84
authored
May 04, 2024
by
Nawasan Wisitsingkhon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pepare for sending message and add new support more message
parent
12d6f072
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
201 additions
and
76 deletions
+201
-76
main.rs
src/main.rs
+5
-5
controller.rs
src/openflow/controller.rs
+30
-21
features_req.rs
src/openflow/events/features_req.rs
+21
-0
command.rs
src/openflow/events/flow_mod/command.rs
+16
-6
flow_actions.rs
src/openflow/events/flow_mod/flow_actions.rs
+22
-1
flow_mod_handler.rs
src/openflow/events/flow_mod/flow_mod_handler.rs
+30
-28
match_fields.rs
src/openflow/events/flow_mod/match_fields.rs
+3
-3
mod.rs
src/openflow/events/flow_mod/mod.rs
+2
-0
hello.rs
src/openflow/events/hello.rs
+21
-0
mod.rs
src/openflow/events/mod.rs
+7
-0
header.rs
src/openflow/header.rs
+1
-1
message.rs
src/openflow/message.rs
+10
-8
mod.rs
src/openflow/mod.rs
+5
-3
ofp_port.rs
src/openflow/ofp_port.rs
+17
-0
trait_marshal.rs
src/openflow/trait_marshal.rs
+11
-0
No files found.
src/main.rs
View file @
282cba84
use
std
::
io
::
Read
;
use
std
::
net
::
TcpListener
;
use
tenjin
::
openflow
::
events
::
packet_in
::
PacketInEvent
;
use
tenjin
::
openflow
::{
Controller
,
Msg
,
OfpHeader
};
use
tenjin
::
openflow
::{
Controller
,
Ofp
Msg
,
OfpHeader
};
extern
crate
byteorder
;
...
...
@@ -31,16 +31,16 @@ fn main() -> Result<(), std::io::Error> {
let
length_payload
=
packet
.size
();
let
mut
payload
=
vec!
[
0u8
;
length_payload
];
stream
.read
(
&
mut
payload
)
?
;
let
message
=
Msg
::
parse
(
packet
.message
);
let
message
=
Ofp
Msg
::
parse
(
packet
.message
);
match
message
{
// 0 is Hello message
Msg
::
Hello
=>
{
Ofp
Msg
::
Hello
=>
{
// after get Hello, send fetureReq
controller
.feture_req
(
packet
.xid
,
&
mut
stream
);
controller
.feture
s
_req
(
packet
.xid
,
&
mut
stream
);
println!
(
"Hello event"
);
}
Msg
::
PacketIn
=>
{
Ofp
Msg
::
PacketIn
=>
{
controller
.packet_in
(
packet
.xid
,
PacketInEvent
::
parse
(
&
payload
),
...
...
src/openflow/controller.rs
View file @
282cba84
use
std
::{
collections
::
HashMap
,
io
::
Write
,
mem
::
size_of
,
net
::
TcpStream
};
use
std
::{
collections
::
HashMap
,
io
::
Write
,
net
::
TcpStream
};
use
super
::{
events
::
PacketInEvent
,
OfpHeader
};
use
super
::{
events
::{
FeaturesReq
,
HelloEvent
,
PacketInEvent
},
trait_marshal
::
MessageMarshal
,
OfpHeader
,
};
pub
struct
Controller
{
version
:
u8
,
...
...
@@ -15,32 +19,37 @@ impl Controller {
mac_to_port
:
HashMap
::
new
(),
}
}
pub
fn
send_msg
<
T
:
MessageMarshal
>
(
&
self
,
msg
:
T
,
xid
:
u32
,
stream
:
&
mut
TcpStream
)
{
let
mut
header_bytes
:
Vec
<
u8
>
=
Vec
::
new
();
let
mut
body_bytes
:
Vec
<
u8
>
=
Vec
::
new
();
msg
.marshal
(
&
mut
body_bytes
);
let
ofpheader
=
OfpHeader
::
new
(
self
.version
,
msg
.msg_code
()
as
u8
,
body_bytes
.len
()
as
u16
,
xid
,
);
ofpheader
.marshal
(
&
mut
header_bytes
);
header_bytes
.append
(
&
mut
body_bytes
);
let
_
=
stream
.write_all
(
&
header_bytes
);
}
/**
* example of sending message
*/
pub
fn
hello
(
&
self
,
stream
:
&
mut
TcpStream
)
{
let
header
=
OfpHeader
::
new
(
self
.version
,
0
,
size_of
::
<
OfpHeader
>
()
as
u16
,
0
);
let
mut
bytes
:
Vec
<
u8
>
=
Vec
::
new
();
header
.marshal
(
&
mut
bytes
);
stream
.write_all
(
&
bytes
)
.unwrap
();
let
hello_msg
=
HelloEvent
::
new
();
self
.send_msg
(
hello_msg
,
0
,
stream
);
}
pub
fn
feture_req
(
&
self
,
xid
:
u32
,
stream
:
&
mut
TcpStream
)
{
let
header
=
OfpHeader
::
new
(
self
.version
,
5
,
8
,
xid
);
let
mut
bytes
:
Vec
<
u8
>
=
Vec
::
new
();
header
.marshal
(
&
mut
bytes
);
stream
.write_all
(
&
bytes
)
.unwrap
();
pub
fn
fetures_req
(
&
self
,
xid
:
u32
,
stream
:
&
mut
TcpStream
)
{
let
fetreq_msg
=
FeaturesReq
::
new
();
self
.send_msg
(
fetreq_msg
,
xid
,
stream
);
}
pub
fn
packet_in
(
&
mut
self
,
xid
:
u32
,
packetin
:
PacketInEvent
,
stream
:
&
mut
TcpStream
)
{
let
ether
=
packetin
.payload
;
self
.mac_to_port
.insert
(
ether
.mac_src
,
packetin
.port
);
}
pub
fn
send
(
&
self
,
xid
:
u32
,
message
:
u8
,
payload
:
&
Vec
<
u8
>
,
stream
:
&
mut
TcpStream
)
{
let
length
=
size_of
::
<
OfpHeader
>
()
+
payload
.len
();
let
header
=
OfpHeader
::
new
(
self
.version
,
message
,
length
as
u16
,
xid
);
let
mut
bytes
:
Vec
<
u8
>
=
Vec
::
new
();
header
.marshal
(
&
mut
bytes
);
stream
.write_all
(
&
bytes
)
.unwrap
();
}
}
src/openflow/events/features_req.rs
0 → 100644
View file @
282cba84
use
crate
::
openflow
::
trait_marshal
::
MessageMarshal
;
pub
struct
FeaturesReq
{}
impl
FeaturesReq
{
pub
fn
new
()
->
Self
{
FeaturesReq
{}
}
}
impl
MessageMarshal
for
FeaturesReq
{
fn
marshal
(
&
self
,
_
:
&
mut
Vec
<
u8
>
)
{}
fn
msg_code
(
&
self
)
->
crate
::
openflow
::
OfpMsg
{
crate
::
openflow
::
OfpMsg
::
FeaturesReq
}
fn
size_of
(
&
self
)
->
usize
{
0
}
}
src/openflow/events/flow_mod/command.rs
View file @
282cba84
pub
enum
FlowModCommand
{
Add
,
Modify
,
ModifyStrict
,
Delete
,
DeleteStrict
,
Unparsable
,
Add
=
0
,
Modify
=
1
,
ModifyStrict
=
2
,
Delete
=
3
,
DeleteStrict
=
4
,
Unparsable
=
-
1
,
}
impl
FlowModCommand
{
pub
fn
to_number
(
&
self
)
->
usize
{
match
self
{
FlowModCommand
::
Add
=>
Self
::
Add
as
usize
,
FlowModCommand
::
Modify
=>
Self
::
Modify
as
usize
,
FlowModCommand
::
ModifyStrict
=>
Self
::
ModifyStrict
as
usize
,
FlowModCommand
::
Delete
=>
Self
::
Delete
as
usize
,
FlowModCommand
::
DeleteStrict
=>
Self
::
DeleteStrict
as
usize
,
FlowModCommand
::
Unparsable
=>
Self
::
Unparsable
as
usize
,
}
}
pub
fn
parse
(
byte
:
u16
)
->
Self
{
match
byte
{
0
=>
Self
::
Add
,
...
...
src/openflow/events/flow_mod/flow_actions.rs
View file @
282cba84
...
...
@@ -28,7 +28,7 @@ pub enum FlowAction {
}
impl
FlowAction
{
pub
fn
to_action_code
(
&
self
)
->
FlowActionType
{
pub
fn
to_action_code
(
&
self
)
->
FlowActionType
{
match
self
{
FlowAction
::
Oputput
(
_
)
=>
FlowActionType
::
Output
,
FlowAction
::
SetDlVlan
(
_
)
=>
FlowActionType
::
SetVlanId
,
...
...
@@ -201,3 +201,23 @@ impl FlowAction {
}
}
}
impl
Clone
for
FlowAction
{
fn
clone
(
&
self
)
->
Self
{
match
self
{
Self
::
Oputput
(
v
)
=>
Self
::
Oputput
(
v
.clone
()),
Self
::
SetDlVlan
(
v
)
=>
Self
::
SetDlVlan
(
v
.clone
()),
Self
::
SetDlVlanPcp
(
v
)
=>
Self
::
SetDlVlanPcp
(
v
.clone
()),
Self
::
SetDlSrc
(
v
)
=>
Self
::
SetDlSrc
(
v
.clone
()),
Self
::
SetDlDest
(
v
)
=>
Self
::
SetDlDest
(
v
.clone
()),
Self
::
SetIpSrc
(
v
)
=>
Self
::
SetIpSrc
(
v
.clone
()),
Self
::
SetIpDes
(
v
)
=>
Self
::
SetIpDes
(
v
.clone
()),
Self
::
SetTos
(
v
)
=>
Self
::
SetTos
(
v
.clone
()),
Self
::
SetTpSrc
(
v
)
=>
Self
::
SetTpSrc
(
v
.clone
()),
Self
::
SetTpDest
(
v
)
=>
Self
::
SetTpDest
(
v
.clone
()),
Self
::
Enqueue
(
v
,
arg1
)
=>
Self
::
Enqueue
(
v
.clone
(),
arg1
.clone
()),
Self
::
Unparsable
=>
Self
::
Unparsable
,
}
}
}
\ No newline at end of file
src/openflow/events/flow_mod/flow_mod_handler.rs
View file @
282cba84
...
...
@@ -2,7 +2,7 @@ use std::io::Cursor;
use
byteorder
::{
BigEndian
,
ReadBytesExt
,
WriteBytesExt
};
use
crate
::
openflow
::{
OfpPort
,
PseudoPort
};
use
crate
::
openflow
::{
trait_marshal
::
MessageMarshal
,
OfpMsg
,
OfpPort
,
PseudoPort
};
use
super
::{
FlowAction
,
FlowModCommand
,
MatchFields
};
...
...
@@ -25,7 +25,7 @@ impl Timeout {
}
}
pub
struct
FlowMod
{
pub
struct
FlowMod
Event
{
command
:
FlowModCommand
,
match_fields
:
MatchFields
,
priority
:
u16
,
...
...
@@ -39,26 +39,23 @@ pub struct FlowMod {
check_overlap
:
bool
,
}
impl
FlowMod
{
pub
fn
get_controller_last
(
actions
:
Vec
<
FlowAction
>
)
->
Vec
<
FlowAction
>
{
impl
FlowMod
Event
{
pub
fn
get_controller_last
(
&
self
)
->
Vec
<
FlowAction
>
{
let
mut
not_ctrl
:
Vec
<
FlowAction
>
=
Vec
::
new
();
let
mut
is_ctrl
:
Vec
<
FlowAction
>
=
Vec
::
new
();
for
act
in
actions
{
for
act
in
&
self
.
actions
{
match
act
{
FlowAction
::
Oputput
(
PseudoPort
::
Controller
(
_
))
=>
{
is_ctrl
.push
(
act
);
is_ctrl
.push
(
act
.clone
()
);
}
_
=>
not_ctrl
.push
(
act
),
_
=>
not_ctrl
.push
(
act
.clone
()
),
}
}
not_ctrl
.append
(
&
mut
is_ctrl
);
not_ctrl
}
pub
fn
size_of
()
->
usize
{
24
}
pub
fn
parse
(
buf
:
&
[
u8
])
->
FlowMod
{
pub
fn
parse
(
buf
:
&
[
u8
])
->
FlowModEvent
{
let
mut
bytes
=
Cursor
::
new
(
buf
.to_vec
());
let
match_fields
=
MatchFields
::
parse
(
&
mut
bytes
);
let
cookie
=
bytes
.read_u64
::
<
BigEndian
>
()
.unwrap
();
...
...
@@ -70,7 +67,7 @@ impl FlowMod {
let
out_port
=
PseudoPort
::
parse
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
());
let
flags
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
let
actions
=
FlowAction
::
parse_sequence
(
&
mut
bytes
);
FlowMod
{
FlowMod
Event
{
command
,
match_fields
,
cookie
,
...
...
@@ -89,30 +86,35 @@ impl FlowMod {
check_overlap
:
flags
&
2
!=
0
,
}
}
pub
fn
marshal
(
flowmod
:
FlowMod
,
bytes
:
&
mut
Vec
<
u8
>
)
{
flowmod
.match_fields
.marshal
(
bytes
);
let
_
=
bytes
.write_u64
::
<
BigEndian
>
(
flowmod
.cookie
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
flowmod
.command
as
u16
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
flowmod
.idle_timeout
.to_int
());
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
flowmod
.hard_timeout
.to_int
());
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
flowmod
.priority
);
let
_
=
bytes
.write_i32
::
<
BigEndian
>
(
match
flowmod
.apply_to_packet
{
}
impl
MessageMarshal
for
FlowModEvent
{
fn
size_of
(
&
self
)
->
usize
{
24
}
fn
msg_code
(
&
self
)
->
OfpMsg
{
OfpMsg
::
FlowMod
}
fn
marshal
(
&
self
,
bytes
:
&
mut
Vec
<
u8
>
)
{
self
.match_fields
.marshal
(
bytes
);
let
_
=
bytes
.write_u64
::
<
BigEndian
>
(
self
.cookie
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
self
.command
.to_number
()
as
u16
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
self
.idle_timeout
.to_int
());
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
self
.hard_timeout
.to_int
());
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
self
.priority
);
let
_
=
bytes
.write_i32
::
<
BigEndian
>
(
match
self
.apply_to_packet
{
None
=>
-
1
,
Some
(
buf_id
)
=>
buf_id
as
i32
,
});
match
flowmod
.out_port
{
match
self
.out_port
.as_ref
()
{
None
=>
bytes
.write_u16
::
<
BigEndian
>
(
OfpPort
::
None
as
u16
)
.unwrap
(),
Some
(
p
)
=>
p
.marshal
(
bytes
),
}
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
(
if
flowmod
.check_overlap
{
1
<<
1
}
else
{
0
})
|
(
if
flowmod
.notify_when_removed
{
1
<<
0
}
else
{
0
}),
(
if
self
.check_overlap
{
1
<<
1
}
else
{
0
})
|
(
if
self
.notify_when_removed
{
1
<<
0
}
else
{
0
}),
);
for
act
in
FlowMod
::
get_controller_last
(
flowmod
.actions
)
{
for
act
in
self
.get_controller_last
(
)
{
match
act
{
FlowAction
::
Oputput
(
PseudoPort
::
Table
)
=>
{
panic!
(
"Openflow table not allowed"
)
...
...
src/openflow/events/flow_mod/match_fields.rs
View file @
282cba84
...
...
@@ -75,7 +75,7 @@ pub struct MatchFields {
}
impl
MatchFields
{
pub
fn
marshal
(
self
,
bytes
:
&
mut
Vec
<
u8
>
)
{
pub
fn
marshal
(
&
self
,
bytes
:
&
mut
Vec
<
u8
>
)
{
let
mut
match_f
=
0u32
;
match_f
=
set_bit
(
match_f
,
0
,
self
.in_port
.is_some
());
match_f
=
set_bit
(
match_f
,
1
,
self
.vlan_vid
.is_some
());
...
...
@@ -85,8 +85,8 @@ impl MatchFields {
match_f
=
set_bit
(
match_f
,
5
,
self
.protocol
.is_some
());
match_f
=
set_bit
(
match_f
,
6
,
self
.ip_src
.is_some
());
match_f
=
set_bit
(
match_f
,
7
,
self
.ip_dest
.is_some
());
match_f
=
MatchFields
::
set_nw_mask
(
match_f
,
8
,
self
.ip_src
.unwrap
()
.ip
);
match_f
=
MatchFields
::
set_nw_mask
(
match_f
,
14
,
self
.ip_dest
.unwrap
()
.ip
);
match_f
=
MatchFields
::
set_nw_mask
(
match_f
,
8
,
self
.ip_src
.
as_ref
()
.
unwrap
()
.ip
);
match_f
=
MatchFields
::
set_nw_mask
(
match_f
,
14
,
self
.ip_dest
.
as_ref
()
.
unwrap
()
.ip
);
match_f
=
set_bit
(
match_f
,
20
,
self
.vlan_pcp
.is_some
());
match_f
=
set_bit
(
match_f
,
21
,
self
.tos
.is_some
());
bytes
.write_u32
::
<
BigEndian
>
(
match_f
)
.unwrap
();
...
...
src/openflow/events/flow_mod/mod.rs
View file @
282cba84
pub
mod
flow_mod_handler
;
pub
use
flow_mod_handler
::
FlowModEvent
;
pub
mod
command
;
pub
use
command
::
FlowModCommand
;
...
...
@@ -11,3 +12,4 @@ pub use flow_actions_type::FlowActionType;
pub
mod
match_fields
;
pub
use
match_fields
::{
Mask
,
MatchFields
};
src/openflow/events/hello.rs
0 → 100644
View file @
282cba84
use
crate
::
openflow
::{
trait_marshal
::
MessageMarshal
,
OfpMsg
};
pub
struct
HelloEvent
{}
impl
HelloEvent
{
pub
fn
new
()
->
Self
{
HelloEvent
{}
}
}
impl
MessageMarshal
for
HelloEvent
{
fn
marshal
(
&
self
,
_
:
&
mut
Vec
<
u8
>
)
{}
fn
msg_code
(
&
self
)
->
crate
::
openflow
::
OfpMsg
{
OfpMsg
::
Hello
}
fn
size_of
(
&
self
)
->
usize
{
0
}
}
src/openflow/events/mod.rs
View file @
282cba84
...
...
@@ -2,4 +2,10 @@ pub mod packet_in;
pub
use
packet_in
::{
PacketInEvent
,
PacketInReason
};
pub
mod
flow_mod
;
pub
use
flow_mod
::{
FlowAction
,
FlowModEvent
};
pub
mod
hello
;
pub
use
hello
::
HelloEvent
;
pub
mod
features_req
;
pub
use
features_req
::
FeaturesReq
;
\ No newline at end of file
src/openflow/header.rs
View file @
282cba84
...
...
@@ -17,7 +17,7 @@ impl OfpHeader {
Self
{
version
,
message
,
length
,
length
:
length
+
8
,
xid
,
}
}
...
...
src/openflow/message.rs
View file @
282cba84
pub
enum
Msg
{
Hello
,
PacketIn
,
NotFound
,
pub
enum
OfpMsg
{
Hello
=
0
,
FeaturesReq
=
5
,
PacketIn
=
8
,
FlowMod
=
14
,
NotFound
=
-
1
,
}
impl
Msg
{
impl
Ofp
Msg
{
pub
fn
parse
(
message_code
:
u8
)
->
Self
{
match
message_code
{
0
=>
Msg
::
Hello
,
8
=>
Msg
::
PacketIn
,
_
=>
Msg
::
NotFound
,
0
=>
Ofp
Msg
::
Hello
,
8
=>
Ofp
Msg
::
PacketIn
,
_
=>
Ofp
Msg
::
NotFound
,
}
}
}
src/openflow/mod.rs
View file @
282cba84
...
...
@@ -2,7 +2,7 @@ pub mod header;
pub
use
header
::
OfpHeader
;
pub
mod
message
;
pub
use
message
::
Msg
;
pub
use
message
::
Ofp
Msg
;
pub
mod
controller
;
pub
use
controller
::
Controller
;
...
...
@@ -10,4 +10,6 @@ pub use controller::Controller;
pub
mod
events
;
pub
mod
ofp_port
;
pub
use
ofp_port
::{
OfpPort
,
PseudoPort
};
\ No newline at end of file
pub
use
ofp_port
::{
OfpPort
,
PseudoPort
};
pub
mod
trait_marshal
;
\ No newline at end of file
src/openflow/ofp_port.rs
View file @
282cba84
...
...
@@ -68,3 +68,19 @@ impl PseudoPort {
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
port
);
}
}
impl
Clone
for
PseudoPort
{
fn
clone
(
&
self
)
->
Self
{
match
self
{
Self
::
PhysicalPort
(
arg0
)
=>
Self
::
PhysicalPort
(
arg0
.clone
()),
Self
::
InPort
=>
Self
::
InPort
,
Self
::
Table
=>
Self
::
Table
,
Self
::
Normal
=>
Self
::
Normal
,
Self
::
Flood
=>
Self
::
Flood
,
Self
::
AllPorts
=>
Self
::
AllPorts
,
Self
::
Controller
(
arg0
)
=>
Self
::
Controller
(
arg0
.clone
()),
Self
::
Local
=>
Self
::
Local
,
Self
::
Unsupport
=>
Self
::
Unsupport
,
}
}
}
\ No newline at end of file
src/openflow/trait_marshal.rs
0 → 100644
View file @
282cba84
use
super
::
OfpMsg
;
/**
* the trait for parse value to bytes.
* for use with Controller's send_msg.
*/
pub
trait
MessageMarshal
{
fn
marshal
(
&
self
,
bytes
:
&
mut
Vec
<
u8
>
);
fn
msg_code
(
&
self
)
->
OfpMsg
;
fn
size_of
(
&
self
)
->
usize
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment