From 2631c577ce490807d2e09b697d814c826fd0591e Mon Sep 17 00:00:00 2001 From: weqe Date: Sat, 3 Aug 2024 00:11:04 +0300 Subject: [PATCH] vrrp: reorganize network calls & handle clippy errors The network calls have been modified in this commit. We have been making the network calls e.g send ARP, send VRRP advertisement etc directly from different files. The calls not send a message through the NetTxPacketMsg. Apart from efficiency, helped in making too many unnecessary functions async. Finally worked on cargo clippy recommendations which had been pending for a while and handled cargo fmt. Signed off by: Paul Wekesa --- holo-interface/src/ibus.rs | 2 +- holo-interface/src/interface.rs | 1 - holo-interface/src/netlink.rs | 19 +- holo-vrrp/src/debug.rs | 3 +- holo-vrrp/src/error.rs | 4 +- holo-vrrp/src/events.rs | 216 ++++++++++++++-------- holo-vrrp/src/instance.rs | 5 - holo-vrrp/src/interface.rs | 46 ++--- holo-vrrp/src/network.rs | 45 +++-- holo-vrrp/src/northbound/configuration.rs | 2 +- holo-vrrp/src/northbound/notification.rs | 2 +- holo-vrrp/src/packet.rs | 52 +++--- holo-vrrp/src/tasks.rs | 37 ++-- holo-vrrp/tests/conformance/mod.rs | 7 - holo-vrrp/tests/mod.rs | 8 - holo-vrrp/tests/packet/arp.rs | 42 ----- holo-vrrp/tests/packet/ipv4.rs | 96 ---------- holo-vrrp/tests/packet/mod.rs | 9 - holo-vrrp/tests/packet/vrrp.rs | 82 -------- 19 files changed, 249 insertions(+), 429 deletions(-) delete mode 100644 holo-vrrp/tests/conformance/mod.rs delete mode 100644 holo-vrrp/tests/mod.rs delete mode 100644 holo-vrrp/tests/packet/arp.rs delete mode 100644 holo-vrrp/tests/packet/ipv4.rs delete mode 100644 holo-vrrp/tests/packet/mod.rs delete mode 100644 holo-vrrp/tests/packet/vrrp.rs diff --git a/holo-interface/src/ibus.rs b/holo-interface/src/ibus.rs index f63edeb8..45d9024f 100644 --- a/holo-interface/src/ibus.rs +++ b/holo-interface/src/ibus.rs @@ -76,7 +76,7 @@ pub(crate) fn notify_interface_update(ibus_tx: &IbusSender, iface: &Interface) { ifindex: iface.ifindex.unwrap_or(0), mtu: iface.mtu.unwrap_or(0), flags: iface.flags, - mac_address: iface.mac_address.clone(), + mac_address: iface.mac_address, }); notify(ibus_tx, msg); } diff --git a/holo-interface/src/interface.rs b/holo-interface/src/interface.rs index 6f4adbbf..b11835cf 100644 --- a/holo-interface/src/interface.rs +++ b/holo-interface/src/interface.rs @@ -211,7 +211,6 @@ impl Interfaces { let iface = &self.arena[iface_idx]; iface.apply_config(ifindex, netlink_handle, self).await; } - } None => { // If the interface does not exist, create a new entry. diff --git a/holo-interface/src/netlink.rs b/holo-interface/src/netlink.rs index 64e72e5b..84bf687a 100644 --- a/holo-interface/src/netlink.rs +++ b/holo-interface/src/netlink.rs @@ -45,7 +45,7 @@ async fn process_newlink_msg( let ifindex = msg.header.index; let mut ifname = None; let mut mtu = None; - let mut mac_address: [u8; 6] = [0u8; 6]; + let mut mac_address: [u8; 6] = [0u8; 6]; let mut flags = InterfaceFlags::empty(); if msg.header.link_layer_type == ARPHRD_LOOPBACK { @@ -59,11 +59,8 @@ async fn process_newlink_msg( Nla::IfName(nla_ifname) => ifname = Some(nla_ifname), Nla::Mtu(nla_mtu) => mtu = Some(nla_mtu), Nla::Address(addr) => { - mac_address = match addr.try_into() { - Ok(a) => a, - Err(e) => [0u8; 6] - }; - }, + mac_address = addr.try_into().unwrap_or([0u8; 6]); + } _ => (), } } @@ -75,7 +72,15 @@ async fn process_newlink_msg( let ibus_tx = notify.then_some(&master.ibus_tx); master .interfaces - .update(ifname, ifindex, mtu, flags, mac_address, &master.netlink_handle, ibus_tx) + .update( + ifname, + ifindex, + mtu, + flags, + mac_address, + &master.netlink_handle, + ibus_tx, + ) .await; } diff --git a/holo-vrrp/src/debug.rs b/holo-vrrp/src/debug.rs index 6c48b3de..7ed2a735 100644 --- a/holo-vrrp/src/debug.rs +++ b/holo-vrrp/src/debug.rs @@ -21,7 +21,8 @@ pub enum Debug<'a> { } // ===== impl Debug ===== - +// allow unused for the log method +#[allow(unused)] impl<'a> Debug<'a> { // Log debug message using the tracing API. pub(crate) fn log(&self) { diff --git a/holo-vrrp/src/error.rs b/holo-vrrp/src/error.rs index 54cae245..6a785500 100644 --- a/holo-vrrp/src/error.rs +++ b/holo-vrrp/src/error.rs @@ -4,7 +4,7 @@ // SPDX-License-Identifier: MIT // -use std::fmt::{Debug, Display}; +use std::fmt::Debug; use std::net::IpAddr; use tracing::{warn, warn_span}; @@ -14,7 +14,7 @@ use tracing::{warn, warn_span}; pub enum Error { // I/O errors IoError(IoError), - InterfaceError(String), + InterfaceError(String), // vrrp-ietf-yang-2018-03-13 specific errors GlobalError(GlobalError), diff --git a/holo-vrrp/src/events.rs b/holo-vrrp/src/events.rs index c1b5d796..e7c31d58 100644 --- a/holo-vrrp/src/events.rs +++ b/holo-vrrp/src/events.rs @@ -2,21 +2,17 @@ // SPDX-License-Identifier: MIT // -use core::task; -use std::borrow::{Borrow, BorrowMut}; -use std::net::IpAddr; use std::time::Duration; -use crate::error::Error; -use crate::instance::{self, Instance, InstanceState, State}; +use crate::error::{Error, IoError}; +use crate::instance::{Instance, State}; use crate::interface::Interface; -use crate::packet::{DecodeResult, VrrpPacket}; +use crate::packet::{ArpPacket, DecodeResult, EthernetFrame, VrrpPacket}; use crate::tasks; +use crate::tasks::messages::output::NetTxPacketMsg; // To collect actions to be executed later -enum Action { - // described in 6.4.1 part 1. Is when the instance owns the - // IP addresses associated with the virtual router +enum VrrpAction { Initialize(VrrpPacket), Backup(VrrpPacket), Master(VrrpPacket), @@ -28,29 +24,132 @@ pub(crate) fn process_vrrp_packet( packet: DecodeResult, ) -> Result<(), Error> { // Handle packet decoding errors - let pkt = packet.unwrap(); + let pkt = match packet { + Ok(pkt) => pkt, + Err(_e) => { + return Err(Error::IoError(IoError::RecvError( + std::io::Error::new( + std::io::ErrorKind::Other, + "problem receiving VRRP packet", + ), + ))) + } + }; // collect the actions that are required - let mut action = match get_action(interface, pkt) { + let action = match get_vrrp_action(interface, pkt) { Ok(a) => a, - Err(e) => return Err(e) + Err(e) => return Err(e), }; - + // execute all collected actions - handle_actions(interface, action); + handle_vrrp_actions(interface, action); Ok(()) } +#[allow(unused)] +pub(crate) fn process_arp_packet( + interface: &mut Interface, + packet: DecodeResult, +) -> Result<(), Error> { + // Handle packet decoding errors + let pkt = match packet { + Ok(pkt) => pkt, + Err(_e) => { + return Err(Error::IoError(IoError::RecvError( + std::io::Error::new( + std::io::ErrorKind::Other, + "problem receiving ARP packet", + ), + ))) + } + }; + + let mut instance: Option<&mut Instance> = None; + + 'outer: for (_vr, inst) in interface.instances.iter_mut() { + for addr in inst.config.virtual_addresses.clone() { + let addr_arr = addr.ip().octets(); + if addr_arr == pkt.target_proto_address { + instance = Some(inst); + break 'outer; + } + } + } + + let instance = match instance { + Some(i) => i, + // the target ip address in the ARP request is for none of the instances + None => return Ok(()), + }; + + match instance.state.state { + State::Initialize => {} + State::Backup => { + // ======================================================== + // RFC 3768 Section 6.4.2. Backup + // While in this state, a VRRP router MUST do the following + // ======================================================== + + // MUST NOT respond to ARP requests for the IP address(es) associated with the virutal + // router + } + State::Master => { + // ======================================================== + // RFC 3768 Section 6.4.3. Master + // While in the {Maste} state the router functions as the forwarding router for the IP + // address(es) associated with the virtual router. + // While in this state, a VRRP router MUST do the following: + // ======================================================== + + // MUST respond to ARP requests for the IP address(es) associated with the virtual + // router + + if pkt.operation == 1 { + // if is ARP request + // build ARP response packet. + let mut arp_response_pkt = pkt.clone(); + arp_response_pkt.operation = 2; // reply operation + arp_response_pkt.sender_hw_address = pkt.target_hw_address; + arp_response_pkt.target_hw_address = pkt.sender_hw_address; + arp_response_pkt.sender_proto_address = + pkt.target_proto_address; + arp_response_pkt.target_proto_address = + pkt.sender_proto_address; + + // build ethernet packet + let eth_frame = EthernetFrame { + ethertype: 0x806, + src_mac: interface.system.mac_address, + dst_mac: pkt.sender_hw_address, + }; + let msg = NetTxPacketMsg::Arp { + name: interface.name.clone(), + eth_frame, + arp_packet: arp_response_pkt, + }; + interface.net.net_tx_packetp.send(msg); + } + } + } + + Ok(()) +} // gets all the actions that are required to be done bacsed on the interface // configs and incoming packet -fn get_action(interface: &mut Interface, packet: VrrpPacket) -> Result { +fn get_vrrp_action( + interface: &mut Interface, + packet: VrrpPacket, +) -> Result { // Handle missing instance let instance = match interface.instances.get_mut(&packet.vrid) { - Some(inst) => inst, - None => return Err( - Error::InterfaceError(String::from("unable to fetch VRRP instance from interface")) - ), + Some(instance) => instance, + None => { + return Err(Error::InterfaceError(String::from( + "unable to fetch VRRP instance from interface", + ))) + } }; // Update statistics @@ -58,16 +157,15 @@ fn get_action(interface: &mut Interface, packet: VrrpPacket) -> Result return Ok(Action::Initialize(packet)), - State::Backup => return Ok(Action::Backup(packet)), - State::Master => return Ok(Action::Master(packet)), + State::Initialize => Ok(VrrpAction::Initialize(packet)), + State::Backup => Ok(VrrpAction::Backup(packet)), + State::Master => Ok(VrrpAction::Master(packet)), } -} - +} -fn handle_actions(interface: &mut Interface, action: Action) { +fn handle_vrrp_actions(interface: &mut Interface, action: VrrpAction) { match action { - Action::Initialize(pkt) => { + VrrpAction::Initialize(pkt) => { let vrid = pkt.vrid; if vrid == 255 { interface.send_vrrp_advert(vrid); @@ -77,95 +175,69 @@ fn handle_actions(interface: &mut Interface, action: Action) { interface.change_state(vrid, State::Backup); } } - Action::Backup(pkt) => { + VrrpAction::Backup(pkt) => { let vrid = pkt.vrid; if let Some(instance) = interface.instances.get_mut(&vrid) { if pkt.priority == 0 { - let duration = Duration::from_secs_f32(instance.state.skew_time); + let duration = + Duration::from_secs_f32(instance.state.skew_time); tasks::set_master_down_timer(interface, vrid, duration); - } - else { + } else { // RFC 3768 Section 6.4.2 // If Preempt Mode if False, or if the priority in the ADVERTISEMENT is // greater than or equal to local priority then: - if (instance.config.preempt == false) - || (pkt.priority > instance.config.priority){ - instance.reset_timer(); + if !instance.config.preempt + || (pkt.priority > instance.config.priority) + { + instance.reset_timer(); } - // drop the packet - else { - return - } } } - } - Action::Master(pkt) => { + VrrpAction::Master(pkt) => { let vrid = pkt.vrid; let mut send_ad = false; if let Some(instance) = interface.instances.get_mut(&vrid) { - if pkt.priority == 0 { - send_ad = true; + send_ad = true; - instance.reset_timer(); - } - - else if (pkt.priority > instance.config.priority) + } else if pkt.priority > instance.config.priority // TODO: in RFC 3768 page 18, we have a requirement, where If the priority // in the ADVERTISEMENT is equal to the local Priority and the primary IP // Address of the sender is greater than the local primary IP Address, then we - // proceed. + // proceed. // // We can get our primary IP address, but purely from the VRRP packet we cannot // get our senders primary. // { interface.change_state(vrid, State::Backup); - } - - else { - return + } else { + return; } } - + if send_ad { interface.send_vrrp_advert(vrid); } - } } } -// ====== Handle Master Down Timer ===== -// This is called when the master down timer fires. -// Basically When the Instance master down timer -// ticks down. -// -// RFC 3768 : Section 6.4.2 +// ====== Handle Master Down Timer ===== +// RFC 3768 : Section 6.4.2 // 'If the Master_Down_timer fires' pub(crate) fn handle_master_down_timer( - interface: &mut Interface, - vrid: u8 -) -> Result<(), Error>{ + interface: &mut Interface, + vrid: u8, +) -> Result<(), Error> { interface.send_vrrp_advert(vrid); interface.send_gratuitous_arp(vrid); - - let instance: &mut Instance = match interface.instances.get_mut(&vrid) { - Some(i) => i, - None => { - return Err(Error::InterfaceError(String::from( - "unable to get VRRP instance from interface" - ))); - } - }; interface.change_state(vrid, State::Master); Ok(()) } - - diff --git a/holo-vrrp/src/instance.rs b/holo-vrrp/src/instance.rs index 6094e486..29a40377 100644 --- a/holo-vrrp/src/instance.rs +++ b/holo-vrrp/src/instance.rs @@ -4,8 +4,6 @@ // SPDX-License-Identifier: MIT // -use core::task; -use std::borrow::BorrowMut; use std::net::Ipv4Addr; use std::time::Duration; @@ -13,8 +11,6 @@ use chrono::{DateTime, Utc}; use holo_utils::task::{IntervalTask, TimeoutTask}; use crate::northbound::configuration::InstanceCfg; -use crate::packet::VrrpPacket; -use crate::{network, tasks}; #[derive(Debug)] pub struct Instance { @@ -125,7 +121,6 @@ impl Instance { _ => {} } } - } // ===== impl InstanceState ===== diff --git a/holo-vrrp/src/interface.rs b/holo-vrrp/src/interface.rs index 0107db25..5982c9a8 100644 --- a/holo-vrrp/src/interface.rs +++ b/holo-vrrp/src/interface.rs @@ -73,7 +73,7 @@ pub struct InterfaceNet { pub struct ProtocolInputChannelsTx { // Packet Rx event. pub net_packet_rx: Sender, - // Master Down event + // Master Down event pub master_down_timer: Sender, } @@ -97,7 +97,6 @@ impl Interface { pub(crate) fn send_vrrp_advert(&self, vrid: u8) { if let Some(instance) = self.instances.get(&vrid) { - // send advertisement then reset the timer. let mut ip_addresses: Vec = vec![]; for addr in &instance.config.virtual_addresses { ip_addresses.push(addr.ip()); @@ -117,54 +116,49 @@ impl Interface { auth_data2: 0, }; packet.generate_checksum(); - network::send_packet_vrrp(&self.net.socket_vrrp, packet); + let msg = NetTxPacketMsg::Vrrp { packet }; + let _ = self.net.net_tx_packetp.send(msg); } } - pub(crate) fn send_gratuitous_arp(&self, vrid: u8) { - let ifname = &self.name; - + pub(crate) fn send_gratuitous_arp(&self, vrid: u8) { if let Some(instance) = self.instances.get(&vrid) { - - // send a gratuitous for each of the + // send a gratuitous for each of the // virutal IP addresses for addr in instance.config.virtual_addresses.clone() { - let arp_packet = ArpPacket { - hw_type: 1, - // for Ipv4 + hw_type: 1, + // for Ipv4 proto_type: 0x0800, // mac address length - hw_length: 6, + hw_length: 6, proto_length: 4, operation: 1, // sender hw address is virtual mac. // https://datatracker.ietf.org/doc/html/rfc3768#section-7.3 - sender_hw_address: [0x00, 0x00, 0x5e, 0x00, 0x01, vrid], - sender_proto_address: addr.ip().octets(), + sender_hw_address: [0x00, 0x00, 0x5e, 0x00, 0x01, vrid], + sender_proto_address: addr.ip().octets(), target_hw_address: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff], // broadcast - target_proto_address: addr.ip().octets() + target_proto_address: addr.ip().octets(), }; - let mut mac_addr = self.system.mac_address.clone(); + let mac_addr = self.system.mac_address; let eth_frame = EthernetFrame { ethertype: 0x806, dst_mac: [0xff; 6], - src_mac: mac_addr + src_mac: mac_addr, }; - let _ = network::send_packet_arp( - &self.net.socket_arp, - &self.name, - eth_frame, - arp_packet - ); - } + let msg = NetTxPacketMsg::Arp { + name: self.name.clone(), + eth_frame, + arp_packet, + }; + let _ = self.net.net_tx_packetp.send(msg); + } } } - - } #[async_trait] diff --git a/holo-vrrp/src/network.rs b/holo-vrrp/src/network.rs index a5cd3409..c95bf685 100644 --- a/holo-vrrp/src/network.rs +++ b/holo-vrrp/src/network.rs @@ -5,13 +5,12 @@ // use std::io; -use std::net::{IpAddr, Ipv4Addr, SocketAddrV4}; -use std::os::fd::FromRawFd; +use std::net::{Ipv4Addr, SocketAddrV4}; use std::sync::Arc; use holo_utils::socket::{AsyncFd, Socket}; use holo_utils::{capabilities, Sender, UnboundedReceiver}; -use libc::{socket, AF_PACKET, ETH_P_ALL, ETH_P_ARP, SOCK_RAW}; +use libc::{AF_PACKET, ETH_P_ARP}; use socket2::{Domain, Protocol, Type}; use tokio::sync::mpsc::error::SendError; @@ -48,8 +47,8 @@ pub fn socket_arp(ifname: &str) -> Result { ) })?; capabilities::raise(|| { - sock.bind_device(Some(ifname.as_bytes())); - sock.set_broadcast(true); + let _ = sock.bind_device(Some(ifname.as_bytes())); + let _ = sock.set_broadcast(true); }); Ok(sock) } @@ -70,27 +69,22 @@ pub(crate) async fn send_packet_vrrp( socket .async_io(tokio::io::Interest::WRITABLE, |sock| { sock.send_to(buf, &saddr.into()) - .map_err(|errno| errno.into()) }) .await .map_err(IoError::SendError) } -//#[cfg(not(feature = "testing"))] -pub fn send_packet_arp( +#[cfg(not(feature = "testing"))] +pub async fn send_packet_arp( sock: &AsyncFd, ifname: &str, eth_frame: EthernetFrame, arp_packet: ArpPacket, ) -> Result { - use std::ffi::{CString, NulError}; + use std::ffi::CString; use std::os::fd::AsRawFd; - use std::os::{self}; - use bytes::Buf; - use libc::{ - c_void, if_indextoname, if_nametoindex, sendto, sockaddr, sockaddr_ll, - }; + use libc::{c_void, sendto, sockaddr, sockaddr_ll}; use crate::packet::ARPframe; let mut arpframe = ARPframe::new(eth_frame, arp_packet); @@ -134,7 +128,7 @@ pub fn send_packet_arp( } } -#[cfg(not(feature = "testing"))] +//#[cfg(not(feature = "testing"))] pub(crate) async fn write_loop( socket_vrrp: Arc>, socket_arp: Arc>, @@ -142,18 +136,23 @@ pub(crate) async fn write_loop( ) { while let Some(msg) = net_tx_packetc.recv().await { match msg { - NetTxPacketMsg::Vrrp { packet, src, dst } => { - if let Err(error) = - send_packet_vrrp(&socket_vrrp, packet).await + NetTxPacketMsg::Vrrp { packet } => { + if let Err(error) = send_packet_vrrp(&socket_vrrp, packet).await { error.log(); } } - NetTxPacketMsg::Arp {} => { - - // if let Err(error) = send_packet_arp(&socket_arp).await { - // error.log(); - // } + NetTxPacketMsg::Arp { + name, + eth_frame, + arp_packet, + } => { + if let Err(error) = + send_packet_arp(&socket_arp, &name, eth_frame, arp_packet) + .await + { + error.log(); + } } } } diff --git a/holo-vrrp/src/northbound/configuration.rs b/holo-vrrp/src/northbound/configuration.rs index 4eabd119..c9c3b2d4 100644 --- a/holo-vrrp/src/northbound/configuration.rs +++ b/holo-vrrp/src/northbound/configuration.rs @@ -142,7 +142,7 @@ fn load_validation_callbacks() -> ValidationCallbacks { .validate(|args| { let version = args.dnode.get_string(); if version != "ietf-vrrp:vrrp-v2" { - return Err(format!("unsupported VRRP version",)); + return Err("unsupported VRRP version".to_string()); } Ok(()) diff --git a/holo-vrrp/src/northbound/notification.rs b/holo-vrrp/src/northbound/notification.rs index e1245243..ffd7b80a 100644 --- a/holo-vrrp/src/northbound/notification.rs +++ b/holo-vrrp/src/northbound/notification.rs @@ -13,7 +13,7 @@ use holo_yang::ToYang; use crate::instance::MasterReason; // ===== global functions ===== - +#[allow(unused)] pub(crate) fn new_master_event( nb_tx: &NbProviderSender, addr: Ipv4Addr, diff --git a/holo-vrrp/src/packet.rs b/holo-vrrp/src/packet.rs index ff26b0af..848bc6e3 100644 --- a/holo-vrrp/src/packet.rs +++ b/holo-vrrp/src/packet.rs @@ -214,7 +214,6 @@ impl VrrpPacket { pub fn decode(data: &[u8]) -> DecodeResult { // 1. pkt length verification let pkt_size = data.len(); - let count_ip = data[3]; let mut buf: Bytes = Bytes::copy_from_slice(data); let ver_type = buf.get_u8(); @@ -226,8 +225,7 @@ impl VrrpPacket { let auth_type = buf.get_u8(); let adver_int = buf.get_u8(); - if pkt_size < Self::MIN_PKT_LENGTH - || pkt_size > Self::MAX_PKT_LENGTH + if !(Self::MIN_PKT_LENGTH..=Self::MAX_PKT_LENGTH).contains(&pkt_size) || count_ip as usize > Self::MAX_IP_COUNT || (count_ip * 4) + 16 != pkt_size as u8 { @@ -243,7 +241,7 @@ impl VrrpPacket { } let mut ip_addresses: Vec = vec![]; - for addr in 0..count_ip { + for _ in 0..count_ip { ip_addresses.push(buf.get_ipv4()); } @@ -260,8 +258,8 @@ impl VrrpPacket { adver_int, checksum, ip_addresses, - auth_data: auth_data, - auth_data2: auth_data2, + auth_data, + auth_data2, }) } @@ -274,6 +272,7 @@ impl Ipv4Packet { const MIN_HDR_LENGTH: usize = 20; const MAX_HDR_LENGTH: usize = 24; + #[allow(unused)] fn encode(&self) -> BytesMut { let mut buf = BytesMut::new(); @@ -386,14 +385,14 @@ impl EthernetFrame { pub fn decode(data: &[u8]) -> DecodeResult { let mut buf = Bytes::copy_from_slice(data); - let mut dst_mac: [u8; 6] = [0u8; 6]; - let mut src_mac: [u8; 6] = [0u8; 6]; + let dst_mac: [u8; 6] = [0u8; 6]; + let src_mac: [u8; 6] = [0u8; 6]; - for x in 0..6 { - dst_mac[x] = buf.get_u8(); + for mut _x in &dst_mac { + _x = &buf.get_u8(); } - for x in 0..6 { - src_mac[x] = buf.get_u8(); + for mut _x in &src_mac { + _x = &buf.get_u8(); } Ok(Self { @@ -439,24 +438,25 @@ impl ArpPacket { let hw_length = buf.get_u8(); let proto_length = buf.get_u8(); let operation = buf.get_u16(); - let mut sender_hw_address: [u8; 6] = [0_u8; 6]; - for x in 0..6 { - sender_hw_address[x] = buf.get_u8(); + + let sender_hw_address: [u8; 6] = [0_u8; 6]; + for mut _x in &sender_hw_address { + _x = &buf.get_u8(); } - let mut sender_proto_address: [u8; 4] = [0_u8; 4]; - for x in 0..4 { - sender_proto_address[x] = buf.get_u8(); + let sender_proto_address: [u8; 4] = [0_u8; 4]; + for mut _x in &sender_proto_address { + _x = &buf.get_u8(); } - let mut target_hw_address: [u8; 6] = [0_u8; 6]; - for x in 0..6 { - target_hw_address[x] = buf.get_u8(); + let target_hw_address: [u8; 6] = [0_u8; 6]; + for mut _x in &target_hw_address { + _x = &buf.get_u8(); } - let mut target_proto_address: [u8; 4] = [0_u8; 4]; - for x in 0..4 { - target_hw_address[x] = buf.get_u8(); + let target_proto_address: [u8; 4] = [0_u8; 4]; + for mut _x in &target_proto_address { + _x = &buf.get_u8(); } Ok(Self { @@ -497,10 +497,10 @@ pub mod checksum { let mut result: u16 = 0; while carry != 0 { - let tmp_res = (first as u32 + second as u32) as u32; + let tmp_res = first as u32 + second as u32; result = (tmp_res & 0xFFFF) as u16; carry = tmp_res >> 16; - first = result as u16; + first = result; second = carry as u16; } result diff --git a/holo-vrrp/src/tasks.rs b/holo-vrrp/src/tasks.rs index b97440f2..8b40490c 100644 --- a/holo-vrrp/src/tasks.rs +++ b/holo-vrrp/src/tasks.rs @@ -4,17 +4,15 @@ // SPDX-License-Identifier: MIT // -use std::borrow::BorrowMut; use std::sync::Arc; use std::time::Duration; use holo_utils::socket::{AsyncFd, Socket}; use holo_utils::task::{IntervalTask, Task, TimeoutTask}; use holo_utils::{Sender, UnboundedReceiver}; -use messages::input::MasterDownTimerMsg; use tracing::{debug_span, Instrument}; -use crate::instance::{Instance, VrrpTimer}; +use crate::instance::VrrpTimer; use crate::interface::Interface; use crate::network; @@ -69,13 +67,14 @@ pub mod messages { #[derive(Debug, Deserialize, Serialize)] pub struct MasterDownTimerMsg { - pub vrid: u8, + pub vrid: u8, } } // Output messages (main task -> child task). pub mod output { use super::*; + use crate::packet::{ArpPacket, EthernetFrame}; #[derive(Debug, Serialize)] pub enum ProtocolMsg { @@ -86,11 +85,11 @@ pub mod messages { pub enum NetTxPacketMsg { Vrrp { packet: VrrpPacket, - src: IpAddr, - dst: IpAddr, }, Arp { - // TODO + name: String, + eth_frame: EthernetFrame, + arp_packet: ArpPacket, }, } } @@ -168,24 +167,23 @@ pub(crate) fn net_tx( } // handling the timers... -pub(crate) fn set_timer( interface: &mut Interface, vrid: u8 -) { - if let Some(instance) = interface.instances.get_mut(&vrid){ +pub(crate) fn set_timer(interface: &mut Interface, vrid: u8) { + if let Some(instance) = interface.instances.get_mut(&vrid) { match instance.state.state { crate::instance::State::Initialize => { instance.timer = VrrpTimer::Null; } crate::instance::State::Backup => { - let duration = Duration::from_secs(instance.state.master_down_interval as u64); - set_master_down_timer( - interface, - vrid, - duration + let duration = Duration::from_secs( + instance.state.master_down_interval as u64, ); + set_master_down_timer(interface, vrid, duration); } crate::instance::State::Master => { let timer = IntervalTask::new( - Duration::from_secs(instance.config.advertise_interval as u64), + Duration::from_secs( + instance.config.advertise_interval as u64, + ), true, move || async move { todo!("send VRRP advertisement"); @@ -195,18 +193,19 @@ pub(crate) fn set_timer( interface: &mut Interface, vrid: u8 } } } - } // ==== Set Master Down Timer ==== pub(crate) fn set_master_down_timer( - interface: &mut Interface, vrid: u8, duration: Duration // period: u64 + interface: &mut Interface, + vrid: u8, + duration: Duration, // period: u64 ) { let instance = interface.instances.get_mut(&vrid).unwrap(); let tx = interface.tx.protocol_input.master_down_timer.clone(); let timer = TimeoutTask::new(duration, move || async move { - tx.send(messages::input::MasterDownTimerMsg{ vrid }); + let _ = tx.send(messages::input::MasterDownTimerMsg { vrid }).await; }); instance.timer = VrrpTimer::MasterDownTimer(timer); } diff --git a/holo-vrrp/tests/conformance/mod.rs b/holo-vrrp/tests/conformance/mod.rs deleted file mode 100644 index 8151c7f1..00000000 --- a/holo-vrrp/tests/conformance/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -// -// Copyright (c) The Holo Core Contributors -// -// SPDX-License-Identifier: MIT -// - -// TODO diff --git a/holo-vrrp/tests/mod.rs b/holo-vrrp/tests/mod.rs deleted file mode 100644 index f505cbe8..00000000 --- a/holo-vrrp/tests/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// -// Copyright (c) The Holo Core Contributors -// -// SPDX-License-Identifier: MIT -// - -mod conformance; -mod packet; diff --git a/holo-vrrp/tests/packet/arp.rs b/holo-vrrp/tests/packet/arp.rs deleted file mode 100644 index d3ee624e..00000000 --- a/holo-vrrp/tests/packet/arp.rs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) The Holo Core Contributors -// -// SPDX-License-Identifier: MIT -// - -use holo_vrrp::packet::{ArpPacket, DecodeError}; - -/* -ARP packet => - - -hw_type: 1, -proto_type: 0x0800, -hw_length: 6, -proto_length: 4, -operation: 1, -sender_hw_address: [0xd4, 0xb1, 0x08, 0x4c, 0xbb, 0xf9], // src mac -sender_proto_address: [192, 168, 100, 1], // src ip -pub target_hw_address: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00], // src mac -pub target_proto_address: [192, 168, 100, 16] // src ip - -*/ -fn valid_pkt_data() -> [u8; 28] { - [ - 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xd4, 0xb1, 0x08, 0x4c, - 0xbb, 0xf9, 0xc0, 0xa8, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0xa8, 0x64, 0x10, - ] -} - -#[test] -fn encode_valid_pkt() { - let pkt_wrapped = ArpPacket::decode(&valid_pkt_data()); - assert!(pkt_wrapped.is_ok()); -} - -#[test] -fn test_pkt_invalid_length() { - let pkt = ArpPacket::decode(&[0x01]); - assert_eq!(pkt, Err(DecodeError::PacketLengthError)); -} diff --git a/holo-vrrp/tests/packet/ipv4.rs b/holo-vrrp/tests/packet/ipv4.rs deleted file mode 100644 index 978abc8a..00000000 --- a/holo-vrrp/tests/packet/ipv4.rs +++ /dev/null @@ -1,96 +0,0 @@ -// -// Copyright (c) The Holo Core Contributors -// -// SPDX-License-Identifier: MIT -// - -use std::net::Ipv4Addr; - -use holo_vrrp::packet::{DecodeError, Ipv4Packet}; - -// the ipv4 Packet header details that will be used in IPV4 tests. -// It may have slight modifications based on the specific test -// but that will be specified beforehand. -// -// - version: 4 -// - header length: 5 -// - tos: 0 -// - total length: 52 -// - identification: 0x6cb8 -// - flags: 0b0100000000000000 -// - ttl: 51 -// - protocol: 6 [TCP] -// - checksum: 0xfe74 -// - source_address: 208.115.231.106 -// - destination_address: 192.168.100.16 -fn valid_pkt_data() -> [u8; 20] { - [ - 0x45, 0x00, 0x00, 0x34, 0x6c, 0xb8, 0x40, 0x00, 0x33, 0x06, 0xfe, 0x74, - 0xd0, 0x73, 0xe7, 0x6a, 0xc0, 0xa8, 0x64, 0x10, - ] -} - -#[test] -fn encode_valid_pkt() { - let pkt_wrapped = Ipv4Packet::decode(&valid_pkt_data()); - assert!(pkt_wrapped.is_ok()); - - let pkt = pkt_wrapped.unwrap(); - let expected = Ipv4Packet { - version: 4, - ihl: 5, - tos: 0, - total_length: 52, - identification: 0x6cb8, - flags: 0b0100, - offset: 0b0000000000000000, - ttl: 51, - protocol: 6, - checksum: 0xfe74, - src_address: Ipv4Addr::new(208, 115, 231, 106), - dst_address: Ipv4Addr::new(192, 168, 100, 16), - options: None, - padding: None, - }; - assert_eq!(expected, pkt); -} - -#[test] -fn test_hdr_length_corruption() { - let data = &mut valid_pkt_data(); - - // change length from 4 to 5 - data[0] = 0x44; - - let pkt = Ipv4Packet::decode(data); - assert_eq!(pkt, Err(DecodeError::PacketLengthError)); -} - -#[test] -fn test_header_too_short() { - let data = [ - 0x43, 0x00, 0x00, 0x34, 0x6c, 0xb8, 0x40, 0x00, 0x33, 0x06, 0xfe, 0x74, - ]; - let pkt = Ipv4Packet::decode(&data); - assert_eq!(pkt, Err(DecodeError::PacketLengthError)); -} - -#[test] -fn test_header_too_long() { - let data = &mut [0x00; 28]; - data[0] = 0x47; - let pkt = Ipv4Packet::decode(data); - assert_eq!(pkt, Err(DecodeError::PacketLengthError)); -} - -#[test] -fn test_invalid_checksum() { - let data = &mut valid_pkt_data(); - - // change the checksum fields to be sth invalid - data[10] = 0x10; - data[11] = 0x01; - - let pkt = Ipv4Packet::decode(data); - assert_eq!(pkt, Err(DecodeError::ChecksumError)); -} diff --git a/holo-vrrp/tests/packet/mod.rs b/holo-vrrp/tests/packet/mod.rs deleted file mode 100644 index 6a4cd235..00000000 --- a/holo-vrrp/tests/packet/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Copyright (c) The Holo Core Contributors -// -// SPDX-License-Identifier: MIT -// - -mod arp; -mod ipv4; -mod vrrp; diff --git a/holo-vrrp/tests/packet/vrrp.rs b/holo-vrrp/tests/packet/vrrp.rs deleted file mode 100644 index ea884cff..00000000 --- a/holo-vrrp/tests/packet/vrrp.rs +++ /dev/null @@ -1,82 +0,0 @@ -// -// Copyright (c) The Holo Core Contributors -// -// SPDX-License-Identifier: MIT -// - -use holo_vrrp::packet::{DecodeError, VrrpPacket}; - -/* -generally in the packet tests we will use the following packet structure -with slight modifications to be done on a per test basis(the changes will -be specified) - -Valid VRRP packet with the following params: - - ver_type: 21 [version: 2, header_type: 1] - - vrid: 51 - - priority: 101 - - count_ip: 1 - - auth_type: 0 - - adver_int: 1 - - checksum: 0x54db - - ip_addresses: [192.168.100.100] - - auth_data: 0 - - auth_data2: 0 - */ -fn valid_pkt_data() -> [u8; 20] { - [ - 0x21, 0x33, 0x65, 0x01, 0x00, 0x01, 0x54, 0xbd, 0xc0, 0xa8, 0x64, 0x64, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] -} - -// test the valid packet being decoded -#[test] -fn test_valid_decoding() { - let vrrp_pkt = VrrpPacket::decode(&valid_pkt_data()); - assert!(vrrp_pkt.is_ok()); -} - -// make the VRRP packet too short. We will use 10 bytes. -#[test] -fn test_pkt_too_short() { - let vrrp_pkt = VrrpPacket::decode(&[0x00; 10]); - assert_eq!(vrrp_pkt, Err(DecodeError::PacketLengthError)); -} - -// the length of the entire packet is too long -#[test] -fn test_pkt_too_long() { - let vrrp_pkt = VrrpPacket::decode(&[0x00; 100]); - assert_eq!(vrrp_pkt, Err(DecodeError::PacketLengthError)); -} - -// test when the packet is too long in length -// we set count_ip as 17 -#[test] -fn test_count_ip_too_high() { - let data: &mut [u8] = &mut valid_pkt_data(); - data[3] = 17; - let vrrp_pkt = VrrpPacket::decode(data); - assert_eq!(vrrp_pkt, Err(DecodeError::PacketLengthError)); -} - -// let us claim we have 3 ip addresses yet we have only one -// we set count_ip as 17 -#[test] -fn test_count_ip_corrupted() { - let data: &mut [u8] = &mut valid_pkt_data(); - data[3] = 3; - let vrrp_pkt = VrrpPacket::decode(data); - assert_eq!(vrrp_pkt, Err(DecodeError::PacketLengthError)); -} - -#[test] -fn test_invalid_checksum() { - let data = &mut valid_pkt_data(); - data[6] = 0x01; - data[7] = 0xde; - - let pkt = VrrpPacket::decode(data); - assert_eq!(pkt, Err(DecodeError::ChecksumError)); -}