Skip to content

Commit

Permalink
Move macaddress from InterfaceCfg to
Browse files Browse the repository at this point in the history
Interface

Change event code for borrow checker purposes
Minor changes in `holo-vrrp`
  • Loading branch information
Paul-weqe committed Jul 30, 2024
1 parent 8ddc171 commit beff510
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 44 deletions.
2 changes: 1 addition & 1 deletion holo-interface/src/ibus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.config.mac_address.clone(),
mac_address: iface.mac_address.clone(),
});
notify(ibus_tx, msg);
}
Expand Down
6 changes: 5 additions & 1 deletion holo-interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct Interface {
pub mtu: Option<u32>,
pub flags: InterfaceFlags,
pub addresses: BTreeMap<IpNetwork, InterfaceAddress>,
pub mac_address: Vec<u8>,
pub owner: Owner,
pub vrrp: Option<NbDaemonSender>,
}
Expand Down Expand Up @@ -126,6 +127,7 @@ impl Interfaces {
addresses: Default::default(),
owner: Owner::CONFIG,
vrrp: None,
mac_address: Default::default(),
};

let iface_idx = self.arena.insert(iface);
Expand Down Expand Up @@ -156,6 +158,7 @@ impl Interfaces {
if iface.name == ifname
&& iface.mtu == Some(mtu)
&& iface.flags == flags
&& iface.mac_address == mac_address
{
return;
}
Expand All @@ -174,7 +177,7 @@ impl Interfaces {
iface.owner.insert(Owner::SYSTEM);
iface.mtu = Some(mtu);
iface.flags = flags;
iface.config.mac_address = mac_address;
iface.mac_address = mac_address;

// Notify protocol instances about the interface update.
//
Expand Down Expand Up @@ -221,6 +224,7 @@ impl Interfaces {
addresses: Default::default(),
owner: Owner::SYSTEM,
vrrp: None,
mac_address: Default::default(),
};

// Notify protocol instances about the interface update.
Expand Down
2 changes: 0 additions & 2 deletions holo-interface/src/northbound/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ pub struct InterfaceCfg {
pub parent: Option<String>,
pub vlan_id: Option<u16>,
pub addr_list: BTreeMap<IpAddr, u8>,
pub mac_address: Vec<u8>,
}

// ===== callbacks =====
Expand Down Expand Up @@ -462,7 +461,6 @@ impl Default for InterfaceCfg {
parent: None,
vlan_id: None,
addr_list: Default::default(),
mac_address: Default::default(),
}
}
}
2 changes: 1 addition & 1 deletion holo-vrrp/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub enum Error {
// I/O errors
IoError(IoError),

// ietf yang specific errors
// vrrp-ietf-yang-2018-03-13 specific errors
GlobalError(GlobalError),
VirtualRouterError(VirtualRouterError),
}
Expand Down
118 changes: 81 additions & 37 deletions holo-vrrp/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,61 +1,105 @@
//
// Copyright (c) The Holo Core Contributors
//
// SPDX-License-Identifier: MIT
//

use std::borrow::{Borrow, BorrowMut};
use std::net::IpAddr;

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

// ===== Network packet receipt =====


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

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

let mut actions = Vec::new();

// errors will be modified to occupy the other statistics
instance.state.statistics.adv_rcvd += 1;
{
// Handle missing instance
let instance = match interface.instances.get_mut(&pkt.vrid) {
Some(inst) => inst,
None => return Ok(()), // or handle the error appropriately
};

match instance.state.state {

// RFC 3768 6.4.1
State::Initialize => {

if instance.config.priority == 255 {
interface.send_vrrp_advert(pkt.vrid);
// 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));
}
}
}
State::Backup => {
if pkt.priority == 0 {
tasks::set_master_down_timer(
instance,
instance.state.skew_time as u64,
);
} else if !instance.config.preempt
|| pkt.priority >= instance.config.priority
{
instance.reset_timer();
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::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 pkt.priority == 0 {
instance.reset_timer();
} 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
)
{
instance.transition_state(State::Backup);
}

// Execute collected actions
for action in actions {
match action {
Action::SendVrrpAdvert(vrid) => interface.send_vrrp_advert(vrid),
Action::SendGratuitousArp(vrid) => {
tokio::runtime::Builder::new_current_thread()
.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) {
instance.change_state(state);
}
}
Action::SetMasterDownTimer(vrid, time) => {
if let Some(instance) = interface.instances.get_mut(&vrid) {
tasks::set_master_down_timer(instance, time);
}
}
Action::ResetTimer(vrid) => {
if let Some(instance) = interface.instances.get_mut(&vrid) {
instance.reset_timer();
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion holo-vrrp/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl Instance {
}
}

pub(crate) fn transition_state(&mut self, state: State) {
pub(crate) fn change_state(&mut self, state: State) {
self.state.state = state;
tasks::set_timer(self);
}
Expand Down
6 changes: 5 additions & 1 deletion holo-vrrp/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,15 @@ impl Interface {

let arp_packet = ArpPacket {
hw_type: 1,
// for Ipv4
proto_type: 0x0800,
// mac address length
hw_length: 6,
proto_length: 4,
operation: 1,
sender_hw_address: [0x00, 0x00, 0x5e, 0x00, 0x01, vrid],
// 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(),
target_hw_address: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff], // broadcast
target_proto_address: addr.ip().octets()
Expand Down

0 comments on commit beff510

Please sign in to comment.