From: Yann Dirson Date: Tue, 21 Nov 2023 13:55:17 +0000 (+0100) Subject: net: separate add/rm of interface and add/rm of MAC address X-Git-Tag: 0.3.0~11^2~3 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5b7addc7c884b24ea5425760e01382387c8f8443;p=xen-guest-agent.git net: separate add/rm of interface and add/rm of MAC address The current code would do nothing on interface removal, as we only emit a `RmMac` event, with which xenstore_schema_std does nothing (we did not add them in the first place). An explicit `RmIface` allows for the removal of the full iface tree in Xenstore, since there is no need to expose a mostly-empty tree. Signed-off-by: Yann Dirson --- diff --git a/src/collector_net_netlink.rs b/src/collector_net_netlink.rs index dc51021..81c8cde 100644 --- a/src/collector_net_netlink.rs +++ b/src/collector_net_netlink.rs @@ -108,12 +108,15 @@ impl NetworkSource { 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 diff --git a/src/collector_net_pnet.rs b/src/collector_net_pnet.rs index 1ce5c8a..0be4283 100644 --- a/src/collector_net_pnet.rs +++ b/src/collector_net_pnet.rs @@ -6,6 +6,7 @@ use pnet_base::MacAddr; 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; @@ -94,27 +95,34 @@ impl NetworkSource { 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 = diff --git a/src/datastructs.rs b/src/datastructs.rs index 25e3655..a1ba27b 100644 --- a/src/datastructs.rs +++ b/src/datastructs.rs @@ -58,6 +58,8 @@ pub type NetInterfaceCache = HashMap>; #[derive(Debug)] pub enum NetEventOp { + AddIface, + RmIface, AddMac(String), RmMac(String), AddIp(IpAddr), diff --git a/src/publisher.rs b/src/publisher.rs index 5970f8c..fcaa26b 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -31,6 +31,8 @@ impl Publisher { 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}"), diff --git a/src/xenstore_schema_rfc.rs b/src/xenstore_schema_rfc.rs index 50cbb04..e1f1a1e 100644 --- a/src/xenstore_schema_rfc.rs +++ b/src/xenstore_schema_rfc.rs @@ -44,6 +44,12 @@ impl XenstoreSchema for Schema { 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}"), "")?; diff --git a/src/xenstore_schema_std.rs b/src/xenstore_schema_std.rs index cdc6e07..0186dec 100644 --- a/src/xenstore_schema_std.rs +++ b/src/xenstore_schema_std.rs @@ -111,6 +111,12 @@ impl XenstoreSchema for Schema { }; 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}"),