]> xenbits.xensource.com Git - xen-guest-agent.git/commitdiff
net: separate add/rm of interface and add/rm of MAC address
authorYann Dirson <yann.dirson@vates.fr>
Tue, 21 Nov 2023 13:55:17 +0000 (14:55 +0100)
committerYann Dirson <yann.dirson@vates.fr>
Fri, 8 Dec 2023 09:59:46 +0000 (10:59 +0100)
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 <yann.dirson@vates.fr>
src/collector_net_netlink.rs
src/collector_net_pnet.rs
src/datastructs.rs
src/publisher.rs
src/xenstore_schema_rfc.rs
src/xenstore_schema_std.rs

index dc51021e02f0d833911d429d5bd77704902e90ed..81c8cded331bb0ebf43c1192a0c093fd8f7ff4be 100644 (file)
@@ -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
index 1ce5c8a271b012fe27665167d97b3aa84a6404c0..0be42830d3550d64ce2547ad35ddb3a6a337a731 100644 (file)
@@ -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 =
index 25e365500d9576461902851a5db4bed537659292..a1ba27b36625a72a5794906100f49c704ba0bf0b 100644 (file)
@@ -58,6 +58,8 @@ pub type NetInterfaceCache = HashMap<u32, Rc<NetInterface>>;
 
 #[derive(Debug)]
 pub enum NetEventOp {
+    AddIface,
+    RmIface,
     AddMac(String),
     RmMac(String),
     AddIp(IpAddr),
index 5970f8c3fc004aae8946e51318f80b302764b1ad..fcaa26bfc387dbae6d09fe6aafec2577f2e5e7de 100644 (file)
@@ -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}"),
index 50cbb041599fe4a6658d448c6da31f0aac42ee93..e1f1a1eb00d84d1ba65914621cf1e47f19677539 100644 (file)
@@ -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}"), "")?;
index cdc6e0710be5830c9b378945804e9b80fe37babe..0186deceb7c520c0a2217e1b637ac7206b5299e0 100644 (file)
@@ -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}"),