Skip to content

Commit

Permalink
Change mac address datatype to [u8; 6]
Browse files Browse the repository at this point in the history
enhance events.rs with functions.
  • Loading branch information
Paul-weqe committed Jul 30, 2024
1 parent beff510 commit 50ccef2
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 60 deletions.
4 changes: 2 additions & 2 deletions holo-interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct Interface {
pub mtu: Option<u32>,
pub flags: InterfaceFlags,
pub addresses: BTreeMap<IpNetwork, InterfaceAddress>,
pub mac_address: Vec<u8>,
pub mac_address: [u8; 6],
pub owner: Owner,
pub vrrp: Option<NbDaemonSender>,
}
Expand Down Expand Up @@ -141,7 +141,7 @@ impl Interfaces {
ifindex: u32,
mtu: u32,
flags: InterfaceFlags,
mac_address: Vec<u8>,
mac_address: [u8; 6],
netlink_handle: &rtnetlink::Handle,
ibus_tx: Option<&IbusSender>,
) {
Expand Down
9 changes: 7 additions & 2 deletions holo-interface/src/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: Vec<u8> = Vec::default();
let mut mac_address: [u8; 6] = [0u8; 6];

let mut flags = InterfaceFlags::empty();
if msg.header.link_layer_type == ARPHRD_LOOPBACK {
Expand All @@ -58,7 +58,12 @@ async fn process_newlink_msg(
match nla {
Nla::IfName(nla_ifname) => ifname = Some(nla_ifname),
Nla::Mtu(nla_mtu) => mtu = Some(nla_mtu),
Nla::Address(addr) => mac_address = addr,
Nla::Address(addr) => {
mac_address = match addr.try_into() {
Ok(a) => a,
Err(e) => [0u8; 6]
};
},
_ => (),
}
}
Expand Down
2 changes: 1 addition & 1 deletion holo-utils/src/southbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub struct InterfaceUpdateMsg {
pub ifindex: u32,
pub mtu: u32,
pub flags: InterfaceFlags,
pub mac_address: Vec<u8>,
pub mac_address: [u8; 6],
}

#[derive(Clone, Debug)]
Expand Down
5 changes: 5 additions & 0 deletions holo-vrrp/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use tracing::{warn, warn_span};
pub enum Error {
// I/O errors
IoError(IoError),
InterfaceError(String),

// vrrp-ietf-yang-2018-03-13 specific errors
GlobalError(GlobalError),
Expand Down Expand Up @@ -54,6 +55,9 @@ impl Error {
Error::IoError(error) => {
error.log();
}
Error::InterfaceError(error) => {
warn_span!("vrrp_interface_error").in_scope(|| warn!(error));
}
Error::GlobalError(error) => {
match error {
GlobalError::ChecksumError => {
Expand Down Expand Up @@ -91,6 +95,7 @@ impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::IoError(error) => std::fmt::Display::fmt(error, f),
Error::InterfaceError(error) => write!(f, "{}", error),
Error::GlobalError(error) => std::fmt::Display::fmt(error, f),
Error::VirtualRouterError(error) => {
std::fmt::Display::fmt(error, f)
Expand Down
111 changes: 62 additions & 49 deletions holo-vrrp/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,93 @@
use std::borrow::{Borrow, BorrowMut};
use std::net::IpAddr;

use libc::wait;

use crate::error::Error;
use crate::instance::{Instance, InstanceState, State};
use crate::interface::Interface;
use crate::packet::{DecodeResult, VrrpPacket};
use crate::tasks;

// To collect actions to be executed later
enum Action {
SendVrrpAdvert(u8),
SendGratuitousArp(u8),
ChangeState(u8, State),
SetMasterDownTimer(u8, u64),
ResetTimer(u8),
}

// ===== Network packet receipt =====
//
pub(crate) fn process_packet(
interface: &mut Interface,
packet: DecodeResult<VrrpPacket>,
) -> Result<(), Error> {
// Handle packet decoding errors
let pkt = match packet {
Ok(p) => p,
Err(e) => return Ok(()), // or handle the error appropriately
let pkt = packet.unwrap();

// collect the actions that are required
let mut actions = match get_actions(interface, pkt) {
Ok(a) => a,
Err(e) => return Err(e)
};

// execute all collected actions
handle_actions(interface, actions);
Ok(())
}

// To collect actions to be executed later
enum Action {
SendVrrpAdvert(u8),
SendGratuitousArp(u8),
ChangeState(u8, State),
SetMasterDownTimer(u8, u64),
ResetTimer(u8),
}

// gets all the actions that are required to be done bacsed on the interface
// configs and incoming packet
fn get_actions(interface: &mut Interface, packet: VrrpPacket) -> Result<Vec<Action>, Error> {
let mut actions = Vec::new();

{
// Handle missing instance
let instance = match interface.instances.get_mut(&pkt.vrid) {
Some(inst) => inst,
None => return Ok(()), // or handle the error appropriately
};
// 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"))
),
};

// Update statistics
instance.state.statistics.adv_rcvd += 1;
// Update statistics
instance.state.statistics.adv_rcvd += 1;

// Handle the current state
match instance.state.state {
State::Initialize => {
if instance.config.priority == 255 {
actions.push(Action::SendVrrpAdvert(pkt.vrid));
actions.push(Action::SendGratuitousArp(pkt.vrid));
actions.push(Action::ChangeState(pkt.vrid, State::Master));
}
// Handle the current state
match instance.state.state {
State::Initialize => {
if instance.config.priority == 255 {
actions.push(Action::SendVrrpAdvert(packet.vrid));
actions.push(Action::SendGratuitousArp(packet.vrid));
actions.push(Action::ChangeState(packet.vrid, State::Master));
}
State::Backup => {
if pkt.priority == 0 {
actions.push(Action::SetMasterDownTimer(pkt.vrid, instance.state.skew_time as u64));
} else if !instance.config.preempt
|| pkt.priority >= instance.config.priority
{
actions.push(Action::ResetTimer(pkt.vrid));
}
}
State::Backup => {
if packet.priority == 0 {
actions.push(Action::SetMasterDownTimer(packet.vrid, instance.state.skew_time as u64));
} else if !instance.config.preempt
|| packet.priority >= instance.config.priority
{
actions.push(Action::ResetTimer(packet.vrid));
}
State::Master => {
if pkt.priority == 0 {
actions.push(Action::ResetTimer(pkt.vrid));
} else if pkt.priority > instance.config.priority
|| (pkt.priority == instance.config.priority
// && check if primary IP of sender is greater than the local primary IP
) {
actions.push(Action::ChangeState(pkt.vrid, State::Backup));
}
}
State::Master => {
if packet.priority == 0 {
actions.push(Action::ResetTimer(packet.vrid));
} else if packet.priority > instance.config.priority
|| (packet.priority == instance.config.priority
// && check if primary IP of sender is greater than the local primary IP
) {
actions.push(Action::ChangeState(packet.vrid, State::Backup));
}
}
}
return Ok(actions)
}


// Execute collected actions
fn handle_actions(interface: &mut Interface, actions: Vec<Action>) {
for action in actions {
match action {
Action::SendVrrpAdvert(vrid) => interface.send_vrrp_advert(vrid),
Expand All @@ -84,7 +100,6 @@ pub(crate) fn process_packet(
.build()
.unwrap()
.block_on(interface.send_gratuitous_arp(vrid));
//interface.send_gratuitous_arp(vrid).await
},
Action::ChangeState(vrid, state) => {
if let Some(instance) = interface.instances.get_mut(&vrid) {
Expand All @@ -103,6 +118,4 @@ pub(crate) fn process_packet(
}
}
}

Ok(())
}
9 changes: 3 additions & 6 deletions holo-vrrp/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub struct InterfaceSys {
// Interface IPv4 addresses.
pub addresses: BTreeSet<Ipv4Network>,
// interface Mac Address
pub mac_address: Vec<u8>,
pub mac_address: [u8; 6],
}

#[derive(Debug)]
Expand Down Expand Up @@ -135,14 +135,11 @@ impl Interface {
target_proto_address: addr.ip().octets()
};

let mut mac_addr: &mut [u8; 6] = &mut [0u8; 6];
for (idx, item) in self.system.mac_address.iter().enumerate() {
mac_addr[idx] = *item;
}
let mut mac_addr = self.system.mac_address.clone();
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,
Expand Down

0 comments on commit 50ccef2

Please sign in to comment.