Commit 54a476c1 authored by Nawasan Wisitsingkhon's avatar Nawasan Wisitsingkhon

fix match field, actions, and packet_in

parent 746c46b8
...@@ -38,15 +38,7 @@ impl ControllerFrame13 for Controller13 { ...@@ -38,15 +38,7 @@ impl ControllerFrame13 for Controller13 {
) { ) {
let matchs = MatchFields::match_all(); let matchs = MatchFields::match_all();
let actions = vec![Action::Oputput(ofp13::PseudoPort::Controller(!0))]; let actions = vec![Action::Oputput(ofp13::PseudoPort::Controller(!0))];
self.add_flow( self.add_flow(xid, 0, matchs, &actions, 0, None, stream)
xid,
0,
matchs,
&actions,
features_reply.n_tables,
Some(features_reply.n_buffers),
stream,
)
} }
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 pkt = match packetin.ether_parse() { let pkt = match packetin.ether_parse() {
......
...@@ -101,31 +101,31 @@ impl SetField { ...@@ -101,31 +101,31 @@ impl SetField {
pub fn marshal(&self, bytes: &mut Vec<u8>) { pub fn marshal(&self, bytes: &mut Vec<u8>) {
match &self { match &self {
SetField::InPort(port) => { SetField::InPort(port) => {
OxmHeader::new(OxmMatchFields::ActsetOutput, 4).marshal(bytes); OxmHeader::new(OxmMatchFields::InPort, 4).marshal(bytes);
port.marshal(bytes); port.marshal(bytes);
} }
SetField::EthDst(mac) => { SetField::EthDst(mac) => {
OxmHeader::new(OxmMatchFields::MacDest, 6).marshal(bytes); OxmHeader::new(OxmMatchFields::EthDst, 6).marshal(bytes);
mac.marshal(bytes); mac.marshal(bytes);
} }
SetField::EthSrc(mac) => { SetField::EthSrc(mac) => {
OxmHeader::new(OxmMatchFields::MacSrc, 6); OxmHeader::new(OxmMatchFields::EthSrc, 6);
mac.marshal(bytes); mac.marshal(bytes);
} }
SetField::EthTyp(eth) => { SetField::EthTyp(eth) => {
OxmHeader::new(OxmMatchFields::EthernetType, 2).marshal(bytes); OxmHeader::new(OxmMatchFields::EthType, 2).marshal(bytes);
bytes.write_u16::<BigEndian>(*eth); bytes.write_u16::<BigEndian>(*eth);
} }
SetField::IpProto(proto) => { SetField::IpProto(proto) => {
OxmHeader::new(OxmMatchFields::Protocol, 1).marshal(bytes); OxmHeader::new(OxmMatchFields::IpProto, 1).marshal(bytes);
bytes.write_u8(*proto); bytes.write_u8(*proto);
} }
SetField::Ipv4Src(ipv4) => { SetField::Ipv4Src(ipv4) => {
OxmHeader::new(OxmMatchFields::IpSrc, 4).marshal(bytes); OxmHeader::new(OxmMatchFields::Ipv4Src, 4).marshal(bytes);
bytes.write_u32::<BigEndian>(ipv4.clone().into()); bytes.write_u32::<BigEndian>(ipv4.clone().into());
} }
SetField::Ipv4Dst(ipv4) => { SetField::Ipv4Dst(ipv4) => {
OxmHeader::new(OxmMatchFields::IpDst, 4).marshal(bytes); OxmHeader::new(OxmMatchFields::Ipv4Dst, 4).marshal(bytes);
bytes.write_u32::<BigEndian>(ipv4.clone().into()); bytes.write_u32::<BigEndian>(ipv4.clone().into());
} }
SetField::Ipv6Src(ipv6) => { SetField::Ipv6Src(ipv6) => {
......
...@@ -87,7 +87,6 @@ impl MessageMarshal for FlowModEvent { ...@@ -87,7 +87,6 @@ impl MessageMarshal for FlowModEvent {
Msg::FlowMod Msg::FlowMod
} }
fn marshal(&self, bytes: &mut Vec<u8>) { fn marshal(&self, bytes: &mut Vec<u8>) {
self.match_fields.marshal(bytes);
let _ = bytes.write_u64::<BigEndian>(self.cookie); let _ = bytes.write_u64::<BigEndian>(self.cookie);
let _ = bytes.write_u64::<BigEndian>(self.cookie_mask); let _ = bytes.write_u64::<BigEndian>(self.cookie_mask);
let _ = bytes.write_u8(self.table_id); let _ = bytes.write_u8(self.table_id);
......
...@@ -25,7 +25,7 @@ pub struct OfpMatch { ...@@ -25,7 +25,7 @@ pub struct OfpMatch {
impl OfpMatch { impl OfpMatch {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
typ: MatchType::Standard, typ: MatchType::OXM,
length: 4, length: 4,
oxm_fields: Vec::new(), oxm_fields: Vec::new(),
} }
...@@ -45,6 +45,15 @@ pub enum MatchType { ...@@ -45,6 +45,15 @@ pub enum MatchType {
OXM = 1, //, the OpenFlow 1.1 match type OFPMT_STANDARD is deprecated OXM = 1, //, the OpenFlow 1.1 match type OFPMT_STANDARD is deprecated
} }
impl From<u16> for MatchType {
fn from(value: u16) -> Self {
match value {
0 => Self::Standard,
_ => Self::OXM,
}
}
}
impl From<MatchType> for u16 { impl From<MatchType> for u16 {
fn from(value: MatchType) -> Self { fn from(value: MatchType) -> Self {
value as u16 value as u16
...@@ -114,52 +123,47 @@ impl From<OxmClass> for u16 { ...@@ -114,52 +123,47 @@ impl From<OxmClass> for u16 {
#[repr(u8)] #[repr(u8)]
/* OXM Flow match field types for OpenFlow basic class. */ /* OXM Flow match field types for OpenFlow basic class. */
pub enum OxmMatchFields { pub enum OxmMatchFields {
InPort = 1, InPort = 0, /* Switch input port. */
InPhyPort = 2, InPhyPort = 1, /* Switch physical input port. */
Metadata = 3, METADATA = 2, /* Metadata passed between tables. */
MacDest = 4, EthDst = 3, /* Ethernet destination address. */
MacSrc = 5, EthSrc = 4, /* Ethernet source address. */
EthernetType = 6, EthType = 5, /* Ethernet frame type. */
VlanVid = 7, // vlan type VlanVid = 6, /* VLAN id. */
VlanPcp = 8, VlanPcp = 7, /* VLAN priority. */
// ToS from IPv4 packet IpDscp = 8, /* IP DSCP (6 bits in ToS field). */
IpDscp = 9, // IP DSCP (6 bits in ToS field). IpEcn = 9, /* IP ECN (2 bits in ToS field). */
IpEcn = 10, // IP ECN (2 bits in ToS field). IpProto = 10, /* IP protocol. */
Protocol = 11, Ipv4Src = 11, /* IPv4 source address. */
IpSrc = 12, Ipv4Dst = 12, /* IPv4 destination address. */
IpDst = 13, TcpSrc = 13, /* TCP source port. */
TcpDst = 14, /* TCP destination port. */
TcpSrc = 14, UdpSrc = 15, /* UDP source port. */
TcpDst = 15, UdpDst = 16, /* UDP destination port. */
UdpSrc = 16, SctpSrc = 17, /* SCTP source port. */
UdpDst = 17, SctpDst = 18, /* SCTP destination port. */
SctpSrc = 18, Icmpv4Type = 19, /* ICMP type. */
SctpDst = 19, Icmpv4Code = 20, /* ICMP code. */
ArpOp = 21, /* ARP opcode. */
Icmpv4Type = 20, ArpSpa = 22, /* ARP source IPv4 address. */
Icmpv4Code = 21, ArpTpa = 23, /* ARP target IPv4 address. */
ArpOp = 22, ArpSha = 24, /* ARP source hardware address. */
ArpSpa = 23, // ARP source IPv4 address ArpTha = 25, /* ARP target hardware address. */
ArpTpa = 24, // ARP target IPv4 address Ipv6Src = 26, /* IPv6 source address. */
ArpSha = 25, // ARP source Mac Ipv6Dst = 27, /* IPv6 destination address. */
ArpPha = 26, // ARP target Mac Ipv6Flabel = 28, /* IPv6 Flow Label */
Ipv6Src = 27, // IPv6 address Icmpv6Type = 29, /* ICMPv6 type. */
Ipv6Dst = 28, // IPv6 address Icmpv6Code = 30, /* ICMPv6 code. */
Ipv6Flabel = 29, // IPv6 Flow Lable Ipv6NdTarget = 31, /* Target address for ND. */
Icmpv6Type = 30, // ICMPv6 type Ipv6NdSll = 32, /* Source link-layer for ND. */
Icmpv6Code = 31, // ICMPv6 code Ipv6NdTll = 33, /* Target link-layer for ND. */
Ipv6NdTarget = 32, // Target address for ND MplsLabel = 34, /* MPLS label. */
Ipv6NdSll = 33, // MAC , source link-layer for ND MplsTc = 35, /* MPLS TC. */
Ipv6NdTll = 34, // Mac , Target link-layer for ND MplsBos = 36, /* MPLS BoS bit. */
MplsLabel = 35, // MPLS label PbbIsid = 37, /* PBB I-SID. */
MplsTc = 36, // MPLS TC TunnelId = 38, /* Logical Port Metadata. */
MplsBos = 37, // MPLS Bos bit Ipv6Exthdr = 39, /* IPv6 Extension Header pseudo-field */
PbbIsid = 38, // 24bit PBB I-SID Unparse,
TunnelId = 39, // Logical Port Metadata
Ipv6Exthdr = 40, // IPv6 Extension Header pseudo-field
PbbUca = 41, // PBB UCA Header
TcpFlags = 42, // TCP Flags
ActsetOutput = 43, // Output port from action set metadata
} }
impl From<u8> for OxmMatchFields { impl From<u8> for OxmMatchFields {
...@@ -167,7 +171,7 @@ impl From<u8> for OxmMatchFields { ...@@ -167,7 +171,7 @@ impl From<u8> for OxmMatchFields {
if value < 44 { if value < 44 {
unsafe { transmute(value) } unsafe { transmute(value) }
} else { } else {
Self::ActsetOutput Self::Unparse
} }
} }
} }
...@@ -223,29 +227,29 @@ impl MatchFields { ...@@ -223,29 +227,29 @@ impl MatchFields {
ofp_byte.write_u32::<BigEndian>(*in_port); ofp_byte.write_u32::<BigEndian>(*in_port);
} }
if let Some(eth_dst) = &self.eth_dst { if let Some(eth_dst) = &self.eth_dst {
let header = OxmHeader::new(OxmMatchFields::MacDest, 6); let header = OxmHeader::new(OxmMatchFields::EthDst, 6);
header.marshal(ofp_byte); header.marshal(ofp_byte);
eth_dst.marshal(ofp_byte); eth_dst.marshal(ofp_byte);
} }
if let Some(eth_src) = &self.eth_src { if let Some(eth_src) = &self.eth_src {
let header = OxmHeader::new(OxmMatchFields::MacSrc, 6); let header = OxmHeader::new(OxmMatchFields::EthSrc, 6);
header.marshal(ofp_byte); header.marshal(ofp_byte);
eth_src.marshal(ofp_byte); eth_src.marshal(ofp_byte);
} }
if let Some(eth_typ) = &self.eth_typ { if let Some(eth_typ) = &self.eth_typ {
OxmHeader::new(OxmMatchFields::EthernetType, 2).marshal(ofp_byte); OxmHeader::new(OxmMatchFields::EthType, 2).marshal(ofp_byte);
ofp_byte.write_u16::<BigEndian>(*eth_typ); ofp_byte.write_u16::<BigEndian>(*eth_typ);
} }
if let Some(ip_proto) = &self.ip_proto { if let Some(ip_proto) = &self.ip_proto {
OxmHeader::new(OxmMatchFields::Protocol, 1); OxmHeader::new(OxmMatchFields::IpProto, 1);
ofp_byte.write_u8(*ip_proto); ofp_byte.write_u8(*ip_proto);
} }
if let Some(ipv4_src) = &self.ipv4_src { if let Some(ipv4_src) = &self.ipv4_src {
OxmHeader::new(OxmMatchFields::IpSrc, 4).marshal(ofp_byte); OxmHeader::new(OxmMatchFields::Ipv4Src, 4).marshal(ofp_byte);
bytes.write_u32::<BigEndian>(ipv4_src.clone().into()); bytes.write_u32::<BigEndian>(ipv4_src.clone().into());
} }
if let Some(ipv4_dst) = &self.ipv4_dst { if let Some(ipv4_dst) = &self.ipv4_dst {
OxmHeader::new(OxmMatchFields::IpDst, 4).marshal(ofp_byte); OxmHeader::new(OxmMatchFields::Ipv4Dst, 4).marshal(ofp_byte);
bytes.write_u32::<BigEndian>(ipv4_dst.clone().into()); bytes.write_u32::<BigEndian>(ipv4_dst.clone().into());
} }
if let Some(ipv6_src) = &self.ipv6_src { if let Some(ipv6_src) = &self.ipv6_src {
...@@ -278,7 +282,7 @@ impl MatchFields { ...@@ -278,7 +282,7 @@ impl MatchFields {
pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Result<MatchFields, Error> { pub fn parse(bytes: &mut Cursor<Vec<u8>>) -> Result<MatchFields, Error> {
let mut matcher = MatchFields::match_all(); let mut matcher = MatchFields::match_all();
let typ = bytes.read_u16::<BigEndian>()?; let typ: MatchType = bytes.read_u16::<BigEndian>()?.into();
let length = bytes.read_u16::<BigEndian>()?; let length = bytes.read_u16::<BigEndian>()?;
let mut pkt_len = length - 4; let mut pkt_len = length - 4;
while pkt_len > 0 { while pkt_len > 0 {
...@@ -297,7 +301,7 @@ impl MatchFields { ...@@ -297,7 +301,7 @@ impl MatchFields {
}; };
matcher.in_port = Some(port); matcher.in_port = Some(port);
} }
OxmMatchFields::MacDest => { OxmMatchFields::EthDst => {
let mut mac = [0u8; 6]; let mut mac = [0u8; 6];
for i in 0..6 { for i in 0..6 {
mac[i] = bytes.read_u8()?; mac[i] = bytes.read_u8()?;
...@@ -307,7 +311,7 @@ impl MatchFields { ...@@ -307,7 +311,7 @@ impl MatchFields {
} }
matcher.eth_dst = Some(MacAddr::new(mac)); matcher.eth_dst = Some(MacAddr::new(mac));
} }
OxmMatchFields::MacSrc => { OxmMatchFields::EthSrc => {
let mut mac = [0u8; 6]; let mut mac = [0u8; 6];
for i in 0..6 { for i in 0..6 {
mac[i] = bytes.read_u8()?; mac[i] = bytes.read_u8()?;
...@@ -317,28 +321,28 @@ impl MatchFields { ...@@ -317,28 +321,28 @@ impl MatchFields {
} }
matcher.eth_src = Some(MacAddr::new(mac)); matcher.eth_src = Some(MacAddr::new(mac));
} }
OxmMatchFields::EthernetType => { OxmMatchFields::EthType => {
let eth_typ = bytes.read_u16::<BigEndian>()?; let eth_typ = bytes.read_u16::<BigEndian>()?;
if hash_mask { if hash_mask {
bytes.consume(2); bytes.consume(2);
} }
matcher.eth_typ = Some(eth_typ); matcher.eth_typ = Some(eth_typ);
} }
OxmMatchFields::Protocol => { OxmMatchFields::IpProto => {
let proto = bytes.read_u8()?; let proto = bytes.read_u8()?;
if hash_mask { if hash_mask {
bytes.consume(1); bytes.consume(1);
} }
matcher.ip_proto = Some(proto); matcher.ip_proto = Some(proto);
} }
OxmMatchFields::IpSrc => { OxmMatchFields::Ipv4Src => {
let ip = bytes.read_u32::<BigEndian>()?; let ip = bytes.read_u32::<BigEndian>()?;
if hash_mask { if hash_mask {
bytes.consume(4); bytes.consume(4);
} }
matcher.ipv4_src = Some(Ipv4Addr::from(ip)); matcher.ipv4_src = Some(Ipv4Addr::from(ip));
} }
OxmMatchFields::IpDst => { OxmMatchFields::Ipv4Dst => {
let ip = bytes.read_u32::<BigEndian>()?; let ip = bytes.read_u32::<BigEndian>()?;
if hash_mask { if hash_mask {
bytes.consume(4); bytes.consume(4);
...@@ -389,12 +393,15 @@ impl MatchFields { ...@@ -389,12 +393,15 @@ impl MatchFields {
} }
_ => { _ => {
bytes.consume((oxm_length - 4).into()); bytes.consume((oxm_length - 4) as usize);
} }
} }
pkt_len = pkt_len - (oxm_length as u16); // 4 is size of oxm_tlv_header
pkt_len = pkt_len - (oxm_length as u16 + 4);
}
if length % 8 != 0 {
bytes.consume(4);
} }
Ok(matcher) Ok(matcher)
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment