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
8d6b00b8
Commit
8d6b00b8
authored
May 04, 2024
by
Nawasan Wisitsingkhon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add flowMod
parent
d904d5c7
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
701 additions
and
4 deletions
+701
-4
bits.rs
src/etherparser/tools/bits.rs
+33
-2
command.rs
src/openflow/events/flow_mod/command.rs
+21
-0
flow_actions.rs
src/openflow/events/flow_mod/flow_actions.rs
+203
-0
flow_actions_type.rs
src/openflow/events/flow_mod/flow_actions_type.rs
+19
-0
flow_mod_handler.rs
src/openflow/events/flow_mod/flow_mod_handler.rs
+124
-0
match_fields.rs
src/openflow/events/flow_mod/match_fields.rs
+210
-0
mod.rs
src/openflow/events/flow_mod/mod.rs
+13
-0
mod.rs
src/openflow/events/mod.rs
+3
-0
mod.rs
src/openflow/mod.rs
+5
-2
ofp_port.rs
src/openflow/ofp_port.rs
+70
-0
No files found.
src/etherparser/tools/bits.rs
View file @
8d6b00b8
pub
fn
bit_bool
(
position
:
u16
,
byte
:
u16
)
->
bool
{
pub
trait
NumberTrait
{
(
byte
>>
position
)
&
1
==
1
fn
get_value
(
&
self
)
->
u32
;
}
impl
NumberTrait
for
u32
{
fn
get_value
(
&
self
)
->
u32
{
*
self
as
u32
}
}
impl
NumberTrait
for
u16
{
fn
get_value
(
&
self
)
->
u32
{
*
self
as
u32
}
}
pub
fn
bit_bool
<
T
:
NumberTrait
>
(
position
:
u16
,
byte
:
T
)
->
bool
{
(
byte
.get_value
()
>>
position
)
&
1
==
1
}
pub
fn
set_bit
(
byte
:
u32
,
position
:
u32
,
set
:
bool
)
->
u32
{
if
set
{
byte
|
(
1
<<
position
)
}
else
{
byte
&
!
(
1
<<
position
)
}
}
}
pub
fn
mac_to_bytes
(
byte
:
[
u8
;
6
])
->
u64
{
pub
fn
mac_to_bytes
(
byte
:
[
u8
;
6
])
->
u64
{
...
@@ -9,3 +32,11 @@ pub fn mac_to_bytes(byte: [u8; 6]) -> u64 {
...
@@ -9,3 +32,11 @@ pub fn mac_to_bytes(byte: [u8; 6]) -> u64 {
}
}
u64
::
from_be_bytes
(
addr
)
u64
::
from_be_bytes
(
addr
)
}
}
pub
fn
bytes_to_mac
(
bytes
:
u64
)
->
[
u8
;
6
]
{
let
mut
address
=
[
0
;
6
];
for
i
in
0
..
6
{
address
[
i
]
=
((
bytes
>>
(
8
*
i
))
&
0xff
)
as
u8
;
}
address
}
src/openflow/events/flow_mod/command.rs
0 → 100644
View file @
8d6b00b8
pub
enum
FlowModCommand
{
Add
,
Modify
,
ModifyStrict
,
Delete
,
DeleteStrict
,
Unparsable
,
}
impl
FlowModCommand
{
pub
fn
parse
(
byte
:
u16
)
->
Self
{
match
byte
{
0
=>
Self
::
Add
,
1
=>
Self
::
Modify
,
2
=>
Self
::
ModifyStrict
,
3
=>
Self
::
Delete
,
4
=>
Self
::
DeleteStrict
,
_
=>
Self
::
Unparsable
,
}
}
}
src/openflow/events/flow_mod/flow_actions.rs
0 → 100644
View file @
8d6b00b8
use
std
::{
io
::{
BufRead
,
Cursor
},
mem
::
size_of
,
};
use
byteorder
::{
BigEndian
,
ReadBytesExt
,
WriteBytesExt
};
use
crate
::{
etherparser
::
tools
::
bits
::{
bytes_to_mac
,
mac_to_bytes
},
openflow
::
PseudoPort
,
};
use
super
::
flow_actions_type
::
FlowActionType
;
pub
enum
FlowAction
{
Oputput
(
PseudoPort
),
SetDlVlan
(
Option
<
u16
>
),
SetDlVlanPcp
(
u8
),
SetDlSrc
(
u64
),
SetDlDest
(
u64
),
SetIpSrc
(
u32
),
SetIpDes
(
u32
),
SetTos
(
u8
),
SetTpSrc
(
u16
),
SetTpDest
(
u16
),
Enqueue
(
PseudoPort
,
u32
),
Unparsable
,
}
impl
FlowAction
{
pub
fn
to_action_code
(
&
self
)
->
FlowActionType
{
match
self
{
FlowAction
::
Oputput
(
_
)
=>
FlowActionType
::
Output
,
FlowAction
::
SetDlVlan
(
_
)
=>
FlowActionType
::
SetVlanId
,
FlowAction
::
SetDlVlanPcp
(
_
)
=>
FlowActionType
::
SetVlanPCP
,
FlowAction
::
SetDlSrc
(
_
)
=>
FlowActionType
::
SetSrcMac
,
FlowAction
::
SetDlDest
(
_
)
=>
FlowActionType
::
SetDstMac
,
FlowAction
::
SetIpSrc
(
_
)
=>
FlowActionType
::
SetIPv4Src
,
FlowAction
::
SetIpDes
(
_
)
=>
FlowActionType
::
SetIPv4Des
,
FlowAction
::
SetTos
(
_
)
=>
FlowActionType
::
SetTos
,
FlowAction
::
SetTpSrc
(
_
)
=>
FlowActionType
::
SetTpSrc
,
FlowAction
::
SetTpDest
(
_
)
=>
FlowActionType
::
SetTpDst
,
FlowAction
::
Enqueue
(
_
,
_
)
=>
FlowActionType
::
Enqueue
,
FlowAction
::
Unparsable
=>
panic!
(
"Unparse FlowAction to FlowActionType"
),
}
}
pub
fn
length
(
&
self
)
->
usize
{
let
header
=
size_of
::
<
(
u16
,
u16
)
>
();
let
body
=
match
self
{
FlowAction
::
Oputput
(
_
)
=>
size_of
::
<
(
u16
,
u16
)
>
(),
FlowAction
::
SetDlVlan
(
_
)
=>
size_of
::
<
(
u16
,
u16
)
>
(),
FlowAction
::
SetDlVlanPcp
(
_
)
=>
size_of
::
<
(
u8
,
[
u8
;
3
])
>
(),
FlowAction
::
SetDlSrc
(
_
)
=>
size_of
::
<
([
u8
;
6
],
[
u8
;
6
])
>
(),
FlowAction
::
SetDlDest
(
_
)
=>
size_of
::
<
([
u8
;
6
],
[
u8
;
6
])
>
(),
FlowAction
::
SetIpSrc
(
_
)
=>
size_of
::
<
u32
>
(),
FlowAction
::
SetIpDes
(
_
)
=>
size_of
::
<
u32
>
(),
FlowAction
::
SetTos
(
_
)
=>
size_of
::
<
(
u8
,
[
u8
;
3
])
>
(),
FlowAction
::
SetTpSrc
(
_
)
=>
size_of
::
<
(
u16
,
u16
)
>
(),
FlowAction
::
SetTpDest
(
_
)
=>
size_of
::
<
(
u16
,
u16
)
>
(),
FlowAction
::
Enqueue
(
_
,
_
)
=>
size_of
::
<
(
u16
,
[
u8
;
6
],
u32
)
>
(),
FlowAction
::
Unparsable
=>
0
,
};
header
+
body
}
pub
fn
marshal
(
&
self
,
bytes
:
&
mut
Vec
<
u8
>
)
{
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
self
.to_action_code
()
as
u16
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
self
.length
()
as
u16
);
match
self
{
FlowAction
::
Oputput
(
pseudo
)
=>
{
pseudo
.marshal
(
bytes
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
match
pseudo
{
PseudoPort
::
Controller
(
w
)
=>
*
w
as
u16
,
_
=>
0
,
});
}
FlowAction
::
SetDlVlan
(
None
)
=>
{
let
_
=
bytes
.write_u32
::
<
BigEndian
>
(
0xffff
);
}
FlowAction
::
SetDlVlan
(
Some
(
vid
))
=>
{
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
*
vid
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
0
);
}
FlowAction
::
SetDlVlanPcp
(
pcp
)
=>
{
let
_
=
bytes
.write_u8
(
*
pcp
);
for
_
in
0
..
3
{
let
_
=
bytes
.write_u8
(
0
);
}
}
FlowAction
::
SetDlSrc
(
mac
)
|
FlowAction
::
SetDlDest
(
mac
)
=>
{
let
mac
=
bytes_to_mac
(
*
mac
);
for
m
in
mac
{
let
_
=
bytes
.write_u8
(
m
);
}
for
_
in
0
..
6
{
let
_
=
bytes
.write_u8
(
0
);
}
}
FlowAction
::
SetIpSrc
(
address
)
|
FlowAction
::
SetIpDes
(
address
)
=>
{
let
_
=
bytes
.write_u32
::
<
BigEndian
>
(
*
address
);
}
FlowAction
::
SetTos
(
n
)
=>
{
let
_
=
bytes
.write_u8
(
*
n
);
}
FlowAction
::
SetTpSrc
(
pt
)
|
FlowAction
::
SetTpDest
(
pt
)
=>
{
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
*
pt
);
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
0
);
}
FlowAction
::
Enqueue
(
pp
,
qid
)
=>
{
pp
.marshal
(
bytes
);
for
_
in
0
..
6
{
let
_
=
bytes
.write_u8
(
0
);
}
let
_
=
bytes
.write_u32
::
<
BigEndian
>
(
*
qid
);
}
FlowAction
::
Unparsable
=>
todo!
(),
}
}
pub
fn
parse_sequence
(
bytes
:
&
mut
Cursor
<
Vec
<
u8
>>
)
->
Vec
<
FlowAction
>
{
if
bytes
.get_ref
()
.is_empty
()
{
vec!
[]
}
else
{
let
action
=
FlowAction
::
parse
(
bytes
);
let
mut
v
=
vec!
[
action
];
v
.append
(
&
mut
FlowAction
::
parse_sequence
(
bytes
));
v
}
}
pub
fn
parse
(
bytes
:
&
mut
Cursor
<
Vec
<
u8
>>
)
->
FlowAction
{
let
action_code
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
let
_
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
match
action_code
{
t
if
t
==
(
FlowActionType
::
Output
as
u16
)
=>
{
let
port_code
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
let
len
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
FlowAction
::
Oputput
(
PseudoPort
::
new
(
port_code
,
Some
(
len
as
u64
)))
}
t
if
t
==
(
FlowActionType
::
SetVlanId
as
u16
)
=>
{
let
vid
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
bytes
.consume
(
2
);
if
vid
==
0xffff
{
FlowAction
::
SetDlVlan
(
None
)
}
else
{
FlowAction
::
SetDlVlan
(
Some
(
vid
))
}
}
t
if
t
==
(
FlowActionType
::
SetVlanPCP
as
u16
)
=>
{
let
pcp
=
bytes
.read_u8
()
.unwrap
();
bytes
.consume
(
3
);
FlowAction
::
SetDlVlanPcp
(
pcp
)
}
t
if
t
==
(
FlowActionType
::
StripVlan
as
u16
)
=>
{
bytes
.consume
(
4
);
FlowAction
::
SetDlVlan
(
None
)
}
t
if
t
==
(
FlowActionType
::
SetSrcMac
as
u16
)
=>
{
let
mut
addr
=
[
0u8
;
6
];
for
i
in
0
..
6
{
addr
[
i
]
=
bytes
.read_u8
()
.unwrap
();
}
bytes
.consume
(
6
);
FlowAction
::
SetDlSrc
(
mac_to_bytes
(
addr
))
}
t
if
t
==
(
FlowActionType
::
SetDstMac
as
u16
)
=>
{
let
mut
addr
=
[
0u8
;
6
];
for
i
in
0
..
6
{
addr
[
i
]
=
bytes
.read_u8
()
.unwrap
();
}
bytes
.consume
(
6
);
FlowAction
::
SetDlDest
(
mac_to_bytes
(
addr
))
}
t
if
t
==
(
FlowActionType
::
SetIPv4Src
as
u16
)
=>
{
FlowAction
::
SetIpSrc
(
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
())
}
t
if
t
==
(
FlowActionType
::
SetIPv4Des
as
u16
)
=>
{
FlowAction
::
SetIpDes
(
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
())
}
t
if
t
==
(
FlowActionType
::
SetTos
as
u16
)
=>
{
let
tos
=
bytes
.read_u8
()
.unwrap
();
bytes
.consume
(
3
);
FlowAction
::
SetTos
(
tos
)
}
t
if
t
==
(
FlowActionType
::
SetTpSrc
as
u16
)
=>
{
let
pt
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
bytes
.consume
(
2
);
FlowAction
::
SetTpSrc
(
pt
)
}
t
if
t
==
(
FlowActionType
::
SetTpDst
as
u16
)
=>
{
let
pt
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
bytes
.consume
(
2
);
FlowAction
::
SetTpDest
(
pt
)
}
t
if
t
==
(
FlowActionType
::
Enqueue
as
u16
)
=>
{
let
pt
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
bytes
.consume
(
6
);
let
qid
=
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
();
FlowAction
::
Enqueue
(
PseudoPort
::
new
(
pt
,
Some
(
0
)),
qid
)
}
_
=>
FlowAction
::
Unparsable
,
}
}
}
src/openflow/events/flow_mod/flow_actions_type.rs
0 → 100644
View file @
8d6b00b8
/*
* it don't need to assign vlue.
* but I think I should assign for reading.
*/
pub
enum
FlowActionType
{
Output
=
0
,
SetVlanId
=
1
,
SetVlanPCP
=
2
,
StripVlan
=
3
,
SetSrcMac
=
4
,
SetDstMac
=
5
,
SetIPv4Src
=
6
,
SetIPv4Des
=
7
,
SetTos
=
8
,
SetTpSrc
=
9
,
SetTpDst
=
10
,
Enqueue
=
11
,
}
\ No newline at end of file
src/openflow/events/flow_mod/flow_mod_handler.rs
0 → 100644
View file @
8d6b00b8
use
std
::
io
::
Cursor
;
use
byteorder
::{
BigEndian
,
ReadBytesExt
,
WriteBytesExt
};
use
crate
::
openflow
::{
OfpPort
,
PseudoPort
};
use
super
::{
FlowAction
,
FlowModCommand
,
MatchFields
};
pub
enum
Timeout
{
Permanent
,
ExpireAfter
(
u16
),
}
impl
Timeout
{
pub
fn
parse
(
tm
:
u16
)
->
Self
{
match
tm
{
0
=>
Self
::
Permanent
,
d
=>
Timeout
::
ExpireAfter
(
d
),
}
}
pub
fn
to_int
(
&
self
)
->
u16
{
match
self
{
Timeout
::
Permanent
=>
0
,
Timeout
::
ExpireAfter
(
d
)
=>
*
d
,
}
}
}
pub
struct
FlowMod
{
command
:
FlowModCommand
,
match_fields
:
MatchFields
,
priority
:
u16
,
actions
:
Vec
<
FlowAction
>
,
cookie
:
u64
,
idle_timeout
:
Timeout
,
hard_timeout
:
Timeout
,
notify_when_removed
:
bool
,
apply_to_packet
:
Option
<
u32
>
,
out_port
:
Option
<
PseudoPort
>
,
check_overlap
:
bool
,
}
impl
FlowMod
{
pub
fn
get_controller_last
(
actions
:
Vec
<
FlowAction
>
)
->
Vec
<
FlowAction
>
{
let
mut
not_ctrl
:
Vec
<
FlowAction
>
=
Vec
::
new
();
let
mut
is_ctrl
:
Vec
<
FlowAction
>
=
Vec
::
new
();
for
act
in
actions
{
match
act
{
FlowAction
::
Oputput
(
PseudoPort
::
Controller
(
_
))
=>
{
is_ctrl
.push
(
act
);
}
_
=>
not_ctrl
.push
(
act
),
}
}
not_ctrl
.append
(
&
mut
is_ctrl
);
not_ctrl
}
pub
fn
size_of
()
->
usize
{
24
}
pub
fn
parse
(
buf
:
&
[
u8
])
->
FlowMod
{
let
mut
bytes
=
Cursor
::
new
(
buf
.to_vec
());
let
match_fields
=
MatchFields
::
parse
(
&
mut
bytes
);
let
cookie
=
bytes
.read_u64
::
<
BigEndian
>
()
.unwrap
();
let
command
=
FlowModCommand
::
parse
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
());
let
idle_timeout
=
Timeout
::
parse
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
());
let
hard_timeout
=
Timeout
::
parse
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
());
let
priority
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
let
buffer_id
=
bytes
.read_i32
::
<
BigEndian
>
()
.unwrap
();
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
{
command
,
match_fields
,
cookie
,
actions
,
priority
,
idle_timeout
,
hard_timeout
,
notify_when_removed
:
flags
&
1
!=
0
,
apply_to_packet
:
{
match
buffer_id
{
-
1
=>
None
,
n
=>
Some
(
n
as
u32
),
}
},
out_port
,
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
{
None
=>
-
1
,
Some
(
buf_id
)
=>
buf_id
as
i32
,
});
match
flowmod
.out_port
{
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
}),
);
for
act
in
FlowMod
::
get_controller_last
(
flowmod
.actions
)
{
match
act
{
FlowAction
::
Oputput
(
PseudoPort
::
Table
)
=>
{
panic!
(
"Openflow table not allowed"
)
}
_
=>
(),
}
}
}
}
src/openflow/events/flow_mod/match_fields.rs
0 → 100644
View file @
8d6b00b8
use
std
::
io
::{
BufRead
,
Cursor
};
use
byteorder
::{
BigEndian
,
ReadBytesExt
,
WriteBytesExt
};
use
crate
::
etherparser
::
tools
::
bits
::{
bit_bool
,
mac_to_bytes
,
set_bit
};
pub
struct
Mask
<
T
>
{
pub
ip
:
T
,
pub
mask
:
Option
<
T
>
,
}
impl
Mask
<
u32
>
{
pub
fn
to_int
(
&
self
)
->
u32
{
match
self
.mask
{
Some
(
v
)
=>
v
,
None
=>
0
,
}
}
}
struct
Wildcards
{
pub
in_port
:
bool
,
pub
mac_dest
:
bool
,
pub
mac_src
:
bool
,
pub
ethernet_type
:
bool
,
pub
vlan_vid
:
bool
,
pub
vlan_pcp
:
bool
,
pub
ip_src
:
u32
,
pub
ip_dest
:
u32
,
pub
protocol
:
bool
,
pub
tos
:
bool
,
pub
transport_src
:
bool
,
pub
transport_dest
:
bool
,
}
impl
Wildcards
{
pub
fn
parse
(
byte
:
u32
)
->
Wildcards
{
Wildcards
{
in_port
:
bit_bool
(
0
,
byte
),
vlan_vid
:
bit_bool
(
1
,
byte
),
mac_src
:
bit_bool
(
2
,
byte
),
mac_dest
:
bit_bool
(
3
,
byte
),
ethernet_type
:
bit_bool
(
4
,
byte
),
protocol
:
bit_bool
(
5
,
byte
),
transport_src
:
bit_bool
(
6
,
byte
),
transport_dest
:
bit_bool
(
7
,
byte
),
ip_src
:
Wildcards
::
get_nw_mask
(
byte
,
8
),
ip_dest
:
Wildcards
::
get_nw_mask
(
byte
,
14
),
vlan_pcp
:
bit_bool
(
20
,
byte
),
tos
:
bit_bool
(
21
,
byte
),
}
}
pub
fn
get_nw_mask
(
f
:
u32
,
offset
:
usize
)
->
u32
{
(
f
>>
offset
)
&
0x3f
}
}
pub
struct
MatchFields
{
pub
in_port
:
Option
<
u16
>
,
pub
mac_dest
:
Option
<
u64
>
,
pub
mac_src
:
Option
<
u64
>
,
pub
ethernet_type
:
Option
<
u16
>
,
pub
vlan_vid
:
Option
<
u16
>
,
// vlan type
pub
vlan_pcp
:
Option
<
u8
>
,
pub
ip_src
:
Option
<
Mask
<
u32
>>
,
pub
ip_dest
:
Option
<
Mask
<
u32
>>
,
pub
protocol
:
Option
<
u8
>
,
pub
tos
:
Option
<
u8
>
,
pub
transport_src
:
Option
<
u16
>
,
pub
transport_dest
:
Option
<
u16
>
,
}
impl
MatchFields
{
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
());
match_f
=
set_bit
(
match_f
,
2
,
self
.mac_src
.is_some
());
match_f
=
set_bit
(
match_f
,
3
,
self
.mac_dest
.is_some
());
match_f
=
set_bit
(
match_f
,
4
,
self
.ethernet_type
.is_some
());
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
=
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
();
}
pub
fn
set_nw_mask
(
byte
:
u32
,
offset
:
usize
,
set
:
u32
)
->
u32
{
let
value
=
(
0x3f
&
set
)
<<
offset
;
byte
|
value
}
pub
fn
get_ns_mask
(
byte
:
u32
,
offset
:
usize
)
->
u32
{
(
byte
>>
offset
)
&
0x3f
}
pub
fn
parse
(
bytes
:
&
mut
Cursor
<
Vec
<
u8
>>
)
->
MatchFields
{
let
wildcards
=
Wildcards
::
parse
(
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
());
let
in_port
=
if
wildcards
.in_port
{
None
}
else
{
Some
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
())
};
let
mac_src
=
if
wildcards
.mac_src
{
None
}
else
{
let
mut
arr
:
[
u8
;
6
]
=
[
0
;
6
];
for
i
in
0
..
6
{
arr
[
i
]
=
bytes
.read_u8
()
.unwrap
();
}
Some
(
mac_to_bytes
(
arr
))
};
let
mac_dest
=
if
wildcards
.mac_dest
{
None
}
else
{
let
mut
arr
:
[
u8
;
6
]
=
[
0
;
6
];
for
i
in
0
..
6
{
arr
[
i
]
=
bytes
.read_u8
()
.unwrap
();
}
Some
(
mac_to_bytes
(
arr
))
};
let
vlan_vid
=
if
wildcards
.vlan_vid
{
None
}
else
{
let
vid
=
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
();
if
vid
==
0xfff
{
None
}
else
{
Some
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
())
}
};
let
vlan_pcp
=
if
wildcards
.vlan_pcp
{
None
}
else
{
Some
(
bytes
.read_u8
()
.unwrap
())
};
bytes
.consume
(
1
);
let
ethernet_type
=
if
wildcards
.ethernet_type
{
None
}
else
{
Some
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
())
};
let
tos
=
if
wildcards
.tos
{
None
}
else
{
Some
(
bytes
.read_u8
()
.unwrap
())
};
let
protocol
=
if
wildcards
.protocol
{
None
}
else
{
Some
(
bytes
.read_u8
()
.unwrap
())
};
bytes
.consume
(
2
);
let
ip_src
=
if
wildcards
.ip_src
>=
32
{
None
}
else
if
wildcards
.ip_src
==
0
{
Some
(
Mask
{
ip
:
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
(),
mask
:
None
,
})
}
else
{
Some
(
Mask
{
ip
:
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
(),
mask
:
Some
(
wildcards
.ip_src
),
})
};
let
ip_dest
=
if
wildcards
.ip_dest
>=
32
{
None
}
else
if
wildcards
.ip_dest
==
0
{
Some
(
Mask
{
ip
:
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
(),
mask
:
None
,
})
}
else
{
Some
(
Mask
{
ip
:
bytes
.read_u32
::
<
BigEndian
>
()
.unwrap
(),
mask
:
Some
(
wildcards
.ip_dest
),
})
};
let
transport_src
=
if
wildcards
.transport_src
{
None
}
else
{
Some
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
())
};
let
transport_dest
=
if
wildcards
.transport_dest
{
None
}
else
{
Some
(
bytes
.read_u16
::
<
BigEndian
>
()
.unwrap
())
};
MatchFields
{
in_port
,
mac_src
,
mac_dest
,
ethernet_type
,
vlan_vid
,
vlan_pcp
,
ip_src
,
ip_dest
,
protocol
,
tos
,
transport_src
,
transport_dest
,
}
}
}
src/openflow/events/flow_mod/mod.rs
0 → 100644
View file @
8d6b00b8
pub
mod
flow_mod_handler
;
pub
mod
command
;
pub
use
command
::
FlowModCommand
;
pub
mod
flow_actions
;
pub
use
flow_actions
::
FlowAction
;
pub
mod
flow_actions_type
;
pub
use
flow_actions_type
::
FlowActionType
;
pub
mod
match_fields
;
pub
use
match_fields
::{
Mask
,
MatchFields
};
src/openflow/events/mod.rs
View file @
8d6b00b8
pub
mod
packet_in
;
pub
mod
packet_in
;
pub
use
packet_in
::{
PacketInEvent
,
PacketInReason
};
pub
use
packet_in
::{
PacketInEvent
,
PacketInReason
};
pub
mod
flow_mod
;
src/openflow/mod.rs
View file @
8d6b00b8
...
@@ -7,4 +7,7 @@ pub use message::Msg;
...
@@ -7,4 +7,7 @@ pub use message::Msg;
pub
mod
controller
;
pub
mod
controller
;
pub
use
controller
::
Controller
;
pub
use
controller
::
Controller
;
pub
mod
events
;
pub
mod
events
;
\ No newline at end of file
pub
mod
ofp_port
;
pub
use
ofp_port
::{
OfpPort
,
PseudoPort
};
\ No newline at end of file
src/openflow/ofp_port.rs
0 → 100644
View file @
8d6b00b8
use
byteorder
::{
BigEndian
,
WriteBytesExt
};
pub
enum
OfpPort
{
Max
=
0xff00
,
InPort
=
0xfff8
,
Table
=
0xfff9
,
Normal
=
0xfffa
,
Flood
=
0xfffb
,
All
=
0xfffc
,
Controller
=
0xfffd
,
Local
=
0xfffe
,
None
=
0xffff
,
}
pub
enum
PseudoPort
{
PhysicalPort
(
u16
),
InPort
,
Table
,
Normal
,
Flood
,
AllPorts
,
Controller
(
u64
),
Local
,
Unsupport
,
}
impl
PseudoPort
{
pub
fn
parse
(
byte
:
u16
)
->
Option
<
PseudoPort
>
{
if
(
OfpPort
::
None
as
u16
)
==
byte
{
None
}
else
{
Some
(
PseudoPort
::
new
(
byte
,
Some
(
0
)))
}
}
pub
fn
new
(
port
:
u16
,
len
:
Option
<
u64
>
)
->
PseudoPort
{
match
port
{
p
if
p
==
(
OfpPort
::
InPort
as
u16
)
=>
PseudoPort
::
InPort
,
p
if
p
==
(
OfpPort
::
Table
as
u16
)
=>
PseudoPort
::
Table
,
p
if
p
==
(
OfpPort
::
Normal
as
u16
)
=>
PseudoPort
::
Normal
,
p
if
p
==
(
OfpPort
::
Flood
as
u16
)
=>
PseudoPort
::
Flood
,
p
if
p
==
(
OfpPort
::
All
as
u16
)
=>
PseudoPort
::
AllPorts
,
p
if
len
.is_some
()
&&
p
==
(
OfpPort
::
Controller
as
u16
)
=>
{
PseudoPort
::
Controller
(
len
.unwrap
())
}
p
if
p
==
(
OfpPort
::
Local
as
u16
)
=>
PseudoPort
::
InPort
,
_
=>
{
if
port
<=
(
OfpPort
::
Max
as
u16
)
{
PseudoPort
::
PhysicalPort
(
port
)
}
else
{
PseudoPort
::
Unsupport
}
}
}
}
pub
fn
marshal
(
&
self
,
bytes
:
&
mut
Vec
<
u8
>
)
{
let
port
=
match
*
self
{
PseudoPort
::
PhysicalPort
(
p
)
=>
p
,
PseudoPort
::
InPort
=>
OfpPort
::
InPort
as
u16
,
PseudoPort
::
Table
=>
OfpPort
::
Table
as
u16
,
PseudoPort
::
Normal
=>
OfpPort
::
Normal
as
u16
,
PseudoPort
::
Flood
=>
OfpPort
::
Flood
as
u16
,
PseudoPort
::
AllPorts
=>
OfpPort
::
All
as
u16
,
PseudoPort
::
Controller
(
_
)
=>
OfpPort
::
Controller
as
u16
,
PseudoPort
::
Local
=>
OfpPort
::
Local
as
u16
,
// not sure how to handle unsupport
PseudoPort
::
Unsupport
=>
OfpPort
::
Flood
as
u16
,
};
let
_
=
bytes
.write_u16
::
<
BigEndian
>
(
port
);
}
}
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