RtnlMessage::NewLink(link_msg) => {
let (iface, mac_address) = self.nl_linkmessage_decode(link_msg)?;
log::debug!("NewLink({iface:?} {mac_address})");
+ events.push(NetEvent{iface: iface.clone(), op: NetEventOp::AddIface});
events.push(NetEvent{iface, op: NetEventOp::AddMac(mac_address)});
},
RtnlMessage::DelLink(link_msg) => {
let (iface, mac_address) = self.nl_linkmessage_decode(link_msg)?;
log::debug!("DelLink({iface:?} {mac_address})");
- events.push(NetEvent{iface, op: NetEventOp::RmMac(mac_address)});
+ events.push(NetEvent{iface: iface.clone(),
+ op: NetEventOp::RmMac(mac_address)}); // redundant
+ events.push(NetEvent{iface, op: NetEventOp::RmIface});
},
RtnlMessage::NewAddress(address_msg) => {
// FIXME does not distinguish when IP is on DOWN iface
use std::collections::{HashMap, HashSet, hash_map};
use std::error::Error;
use std::io;
+use std::rc::Rc;
use std::time::Duration;
const IFACE_PERIOD_SECONDS: u64 = 60;
cached_iface_index)));
},
};
- let iface_adresses =
- if let Some(iface_info) = current_addresses.get(cached_iface_index) {
- &iface_info.addresses
- } else {
- &empty_address_set
- };
- for disappearing in cached_info.addresses.difference(iface_adresses) {
- log::trace!("disappearing {}: {:?}", iface.name, disappearing);
- events.push(NetEvent{iface: iface.clone(),
- op: match disappearing {
- Address::IP(ip) => NetEventOp::RmIp(ip.ip()),
- Address::MAC(mac) => NetEventOp::RmMac((*mac).to_string()),
- }});
- }
+ // notify addresses or full iface removal
+ match current_addresses.get(cached_iface_index) {
+ Some(iface_info) => {
+ let iface_adresses = &iface_info.addresses;
+ for disappearing in cached_info.addresses.difference(iface_adresses) {
+ log::trace!("disappearing {}: {:?}", iface.name, disappearing);
+ events.push(NetEvent{
+ iface: iface.clone(),
+ op: match disappearing {
+ Address::IP(ip) => NetEventOp::RmIp(ip.ip()),
+ Address::MAC(mac) => NetEventOp::RmMac((*mac).to_string()),
+ }});
+ }
+ },
+ None => {
+ events.push(NetEvent{iface: iface.clone(), op: NetEventOp::RmIface});
+ },
+ };
}
+
// appearing addresses
for (iface_index, iface_info) in current_addresses.iter() {
let iface = self.iface_cache
.entry(*iface_index)
.or_insert_with_key(|index| {
- NetInterface::new(*index, Some(iface_info.name.clone())).into()
+ let iface = Rc::new(NetInterface::new(*index, Some(iface_info.name.clone())));
+ events.push(NetEvent{iface: iface.clone(), op: NetEventOp::AddIface});
+ iface
})
.clone();
let cache_adresses =
#[derive(Debug)]
pub enum NetEventOp {
+ AddIface,
+ RmIface,
AddMac(String),
RmMac(String),
AddIp(IpAddr),
pub fn publish_netevent(&self, event: &NetEvent) -> io::Result<()> {
let iface_id = &event.iface.name;
match &event.op {
+ NetEventOp::AddIface => println!("{iface_id} +IFACE"),
+ NetEventOp::RmIface => println!("{iface_id} -IFACE"),
NetEventOp::AddIp(address) => println!("{iface_id} +IP {address}"),
NetEventOp::RmIp(address) => println!("{iface_id} -IP {address}"),
NetEventOp::AddMac(mac_address) => println!("{iface_id} +MAC {mac_address}"),
let iface_id = &event.iface.index;
let xs_iface_prefix = format!("data/net/{iface_id}");
match &event.op {
+ NetEventOp::AddIface => {
+ xs_publish(&self.xs, &format!("{xs_iface_prefix}"), &event.iface.name)?;
+ },
+ NetEventOp::RmIface => {
+ xs_unpublish(&self.xs, &format!("{xs_iface_prefix}"))?;
+ },
NetEventOp::AddIp(address) => {
let key_suffix = munged_address(address);
xs_publish(&self.xs, &format!("{xs_iface_prefix}/{key_suffix}"), "")?;
};
let xs_iface_prefix = format!("attr/vif/{iface_id}");
match &event.op {
+ NetEventOp::AddIface => {
+ xs_publish(&self.xs, &format!("{xs_iface_prefix}"), "")?;
+ },
+ NetEventOp::RmIface => {
+ xs_unpublish(&self.xs, &format!("{xs_iface_prefix}"))?;
+ },
NetEventOp::AddIp(address) => {
let key_suffix = self.munged_address(address, &event.iface)?;
xs_publish(&self.xs, &format!("{xs_iface_prefix}/{key_suffix}"),