From f6318d86523d1a994a127aadace0d304f2a8b22a Mon Sep 17 00:00:00 2001 From: Herbert Wolverson Date: Tue, 21 Mar 2023 17:46:51 +0000 Subject: [PATCH] Change 'map ip' to add or insert, rather than just insert. This allows for speedy changes without a remove, making it an atomic operation. So you can add a new queue, change the IP/net, and wait a few seconds before deleting the old one to avoid packet loss during reloads. --- src/rust/lqos_sys/src/bpf_map.rs | 32 +++++++++++++++++++++++++ src/rust/lqos_sys/src/ip_mapping/mod.rs | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/rust/lqos_sys/src/bpf_map.rs b/src/rust/lqos_sys/src/bpf_map.rs index 675db85f..be461b79 100644 --- a/src/rust/lqos_sys/src/bpf_map.rs +++ b/src/rust/lqos_sys/src/bpf_map.rs @@ -130,6 +130,38 @@ where } } + /// Inserts an entry into a BPF map, or updates an existing entry with + /// the same key. + /// + /// Use this sparingly, because it briefly pauses XDP access to the + /// underlying map (through internal locking we can't reach from + /// userland). + /// + /// ## Arguments + /// + /// * `key` - the key to insert. + /// * `value` - the value to insert. + /// + /// Returns Ok if insertion succeeded, a generic error (no details yet) + /// if it fails. + pub(crate) fn insert_or_update(&mut self, key: &mut K, value: &mut V) -> Result<()> { + let key_ptr: *mut K = key; + let val_ptr: *mut V = value; + let err = unsafe { + bpf_map_update_elem( + self.fd, + key_ptr as *mut c_void, + val_ptr as *mut c_void, + BPF_NOEXIST.into(), + ) + }; + if err != 0 { + Err(Error::msg(format!("Unable to insert into map ({err})"))) + } else { + Ok(()) + } + } + /// Deletes an entry from the underlying eBPF map. /// Use this sparingly, it locks the underlying map in the /// kernel. This can cause *long* delays under heavy load. diff --git a/src/rust/lqos_sys/src/ip_mapping/mod.rs b/src/rust/lqos_sys/src/ip_mapping/mod.rs index 83c4ab9d..80ecb3b9 100644 --- a/src/rust/lqos_sys/src/ip_mapping/mod.rs +++ b/src/rust/lqos_sys/src/ip_mapping/mod.rs @@ -34,7 +34,7 @@ pub fn add_ip_to_tc( let mut key = IpHashKey { prefixlen: ip_to_add.prefix, address: address.0 }; let mut value = IpHashData { cpu: ip_to_add.cpu, tc_handle: ip_to_add.handle() }; - bpf_map.insert(&mut key, &mut value)?; + bpf_map.insert_or_update(&mut key, &mut value)?; Ok(()) }