Skip to content

Commit

Permalink
vrrp: add owner checks
Browse files Browse the repository at this point in the history
VRRP instance is an owner if it holds a virtual IP
address as it's parent interface. Currently being
checked during virtual-address configuration and
when the primary interface has change in addresses
(addition / deletion) which may affect the is_owner
state.

Signed-off-by: Paul Wekesa <[email protected]>
  • Loading branch information
Paul-weqe committed Dec 11, 2024
1 parent 937a1b3 commit 5d2992d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
23 changes: 21 additions & 2 deletions holo-vrrp/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub struct InstanceState {
pub timer: VrrpTimer,
pub last_adv_src: Option<Ipv4Addr>,
pub statistics: Statistics,
pub is_owner: bool,
}

#[derive(Debug)]
Expand Down Expand Up @@ -165,7 +166,8 @@ impl Instance {
match InstanceNet::new(interface, &self.mvlan) {
Ok(net) => {
self.net = Some(net);
if self.config.priority == 255 {
self.state.is_owner = self.check_is_owner(interface.system);
if self.config.priority == 255 || self.state.is_owner {
let src_ip =
interface.system.addresses.first().unwrap().ip();
self.send_vrrp_advertisement(src_ip);
Expand Down Expand Up @@ -314,11 +316,18 @@ impl Instance {
ip_addresses.push(addr.ip());
}

// RFC 3768 -> 5.3.4. Priority
let priority = if self.state.is_owner {
255
} else {
self.config.priority
};

let mut packet = VrrpHdr {
version: 2,
hdr_type: 1,
vrid: self.vrid,
priority: self.config.priority,
priority: priority,
count_ip: self.config.virtual_addresses.len() as u8,
auth_type: 0,
adver_int: self.config.advertise_interval,
Expand Down Expand Up @@ -403,6 +412,16 @@ impl Instance {
let _ = net.net_tx_packetp.send(msg);
}
}

/// an instance is an owner if the ip address of the parent interface is
/// part of the virutal addresses held by the instance.
pub(crate) fn check_is_owner(&self, interface_sys: &InterfaceSys) -> bool {
self.config
.virtual_addresses
.iter()
.any(|addr| interface_sys.addresses.contains(addr));
false
}
}

impl Drop for Instance {
Expand Down
7 changes: 7 additions & 0 deletions holo-vrrp/src/northbound/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ impl Provider for Interface {
);
instance.timer_set(&interface);
}

// owner status may change when virtual address is added
instance.state.is_owner =
instance.check_is_owner(&interface.system);
}
Event::VirtualAddressDelete { vrid, addr } => {
let (interface, instance) = self.get_instance(vrid).unwrap();
Expand All @@ -234,6 +238,9 @@ impl Provider for Interface {
);
instance.timer_set(&interface);
}
// owner status may change when virtual address is added
instance.state.is_owner =
instance.check_is_owner(&interface.system);
}
Event::ResetTimer { vrid } => {
let (_, instance) = self.get_instance(vrid).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion holo-vrrp/src/northbound/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn load_callbacks() -> Callbacks<Interface> {
vrid: *vrid,
state: Some(instance.state.state.to_yang()),
// TODO
is_owner: None,
is_owner: Some(instance.state.is_owner),
last_adv_source: instance.state.last_adv_src.map(std::convert::Into::into).map(Cow::Owned).ignore_in_testing(),
up_datetime: instance.state.up_time.as_ref().map(Cow::Borrowed).ignore_in_testing(),
master_down_interval: instance.state.timer.as_master_down_timer().map(|task| task.remaining().as_millis() as u32 / 10).ignore_in_testing(),
Expand Down

0 comments on commit 5d2992d

Please sign in to comment.